This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: readelf: Prepare for dumping DWARF info with objdump
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Wed, 7 Sep 2005 11:09:58 -0700
- Subject: PATCH: readelf: Prepare for dumping DWARF info with objdump
DWARF is independent of ELF. Other formats can also use DWARF. But
we can only dump DWARF info with readelf. I am in the process to add
dumping DWARF to objdump and I'd like to use DWARF code in readelf.
This patch is a starting point.
BTW, this patch depends on
http://sourceware.org/ml/binutils/2005-09/msg00045.html
H.J.
----
2005-09-07 H.J. Lu <hongjiu.lu@intel.com>
* readelf.c (dwarf_section): New structure for DWARF section.
(load_debug_section): New.
(load_debug_str): Use it.
(load_debug_loc): Likewise.
(debug_str_section): New.
(debug_abbrev_section): Likewise.
(debug_str_contents): Removed.
(debug_str_size): Likewise.
(debug_loc_contents): Likewise.
(debug_loc_size): Likewise.
(load_debug_loc): Likewise.
(free_debug_loc): Likewise.
(debug_range_contents): Likewise.
(debug_range_size): Likewise.
(load_debug_loc): Likewise.
(free_debug_loc): Likewise.
(free_debug_section): New.
(free_debug_str): Use it.
(free_debug_loc): Likewise.
(fetch_indirect_string): Updated.
(debug_apply_rela_addends): Likewise.
(process_debug_info): Likewise.
(get_debug_info): Likewise.
(display_debug_lines): Likewise.
(display_debug_pubnames): Likewise.
(display_debug_macinfo): Likewise.
(display_debug_abbrev): Likewise.
(display_debug_loc): Likewise.
(display_debug_str): Likewise.
(display_debug_info): Likewise.
(display_debug_aranges): Likewise.
(display_debug_ranges): Likewise.
(display_debug_frames): Likewise.
(display_debug_not_supported): Likewise.
(debug_displays): Likewise.
(display_debug_section): Likewise.
--- binutils/readelf.c.gen 2005-09-06 15:33:27.000000000 -0700
+++ binutils/readelf.c 2005-09-07 10:55:33.000000000 -0700
@@ -7590,162 +7590,96 @@ process_extended_line_op (unsigned char
return len;
}
-static const char *debug_str_contents;
-static bfd_vma debug_str_size;
+struct dwarf_section
+{
+ const char *name;
+ unsigned char *start;
+ bfd_vma address;
+ bfd_size_type size;
+};
static void
-load_debug_str (FILE *file)
+load_debug_section (struct dwarf_section *section, void *file)
{
Elf_Internal_Shdr *sec;
+ char buf [64];
/* If it is already loaded, do nothing. */
- if (debug_str_contents != NULL)
+ if (section->start != NULL)
return;
- /* Locate the .debug_str section. */
- sec = find_section (".debug_str");
+ /* Locate the debug section. */
+ sec = find_section (section->name);
if (sec == NULL)
return;
- debug_str_size = sec->sh_size;
-
- debug_str_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
- _("debug_str section data"));
+ snprintf (buf, sizeof (buf), _("%s section data"), section->name);
+ section->address = sec->sh_addr;
+ section->size = sec->sh_size;
+ section->start = get_data (NULL, file, sec->sh_offset, 1,
+ sec->sh_size, buf);
}
static void
-free_debug_str (void)
+free_debug_section (struct dwarf_section *section)
{
- if (debug_str_contents == NULL)
+ if (section->start == NULL)
return;
- free ((char *) debug_str_contents);
- debug_str_contents = NULL;
- debug_str_size = 0;
+ free ((char *) section->start );
+ section->start = NULL;
+ section->size = 0;
}
-static const char *
-fetch_indirect_string (unsigned long offset)
-{
- if (debug_str_contents == NULL)
- return _("<no .debug_str section>");
-
- if (offset > debug_str_size)
- {
- warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
- return _("<offset is too big>");
- }
-
- return debug_str_contents + offset;
-}
-
-static const char *debug_loc_contents;
-static bfd_vma debug_loc_size;
+static struct dwarf_section debug_str_section;
static void
-load_debug_loc (FILE *file)
+load_debug_str (void *file)
{
- Elf_Internal_Shdr *sec;
-
- /* If it is already loaded, do nothing. */
- if (debug_loc_contents != NULL)
- return;
-
- /* Locate the .debug_loc section. */
- sec = find_section (".debug_loc");
- if (sec == NULL)
- return;
-
- debug_loc_size = sec->sh_size;
-
- debug_loc_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
- _("debug_loc section data"));
+ debug_str_section.name = ".debug_str";
+ load_debug_section (&debug_str_section, file);
}
static void
-free_debug_loc (void)
+free_debug_str (void)
{
- if (debug_loc_contents == NULL)
- return;
-
- free ((char *) debug_loc_contents);
- debug_loc_contents = NULL;
- debug_loc_size = 0;
+ free_debug_section (&debug_str_section);
}
-static const char * debug_range_contents;
-static unsigned long debug_range_size;
-
-static void
-load_debug_range (FILE *file)
+static const char *
+fetch_indirect_string (unsigned long offset)
{
- Elf_Internal_Shdr *sec;
-
- /* If it is already loaded, do nothing. */
- if (debug_range_contents != NULL)
- return;
-
- /* Locate the .debug_ranges section. */
- sec = find_section (".debug_ranges");
- if (sec == NULL)
- return;
-
- debug_range_size = sec->sh_size;
-
- debug_range_contents = get_data (NULL, file, sec->sh_offset, 1, sec->sh_size,
- _("debug_range section data"));
-}
+ if (debug_str_section.start == NULL)
+ return _("<no .debug_str section>");
-static void
-free_debug_range (void)
-{
- if (debug_range_contents == NULL)
- return;
+ if (offset > debug_str_section.size)
+ {
+ warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
+ return _("<offset is too big>");
+ }
- free ((char *) debug_range_contents);
- debug_range_contents = NULL;
- debug_range_size = 0;
+ return debug_str_section.start + offset;
}
-static unsigned char *debug_abbrev_contents;
-static unsigned long debug_abbrev_size;
+static struct dwarf_section debug_abbrev_section;
static void
-load_debug_abbrev (FILE *file)
+load_debug_abbrev (void *file)
{
- Elf_Internal_Shdr *sec;
-
- /* If it is already loaded, do nothing. */
- if (debug_abbrev_contents != NULL)
- return;
-
- /* Locate the .debug_ranges section. */
- sec = find_section (".debug_abbrev");
- if (sec == NULL)
- return;
-
- debug_abbrev_size = sec->sh_size;
-
- debug_abbrev_contents = get_data (NULL, file, sec->sh_offset, 1,
- sec->sh_size,
- _("debug_abbrev section data"));
+ debug_abbrev_section.name = ".debug_abbrev";
+ load_debug_section (&debug_abbrev_section, file);
}
static void
free_debug_abbrev (void)
{
- if (debug_abbrev_contents == NULL)
- return;
-
- free ((char *) debug_abbrev_contents);
- debug_abbrev_contents = NULL;
- debug_abbrev_size = 0;
+ free_debug_section (&debug_abbrev_section);
}
/* Apply addends of RELA relocations. */
static int
-debug_apply_rela_addends (FILE *file,
+debug_apply_rela_addends (void *file,
Elf_Internal_Shdr *section,
unsigned char *start)
{
@@ -9083,10 +9017,11 @@ read_and_display_attr (unsigned long att
anything to the user. */
static int
-process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
- FILE *file, int do_loc)
+process_debug_info (struct dwarf_section *section, FILE *file,
+ int do_loc)
{
- unsigned char *end = start + section->sh_size;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
unsigned char *section_begin;
unsigned int unit;
unsigned int num_units = 0;
@@ -9116,7 +9051,7 @@ process_debug_info (Elf_Internal_Shdr *s
if (num_units == 0)
{
- error (_("No comp units in .debug_info section ?"));
+ error (_("No comp units in %s section ?"), section->name);
return 0;
}
@@ -9133,18 +9068,16 @@ process_debug_info (Elf_Internal_Shdr *s
if (!do_loc)
{
- printf (_("The section %s contains:\n\n"),
- SECTION_NAME (section));
+ printf (_("The section %s contains:\n\n"), section->name);
load_debug_str (file);
- load_debug_loc (file);
- load_debug_range (file);
}
load_debug_abbrev (file);
- if (debug_abbrev_contents == NULL)
+ if (debug_abbrev_section.start == NULL)
{
- warn (_("Unable to locate .debug_abbrev section!\n"));
+ warn (_("Unable to locate %s section!\n"),
+ debug_abbrev_section.name);
return 0;
}
@@ -9226,8 +9159,10 @@ process_debug_info (Elf_Internal_Shdr *s
/* Process the abbrevs used by this compilation unit. */
process_abbrev_section
- (debug_abbrev_contents + compunit.cu_abbrev_offset,
- debug_abbrev_contents + debug_abbrev_size);
+ ((unsigned char *) debug_abbrev_section.start
+ + compunit.cu_abbrev_offset,
+ (unsigned char *) debug_abbrev_section.start
+ + debug_abbrev_section.size);
level = 0;
while (tags < start)
@@ -9311,9 +9246,7 @@ process_debug_info (Elf_Internal_Shdr *s
if (!do_loc)
{
- free_debug_range ();
free_debug_str ();
- free_debug_loc ();
printf ("\n");
}
@@ -9370,11 +9303,11 @@ get_pointer_size_and_offset_of_comp_unit
compilation units upon success. */
static unsigned int
-get_debug_info (FILE * file)
+get_debug_info (void * file)
{
Elf_Internal_Shdr * section;
- unsigned char * start;
- int ret;
+ struct dwarf_section sec;
+ int ret;
/* Reset the last pointer size so that we can issue correct error
messages if we are displaying the contents of more than one section. */
@@ -9385,33 +9318,37 @@ get_debug_info (FILE * file)
if (num_debug_info_entries > 0)
return num_debug_info_entries;
- section = find_section (".debug_info");
+ sec.name = ".debug_info";
+ section = find_section (sec.name);
if (section == NULL)
return 0;
- start = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
- _("extracting information from .debug_info section"));
- if (start == NULL)
+ sec.start = get_data (NULL, file, section->sh_offset, 1,
+ section->sh_size,
+ _("extracting information from .debug_info section"));
+ if (sec.start == NULL)
return 0;
- ret = (debug_apply_rela_addends (file, section, start)
- && process_debug_info (section, start, file, 1));
+ sec.address = section->sh_addr;
+ sec.size = section->sh_size;
+ ret = (debug_apply_rela_addends (file, section, sec.start)
+ && process_debug_info (&sec, file, 1));
- free (start);
+ free (sec.start);
return ret ? num_debug_info_entries : 0;
}
static int
-display_debug_lines (Elf_Internal_Shdr *section,
- unsigned char *start, FILE *file)
+display_debug_lines (struct dwarf_section *section, void *file)
{
+ unsigned char *start = section->start;
unsigned char *data = start;
- unsigned char *end = start + section->sh_size;
+ unsigned char *end = start + section->size;
unsigned int comp_unit = 0;
printf (_("\nDump of debug contents of section %s:\n\n"),
- SECTION_NAME (section));
+ section->name);
get_debug_info (file);
@@ -9446,7 +9383,7 @@ display_debug_lines (Elf_Internal_Shdr *
initial_length_size = 4;
}
- if (info.li_length + initial_length_size > section->sh_size)
+ if (info.li_length + initial_length_size > section->size)
{
warn
(_("The line info appears to be corrupt - the section is too small\n"));
@@ -9693,16 +9630,14 @@ display_debug_lines (Elf_Internal_Shdr *
}
static int
-display_debug_pubnames (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_pubnames (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
DWARF2_Internal_PubNames pubnames;
- unsigned char *end;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
- end = start + section->sh_size;
-
- printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+ printf (_("Contents of the %s section:\n\n"), section->name);
while (start < end)
{
@@ -9779,16 +9714,16 @@ display_debug_pubnames (Elf_Internal_Shd
}
static int
-display_debug_macinfo (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_macinfo (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
- unsigned char *end = start + section->sh_size;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
unsigned char *curr = start;
unsigned int bytes_read;
enum dwarf_macinfo_record_type op;
- printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+ printf (_("Contents of the %s section:\n\n"), section->name);
while (curr < end)
{
@@ -9856,14 +9791,14 @@ display_debug_macinfo (Elf_Internal_Shdr
static int
-display_debug_abbrev (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_abbrev (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
abbrev_entry *entry;
- unsigned char *end = start + section->sh_size;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
- printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
+ printf (_("Contents of the %s section:\n\n"), section->name);
do
{
@@ -9899,9 +9834,9 @@ display_debug_abbrev (Elf_Internal_Shdr
}
static int
-display_debug_loc (Elf_Internal_Shdr *section,
- unsigned char *start, FILE *file)
+display_debug_loc (struct dwarf_section *section, void *file)
{
+ unsigned char *start = section->start;
unsigned char *section_end;
unsigned long bytes;
unsigned char *section_begin = start;
@@ -9914,12 +9849,12 @@ display_debug_loc (Elf_Internal_Shdr *se
int use_debug_info = 1;
unsigned char *next;
- bytes = section->sh_size;
+ bytes = section->size;
section_end = start + bytes;
if (bytes == 0)
{
- printf (_("\nThe .debug_loc section is empty.\n"));
+ printf (_("\nThe %s section is empty.\n"), section->name);
return 0;
}
@@ -9970,10 +9905,10 @@ display_debug_loc (Elf_Internal_Shdr *se
error (_("No location lists in .debug_info section!\n"));
if (debug_information [first].loc_offsets [0] != 0)
- warn (_("Location lists in .debug_loc section start at 0x%lx\n"),
- debug_information [first].loc_offsets [0]);
+ warn (_("Location lists in %s section start at 0x%lx\n"),
+ section->name, debug_information [first].loc_offsets [0]);
- printf (_("Contents of the .debug_loc section:\n\n"));
+ printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End Expression\n"));
seen_first_offset = 0;
@@ -10091,23 +10026,20 @@ display_debug_loc (Elf_Internal_Shdr *se
}
static int
-display_debug_str (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_str (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
- unsigned long bytes;
- bfd_vma addr;
-
- addr = section->sh_addr;
- bytes = section->sh_size;
+ unsigned char *start = section->start;
+ unsigned long bytes = section->size;
+ bfd_vma addr = section->address;
if (bytes == 0)
{
- printf (_("\nThe .debug_str section is empty.\n"));
+ printf (_("\nThe %s section is empty.\n"), section->name);
return 0;
}
- printf (_("Contents of the .debug_str section:\n\n"));
+ printf (_("Contents of the %s section:\n\n"), section->name);
while (bytes)
{
@@ -10153,21 +10085,20 @@ display_debug_str (Elf_Internal_Shdr *se
static int
-display_debug_info (Elf_Internal_Shdr * section,
- unsigned char * start, FILE * file)
+display_debug_info (struct dwarf_section *section, void *file)
{
- return process_debug_info (section, start, file, 0);
+ return process_debug_info (section, file, 0);
}
static int
-display_debug_aranges (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_aranges (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
- unsigned char *end = start + section->sh_size;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
- printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+ printf (_("The section %s contains:\n\n"), section->name);
while (start < end)
{
@@ -10257,10 +10188,10 @@ display_debug_aranges (Elf_Internal_Shdr
}
static int
-display_debug_ranges (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_ranges (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
+ unsigned char *start = section->start;
unsigned char *section_end;
unsigned long bytes;
unsigned char *section_begin = start;
@@ -10273,12 +10204,12 @@ display_debug_ranges (Elf_Internal_Shdr
int use_debug_info = 1;
unsigned char *next;
- bytes = section->sh_size;
+ bytes = section->size;
section_end = start + bytes;
if (bytes == 0)
{
- printf (_("\nThe .debug_ranges section is empty.\n"));
+ printf (_("\nThe %s section is empty.\n"), section->name);
return 0;
}
@@ -10329,10 +10260,10 @@ display_debug_ranges (Elf_Internal_Shdr
error (_("No range lists in .debug_info section!\n"));
if (debug_information [first].range_lists [0] != 0)
- warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
- debug_information [first].range_lists [0]);
+ warn (_("Range lists in %s section start at 0x%lx\n"),
+ section->name, debug_information [first].range_lists [0]);
- printf (_("Contents of the .debug_ranges section:\n\n"));
+ printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End\n"));
seen_first_offset = 0;
@@ -10357,11 +10288,13 @@ display_debug_ranges (Elf_Internal_Shdr
else
{
if (start < next)
- warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
- (long)(start - section_begin), (long)(next - section_begin));
+ warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
+ (long)(start - section_begin),
+ (long)(next - section_begin), section->name);
else if (start > next)
- warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
- (long)(start - section_begin), (long)(next - section_begin));
+ warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
+ (long)(start - section_begin),
+ (long)(next - section_begin), section->name);
}
start = next;
@@ -10541,20 +10474,20 @@ get_encoded_value (unsigned char *data,
#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
static int
-display_debug_frames (Elf_Internal_Shdr *section,
- unsigned char *start,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_frames (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
- unsigned char *end = start + section->sh_size;
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
unsigned char *section_start = start;
Frame_Chunk *chunks = 0;
Frame_Chunk *remembered_state = 0;
Frame_Chunk *rs;
- int is_eh = streq (SECTION_NAME (section), ".eh_frame");
+ int is_eh = streq (section->name, ".eh_frame");
unsigned int length_return;
int max_regs = 0;
- printf (_("The section %s contains:\n"), SECTION_NAME (section));
+ printf (_("The section %s contains:\n"), section->name);
while (start < end)
{
@@ -10765,7 +10698,7 @@ display_debug_frames (Elf_Internal_Shdr
/* Don't adjust for ET_REL since there's invariably a pcrel
reloc here, which we haven't applied. */
&& elf_header.e_type != ET_REL)
- fc->pc_begin += section->sh_addr + (start - section_start);
+ fc->pc_begin += section->address + (start - section_start);
start += encoded_ptr_size;
fc->pc_range = byte_get (start, encoded_ptr_size);
start += encoded_ptr_size;
@@ -10966,7 +10899,7 @@ display_debug_frames (Elf_Internal_Shdr
vma = get_encoded_value (start, fc->fde_encoding);
if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
&& elf_header.e_type != ET_REL)
- vma += section->sh_addr + (start - section_start);
+ vma += section->address + (start - section_start);
start += encoded_ptr_size;
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
@@ -11218,12 +11151,11 @@ display_debug_frames (Elf_Internal_Shdr
#undef SLEB
static int
-display_debug_not_supported (Elf_Internal_Shdr *section,
- unsigned char *start ATTRIBUTE_UNUSED,
- FILE *file ATTRIBUTE_UNUSED)
+display_debug_not_supported (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
{
printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
- SECTION_NAME (section));
+ section->name);
return 1;
}
@@ -11233,7 +11165,7 @@ display_debug_not_supported (Elf_Interna
static struct
{
const char *const name;
- int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
+ int (*display) (struct dwarf_section *, void *);
unsigned int relocate : 1;
}
debug_displays[] =
@@ -11278,21 +11210,24 @@ display_debug_section (Elf_Internal_Shdr
for (i = NUM_ELEM (debug_displays); i--;)
if (streq (debug_displays[i].name, name))
{
- unsigned char *start;
+ struct dwarf_section sec;
- start = get_data (NULL, file, section->sh_offset, 1, length,
- _("debug section data"));
- if (start == NULL)
+ sec.name = name;
+ sec.address = section->sh_addr;
+ sec.size = section->sh_size;
+ sec.start = get_data (NULL, file, section->sh_offset, 1,
+ length, _("debug section data"));
+ if (sec.start == NULL)
{
result = 0;
break;
}
if (!debug_displays[i].relocate
- || debug_apply_rela_addends (file, section, start))
- result &= debug_displays[i].display (section, start, file);
+ || debug_apply_rela_addends (file, section, sec.start))
+ result &= debug_displays[i].display (&sec, file);
- free (start);
+ free (sec.start);
/* If we loaded in the abbrev section
at some point, we must release it here. */