}
}
+/* Returns either the (relocated) data from the Dwarf, or tries to get
+ the "raw" (uncompressed) data from the Elf section. Produces a
+ warning if the data cannot be found (or decompressed). */
+static Elf_Data *
+get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn)
+{
+ /* We prefer to get the section data from the Dwarf because that
+ might have been relocated already. Note this is subtly wrong if
+ there are multiple sections with the same .debug name. */
+ if (dbg->sectiondata[idx] != NULL)
+ return dbg->sectiondata[idx];
+
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+ {
+ if (elf_compress (scn, 0, 0) < 0)
+ {
+ error (0, 0, "%s [%zd] '%s'\n",
+ _("Couldn't uncompress section"),
+ elf_ndxscn (scn), section_name (ebl, shdr));
+ return NULL;
+ }
+ }
+
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data == NULL)
+ error (0, 0, "%s [%zd] '%s': %s\n",
+ _("Couldn't get data from section"),
+ elf_ndxscn (scn), section_name (ebl, shdr), elf_errmsg (-1));
+
+ return elf_getdata (scn, NULL);
+}
void
print_dwarf_addr (Dwfl_Module *dwflmod,
Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
- const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
- dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
+ Elf_Data *elf_data = get_debug_elf_data (dbg, ebl, IDX_debug_abbrev, scn);
+ if (elf_data == NULL)
+ return;
+
+ const size_t sh_size = elf_data->d_size;
printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
" [ Code]\n"),
Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_addr, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
if (shdr->sh_size == 0)
return;
- /* We like to get the section from libdw to make sure they are relocated. */
- Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_addr section data: %s"),
- elf_errmsg (-1));
- return;
- }
-
size_t idx = 0;
sort_listptr (&known_addrbases, "addr_base");
return;
}
- Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
- ?: elf_rawdata (scn, NULL));
-
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_aranges content: %s"),
- elf_errmsg (-1));
- return;
- }
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_aranges, scn);
+ if (data == NULL)
+ return;
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
Elf_Scn *scn, GElf_Shdr *shdr,
Dwarf *dbg __attribute__((unused)))
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_rnglists, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
(uint64_t) shdr->sh_offset);
- Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_rnglists content: %s"),
- elf_errmsg (-1));
- return;
- }
-
/* For the listptr to get the base address/CU. */
sort_listptr (&known_rnglistptr, "rnglistptr");
size_t listptr_idx = 0;
Elf_Scn *scn, GElf_Shdr *shdr,
Dwarf *dbg)
{
- Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_ranges content: %s"),
- elf_errmsg (-1));
- return;
- }
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_ranges, scn);
+ if (data == NULL)
+ return;
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
}
bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
- Elf_Data *data = (is_eh_frame
- ? elf_rawdata (scn, NULL)
- : (dbg->sectiondata[IDX_debug_frame]
- ?: elf_rawdata (scn, NULL)));
-
- if (unlikely (data == NULL))
+ Elf_Data *data;
+ if (is_eh_frame)
{
- error (0, 0, _("cannot get %s content: %s"),
- scnname, elf_errmsg (-1));
- return;
+ data = elf_rawdata (scn, NULL);
+ if (data == NULL)
+ {
+ error (0, 0, _("cannot get %s content: %s"),
+ scnname, elf_errmsg (-1));
+ return;
+ }
+ }
+ else
+ {
+ data = get_debug_elf_data (dbg, ebl, IDX_debug_frame, scn);
+ if (data == NULL)
+ return;
}
if (is_eh_frame)
const bool silent = !(print_debug_sections & section_info) && !debug_types;
const char *secname = section_name (ebl, shdr);
+ /* Check section actually exists. */
+ if (!silent)
+ if (get_debug_elf_data (dbg, ebl,
+ debug_types ? IDX_debug_types : IDX_debug_info,
+ scn) == NULL)
+ return;
+
if (!silent)
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
return;
}
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_line, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
/* There is no functionality in libdw to read the information in the
way it is represented here. Hardcode the decoder. */
- Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get line data section data: %s"),
- elf_errmsg (-1));
- return;
- }
const unsigned char *linep = (const unsigned char *) data->d_buf;
const unsigned char *lineendp;
Elf_Scn *scn, GElf_Shdr *shdr,
Dwarf *dbg)
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loclists, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
(uint64_t) shdr->sh_offset);
- Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_loclists content: %s"),
- elf_errmsg (-1));
- return;
- }
-
/* For the listptr to get the base address/CU. */
sort_listptr (&known_loclistsptr, "loclistsptr");
size_t listptr_idx = 0;
Ebl *ebl, GElf_Ehdr *ehdr,
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
- Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
- ?: elf_rawdata (scn, NULL));
-
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_loc content: %s"),
- elf_errmsg (-1));
- return;
- }
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loc, scn);
+ if (data == NULL)
+ return;
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
GElf_Ehdr *ehdr __attribute__ ((unused)),
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macinfo, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
/* There is no function in libdw to iterate over the raw content of
the section but it is easy enough to do. */
- Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get macro information section data: %s"),
- elf_errmsg (-1));
- return;
- }
/* Get the source file information for all CUs. */
Dwarf_Off offset;
GElf_Ehdr *ehdr __attribute__ ((unused)),
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macro, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
(uint64_t) shdr->sh_offset);
putc_unlocked ('\n', stdout);
- Elf_Data *data = elf_getdata (scn, NULL);
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get macro information section data: %s"),
- elf_errmsg (-1));
- return;
- }
-
/* Get the source file information for all CUs. Uses same
datastructure as macinfo. But uses offset field to directly
match .debug_line offset. And just stored in a list. */
GElf_Ehdr *ehdr __attribute__ ((unused)),
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ /* Check section actually exists. */
+ if (get_debug_elf_data (dbg, ebl, IDX_debug_pubnames, scn) == NULL)
+ return;
+
printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
(uint64_t) shdr->sh_offset);
(void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
}
-/* Print the content of the DWARF string section '.debug_str'. */
+/* Print the content of the DWARF string section '.debug_str'
+ or 'debug_line_str'. */
static void
print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
Ebl *ebl,
Elf_Scn *scn, GElf_Shdr *shdr,
Dwarf *dbg __attribute__ ((unused)))
{
- Elf_Data *data = elf_rawdata (scn, NULL);
- const size_t sh_size = data ? data->d_size : 0;
+ const char *name = section_name (ebl, shdr);
+ int idx = ((name != NULL && strstr (name, "debug_line_str") != NULL)
+ ? IDX_debug_line_str : IDX_debug_str);
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, idx, scn);
+ if (data == NULL)
+ return;
+
+ const size_t sh_size = data->d_size;
/* Compute floor(log16(shdr->sh_size)). */
GElf_Addr tmp = sh_size;
GElf_Ehdr *ehdr __attribute__ ((unused)),
Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
{
+ Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_str_offsets, scn);
+ if (data == NULL)
+ return;
+
printf (_("\
\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
elf_ndxscn (scn), section_name (ebl, shdr),
if (shdr->sh_size == 0)
return;
- /* We like to get the section from libdw to make sure they are relocated. */
- Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
- ?: elf_rawdata (scn, NULL));
- if (unlikely (data == NULL))
- {
- error (0, 0, _("cannot get .debug_str_offsets section data: %s"),
- elf_errmsg (-1));
- return;
- }
-
size_t idx = 0;
sort_listptr (&known_stroffbases, "str_offsets");