Fix initialisation of debug_line_pointer_sizes array so that it is done as needed

This commit is contained in:
Nick Clifton 2004-01-07 18:50:51 +00:00
parent 3ba7a1aacf
commit d9296b1825
4 changed files with 174 additions and 172 deletions

View file

@ -1,3 +1,18 @@
2004-01-07 Nick Clifton <nickc@redhat.com>
* readelf.c (find_section): New function. Locates a named
section.
(get_debug_line_pointer_sizes): New function: Initialises the
debug_line_pointer_sizes array.
(display_debug_lines): Call get_debug_line_pointer_sizes.
(display_debug_loc): Likewise.
(load_debug_loc): Use find_section.
(load_debug_str): Likewise.
(display_debug_info): Likewise.
(prescan_debug_info): Delete.
(debug_displays): Remove prescan field.
(process_section_contents): Do not perform prescans.
2004-01-03 Alan Modra <amodra@bigpond.net.au>
* objcopy.c (filter_bytes): Delete. Move code to..

View file

@ -6271,16 +6271,137 @@ process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
return len;
}
/* Finds section NAME inside FILE and returns a
pointer to it, or NULL upon failure. */
static Elf_Internal_Shdr *
find_section (const char * name)
{
Elf_Internal_Shdr *sec;
unsigned int i;
for (i = elf_header.e_shnum, sec = section_headers + i - 1;
i; --i, --sec)
if (strcmp (SECTION_NAME (sec), name) == 0)
break;
if (i && sec && sec->sh_size != 0)
return sec;
return NULL;
}
/* Size of pointers in the .debug_line section. This information is not
really present in that section. It's obtained before dumping the debug
sections by doing some pre-scan of the .debug_info section. */
static unsigned int * debug_line_pointer_sizes = NULL;
static unsigned int num_debug_line_pointer_sizes = 0;
/* Locate and scan the .debug_info section in the file and record the pointer
sizes for the compilation units in it. Usually an executable will have
just one pointer size, but this is not guaranteed, and so we try not to
make any assumptions. Returns zero upon failure, or the number of
compilation units upon success. */
static unsigned int
get_debug_line_pointer_sizes (FILE * file)
{
Elf_Internal_Shdr * section;
unsigned char * start;
unsigned char * end;
unsigned char * begin;
unsigned long length;
unsigned int num_units;
unsigned int unit;
section = find_section (".debug_info");
if (section == NULL)
return 0;
length = section->sh_size;
start = get_data (NULL, file, section->sh_offset, section->sh_size,
_("extracting pointer sizes from .debug_info section"));
if (start == NULL)
return 0;
end = start + section->sh_size;
/* First scan the section to get the number of comp units. */
for (begin = start, num_units = 0; begin < end; num_units++)
{
/* Read the first 4 bytes. For a 32-bit DWARF section, this will
be the length. For a 64-bit DWARF section, it'll be the escape
code 0xffffffff followed by an 8 byte length. */
length = byte_get (begin, 4);
if (length == 0xffffffff)
{
length = byte_get (begin + 4, 8);
begin += length + 12;
}
else
begin += length + 4;
}
if (num_units == 0)
{
error (_("No comp units in .debug_info section ?"));
free (start);
return 0;
}
/* Then allocate an array to hold the pointer sizes. */
debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
if (debug_line_pointer_sizes == NULL)
{
error (_("Not enough memory for a pointer size array of %u entries"),
num_units);
free (start);
return 0;
}
/* Populate the array. */
for (begin = start, unit = 0; begin < end; unit++)
{
length = byte_get (begin, 4);
if (length == 0xffffffff)
{
/* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
from the start of the section. This is computed as follows:
unit_length: 12 bytes
version: 2 bytes
debug_abbrev_offset: 8 bytes
-----------------------------
Total: 22 bytes */
debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
length = byte_get (begin + 4, 8);
begin += length + 12;
}
else
{
/* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
the start of the section:
unit_length: 4 bytes
version: 2 bytes
debug_abbrev_offset: 4 bytes
-----------------------------
Total: 10 bytes */
debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
begin += length + 4;
}
}
free (start);
num_debug_line_pointer_sizes = num_units;
return num_units;
}
static int
display_debug_lines (Elf_Internal_Shdr *section,
unsigned char * start,
FILE *file ATTRIBUTE_UNUSED)
unsigned char *start, FILE *file)
{
unsigned char *hdrptr;
DWARF2_Internal_LineInfo info;
@ -6296,6 +6417,9 @@ display_debug_lines (Elf_Internal_Shdr *section,
printf (_("\nDump of debug contents of section %s:\n\n"),
SECTION_NAME (section));
if (num_debug_line_pointer_sizes == 0)
get_debug_line_pointer_sizes (file);
while (data < end)
{
unsigned int pointer_size;
@ -7506,20 +7630,14 @@ static void
load_debug_loc (FILE *file)
{
Elf_Internal_Shdr *sec;
unsigned int i;
/* If it is already loaded, do nothing. */
if (debug_loc_contents != NULL)
return;
/* Locate the .debug_loc section. */
for (i = 0, sec = section_headers;
i < elf_header.e_shnum;
i++, sec++)
if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0)
break;
if (i == elf_header.e_shnum || sec->sh_size == 0)
sec = find_section (".debug_loc");
if (sec == NULL)
return;
debug_loc_size = sec->sh_size;
@ -7542,8 +7660,7 @@ free_debug_loc (void)
static int
display_debug_loc (Elf_Internal_Shdr *section,
unsigned char *start,
FILE *file ATTRIBUTE_UNUSED)
unsigned char *start, FILE *file)
{
unsigned char *section_end;
unsigned long bytes;
@ -7561,6 +7678,9 @@ display_debug_loc (Elf_Internal_Shdr *section,
return 0;
}
if (num_debug_line_pointer_sizes == 0)
get_debug_line_pointer_sizes (file);
printf (_("Contents of the .debug_loc section:\n\n"));
printf (_("\n Offset Begin End Expression\n"));
@ -7625,20 +7745,14 @@ static void
load_debug_str (FILE *file)
{
Elf_Internal_Shdr *sec;
unsigned int i;
/* If it is already loaded, do nothing. */
if (debug_str_contents != NULL)
return;
/* Locate the .debug_str section. */
for (i = 0, sec = section_headers;
i < elf_header.e_shnum;
i++, sec++)
if (strcmp (SECTION_NAME (sec), ".debug_str") == 0)
break;
if (i == elf_header.e_shnum || sec->sh_size == 0)
sec = find_section (".debug_str");
if (sec == NULL)
return;
debug_str_size = sec->sh_size;
@ -8100,7 +8214,6 @@ display_debug_info (Elf_Internal_Shdr *section,
unsigned char *hdrptr;
unsigned char *cu_abbrev_offset_ptr;
unsigned char *tags;
unsigned int i;
int level;
unsigned long cu_offset;
int offset_size;
@ -8224,13 +8337,8 @@ display_debug_info (Elf_Internal_Shdr *section,
unsigned char *begin;
/* Locate the .debug_abbrev section and process it. */
for (i = 0, sec = section_headers;
i < elf_header.e_shnum;
i++, sec++)
if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
break;
if (i == elf_header.e_shnum || sec->sh_size == 0)
sec = find_section (".debug_abbrev");
if (sec == NULL)
{
warn (_("Unable to locate .debug_abbrev section!\n"));
return 0;
@ -9194,121 +9302,31 @@ display_debug_not_supported (Elf_Internal_Shdr *section,
return 1;
}
/* Pre-scan the .debug_info section to record the pointer sizes for the
compilation units. Usually an executable will have just one pointer
size, but this is not guaranteed, and so we try not to make any
assumptions. Returns zero upon failure, or the number of compilation
units upon success. */
static unsigned int
prescan_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
FILE *file ATTRIBUTE_UNUSED)
{
unsigned char *begin;
unsigned char *end = start + section->sh_size;
unsigned long length;
unsigned int num_units;
unsigned int unit;
/* First scan the section to compute the number of comp units. */
for (begin = start, num_units = 0; begin < end; num_units++)
{
/* Read the first 4 bytes. For a 32-bit DWARF section, this will
be the length. For a 64-bit DWARF section, it'll be the escape
code 0xffffffff followed by an 8 byte length. */
length = byte_get (begin, 4);
if (length == 0xffffffff)
{
length = byte_get (begin + 4, 8);
begin += length + 12;
}
else
begin += length + 4;
}
if (num_units == 0)
{
error (_("No comp units in .debug_info section ?"));
return 0;
}
/* Then allocate an array to hold the pointer sizes. */
debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
if (debug_line_pointer_sizes == NULL)
{
error (_("Not enough memory for a pointer size array of %u entries"),
num_units);
return 0;
}
/* Populate the array. */
for (begin = start, unit = 0; begin < end; unit++)
{
length = byte_get (begin, 4);
if (length == 0xffffffff)
{
/* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
from the start of the section. This is computed as follows:
unit_length: 12 bytes
version: 2 bytes
debug_abbrev_offset: 8 bytes
-----------------------------
Total: 22 bytes */
debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
length = byte_get (begin + 4, 8);
begin += length + 12;
}
else
{
/* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
the start of the section:
unit_length: 4 bytes
version: 2 bytes
debug_abbrev_offset: 4 bytes
-----------------------------
Total: 10 bytes */
debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
begin += length + 4;
}
}
num_debug_line_pointer_sizes = num_units;
return num_units;
}
/* A structure containing the name of a debug section and a pointer
to a function that can decode it. The third field is a prescan
function to be run over the section before displaying any of the
sections. */
/* A structure containing the name of a debug section
and a pointer to a function that can decode it. */
struct
{
const char *const name;
int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
int (*prescan) (Elf_Internal_Shdr *, unsigned char *, FILE *);
}
debug_displays[] =
{
{ ".debug_abbrev", display_debug_abbrev, NULL },
{ ".debug_aranges", display_debug_aranges, NULL },
{ ".debug_frame", display_debug_frames, NULL },
{ ".debug_info", display_debug_info, prescan_debug_info },
{ ".debug_line", display_debug_lines, NULL },
{ ".debug_pubnames", display_debug_pubnames, NULL },
{ ".eh_frame", display_debug_frames, NULL },
{ ".debug_macinfo", display_debug_macinfo, NULL },
{ ".debug_str", display_debug_str, NULL },
{ ".debug_loc", display_debug_loc, NULL },
{ ".debug_pubtypes", display_debug_not_supported, NULL },
{ ".debug_ranges", display_debug_not_supported, NULL },
{ ".debug_static_func", display_debug_not_supported, NULL },
{ ".debug_static_vars", display_debug_not_supported, NULL },
{ ".debug_types", display_debug_not_supported, NULL },
{ ".debug_weaknames", display_debug_not_supported, NULL }
{ ".debug_abbrev", display_debug_abbrev },
{ ".debug_aranges", display_debug_aranges },
{ ".debug_frame", display_debug_frames },
{ ".debug_info", display_debug_info },
{ ".debug_line", display_debug_lines },
{ ".debug_pubnames", display_debug_pubnames },
{ ".eh_frame", display_debug_frames },
{ ".debug_macinfo", display_debug_macinfo },
{ ".debug_str", display_debug_str },
{ ".debug_loc", display_debug_loc },
{ ".debug_pubtypes", display_debug_not_supported },
{ ".debug_ranges", display_debug_not_supported },
{ ".debug_static_func", display_debug_not_supported },
{ ".debug_static_vars", display_debug_not_supported },
{ ".debug_types", display_debug_not_supported },
{ ".debug_weaknames", display_debug_not_supported }
};
static int
@ -9363,42 +9381,6 @@ process_section_contents (FILE *file)
if (! do_dump)
return 1;
/* Pre-scan the debug sections to find some debug information not
present in some of them. For the .debug_line, we must find out the
size of address (specified in .debug_info and .debug_aranges). */
for (i = 0, section = section_headers;
i < elf_header.e_shnum && i < num_dump_sects;
i++, section++)
{
char *name = SECTION_NAME (section);
int j;
if (section->sh_size == 0)
continue;
/* See if there is some pre-scan operation for this section. */
for (j = NUM_ELEM (debug_displays); j--;)
if (strcmp (debug_displays[j].name, name) == 0)
{
if (debug_displays[j].prescan != NULL)
{
bfd_size_type length;
unsigned char *start;
length = section->sh_size;
start = get_data (NULL, file, section->sh_offset, length,
_("debug section data"));
if (!start)
return 0;
debug_displays[j].prescan (section, start, file);
free (start);
}
break;
}
}
for (i = 0, section = section_headers;
i < elf_header.e_shnum && i < num_dump_sects;
i++, section++)

View file

@ -1,3 +1,7 @@
2004-01-07 Nick Clifton <nickc@redhat.com>
* gas/cris/rd-dw2-1.d: Expect a pointer size from readelf.
2004-01-06 Alexandre Oliva <aoliva@redhat.com>
2003-11-05 Alexandre Oliva <aoliva@redhat.com>

View file

@ -14,6 +14,7 @@ Dump of debug contents of section \.debug_line:
Line Base: -5
Line Range: 14
Opcode Base: 10
\(Pointer size: 4\)
Opcodes:
Opcode 1 has 0 args