Support reading .zdebug_* DWARF sections compressed via zlib.
diff --git a/src/readelf.c b/src/readelf.c
index 0e50a69..78ee2b7 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1154,6 +1154,13 @@
}
+static const char *
+section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
+{
+ return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
+}
+
+
static void
handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
{
@@ -4406,16 +4413,16 @@
static void
print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
" [ Code]\n"),
- elf_ndxscn (scn), ".debug_abbrev", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
Dwarf_Off offset = 0;
- while (offset < shdr->sh_size)
+ while (offset < dbg->sectiondata[IDX_debug_abbrev]->d_size)
{
printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
offset);
@@ -4477,8 +4484,7 @@
takes care of it. */
static void
print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr, Elf_Scn *scn,
+ Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
GElf_Shdr *shdr, Dwarf *dbg)
{
Dwarf_Aranges *aranges;
@@ -4495,7 +4501,8 @@
"\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
cnt),
- elf_ndxscn (scn), ".debug_aranges", (uint64_t) shdr->sh_offset, cnt);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset, cnt);
/* Compute floor(log16(cnt)). */
size_t tmp = cnt;
@@ -4533,8 +4540,8 @@
/* Print content of DWARF .debug_ranges section. */
static void
print_debug_ranges_section (Dwfl_Module *dwflmod,
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr,
+ Ebl *ebl, GElf_Ehdr *ehdr,
+ Elf_Scn *scn, GElf_Shdr *shdr,
Dwarf *dbg)
{
Elf_Data *data = elf_rawdata (scn, NULL);
@@ -4548,7 +4555,8 @@
printf (gettext ("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
- elf_ndxscn (scn), ".debug_ranges", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
sort_listptr (&known_rangelistptr, "rangelistptr");
size_t listptr_idx = 0;
@@ -5644,14 +5652,12 @@
static void
print_debug_units (Dwfl_Module *dwflmod,
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
- Elf_Scn *scn,
- GElf_Shdr *shdr, Dwarf *dbg,
- bool debug_types)
+ Ebl *ebl, GElf_Ehdr *ehdr,
+ Elf_Scn *scn, GElf_Shdr *shdr,
+ Dwarf *dbg, bool debug_types)
{
const bool silent = !(print_debug_sections & section_info);
- const char *secname = debug_types ? ".debug_types" : ".debug_info";
+ const char *secname = section_name (ebl, ehdr, shdr);
if (!silent)
printf (gettext ("\
@@ -5814,13 +5820,13 @@
static void
-print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
- GElf_Ehdr *ehdr __attribute__ ((unused)),
+print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
- elf_ndxscn (scn), ".debug_line", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
if (shdr->sh_size == 0)
return;
@@ -5853,7 +5859,7 @@
{
invalid_data:
error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
- elf_ndxscn (scn), ".debug_line");
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
return;
}
unit_length = read_8ubyte_unaligned_inc (dbg, linep);
@@ -5921,7 +5927,7 @@
error (0, 0,
gettext ("invalid data at offset %tu in section [%zu] '%s'"),
linep - (const unsigned char *) data->d_buf,
- elf_ndxscn (scn), ".debug_line");
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
linep = lineendp;
continue;
}
@@ -6304,7 +6310,7 @@
static void
print_debug_loc_section (Dwfl_Module *dwflmod,
- Ebl *ebl __attribute__ ((unused)), GElf_Ehdr *ehdr,
+ Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
Elf_Data *data = elf_rawdata (scn, NULL);
@@ -6318,7 +6324,8 @@
printf (gettext ("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
- elf_ndxscn (scn), ".debug_loc", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
sort_listptr (&known_loclistptr, "loclistptr");
size_t listptr_idx = 0;
@@ -6427,13 +6434,13 @@
static void
print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
- elf_ndxscn (scn), ".debug_macinfo", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
putc_unlocked ('\n', stdout);
/* There is no function in libdw to iterate over the raw content of
@@ -6599,12 +6606,12 @@
/* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
static void
print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
- elf_ndxscn (scn), ".debug_pubnames", (uint64_t) shdr->sh_offset);
+ elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+ (uint64_t) shdr->sh_offset);
int n = 0;
(void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
@@ -6613,12 +6620,13 @@
/* Print the content of the DWARF string section '.debug_str'. */
static void
print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
- Ebl *ebl __attribute__ ((unused)),
- GElf_Ehdr *ehdr __attribute__ ((unused)),
+ Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ const size_t sh_size = dbg->sectiondata[IDX_debug_str]->d_size;
+
/* Compute floor(log16(shdr->sh_size)). */
- GElf_Addr tmp = shdr->sh_size;
+ GElf_Addr tmp = sh_size;
int digits = 1;
while (tmp >= 16)
{
@@ -6630,12 +6638,12 @@
printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
" %*s String\n"),
elf_ndxscn (scn),
- ".debug_str", (uint64_t) shdr->sh_offset,
+ section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
/* TRANS: the debugstr| prefix makes the string unique. */
digits + 2, sgettext ("debugstr|Offset"));
Dwarf_Off offset = 0;
- while (offset < shdr->sh_size)
+ while (offset < sh_size)
{
size_t len;
const char *str = dwarf_getstring (dbg, offset, &len);
@@ -6981,7 +6989,13 @@
int n;
for (n = 0; n < ndebug_sections; ++n)
- if (strcmp (name, debug_sections[n].name) == 0)
+ if (strcmp (name, debug_sections[n].name) == 0
+#if USE_ZLIB
+ || (name[0] == '.' && name[1] == 'z'
+ && debug_sections[n].name[1] == 'd'
+ && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
+#endif
+ )
{
if ((print_debug_sections | implicit_debug_sections)
& debug_sections[n].bitmask)