PR gas/3800
* readelf.c: Include elf/h8.h twice. The first time in order to get the reloc numbers, the second time in order to get the reloc decoder function. (dump_section): Tell the user if the section being displayed has unprocessed relocs associated with it. (get_reloc_size): New function - returns the size of a reloc. (debug_apply_rela_addends): Use get_reloc_size(). * dwarf.c (read_and_display_attr_value): Extend number of languages known for the DW_AT_language attribute. (process_debug_info): Display the attribute offset before decoding the attribute, in case there are problems.
This commit is contained in:
parent
7b5030c061
commit
4b78141aa2
3 changed files with 149 additions and 29 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
2007-02-06 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR gas/3800
|
||||||
|
* readelf.c: Include elf/h8.h twice. The first time in order to
|
||||||
|
get the reloc numbers, the second time in order to get the reloc
|
||||||
|
decoder function.
|
||||||
|
(dump_section): Tell the user if the section being displayed has
|
||||||
|
unprocessed relocs associated with it.
|
||||||
|
(get_reloc_size): New function - returns the size of a reloc.
|
||||||
|
(debug_apply_rela_addends): Use get_reloc_size().
|
||||||
|
* dwarf.c (read_and_display_attr_value): Extend number of
|
||||||
|
languages known for the DW_AT_language attribute.
|
||||||
|
(process_debug_info): Display the attribute offset before decoding
|
||||||
|
the attribute, in case there are problems.
|
||||||
|
|
||||||
2007-02-05 Dave Brolley <brolley@redhat.com>
|
2007-02-05 Dave Brolley <brolley@redhat.com>
|
||||||
|
|
||||||
* readelf.c (dump_relocations): Don't check for
|
* readelf.c (dump_relocations): Don't check for
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* dwarf.c -- display DWARF contents of a BFD binary file
|
/* dwarf.c -- display DWARF contents of a BFD binary file
|
||||||
Copyright 2005, 2006
|
Copyright 2005, 2006, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
||||||
|
@ -1213,26 +1213,37 @@ read_and_display_attr_value (unsigned long attribute,
|
||||||
case DW_AT_language:
|
case DW_AT_language:
|
||||||
switch (uvalue)
|
switch (uvalue)
|
||||||
{
|
{
|
||||||
case DW_LANG_C: printf ("(non-ANSI C)"); break;
|
/* Ordered by the numeric value of these constants. */
|
||||||
case DW_LANG_C89: printf ("(ANSI C)"); break;
|
case DW_LANG_C89: printf ("(ANSI C)"); break;
|
||||||
case DW_LANG_C_plus_plus: printf ("(C++)"); break;
|
case DW_LANG_C: printf ("(non-ANSI C)"); break;
|
||||||
case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
|
|
||||||
case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
|
|
||||||
case DW_LANG_Modula2: printf ("(Modula 2)"); break;
|
|
||||||
case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
|
|
||||||
case DW_LANG_Ada83: printf ("(Ada)"); break;
|
case DW_LANG_Ada83: printf ("(Ada)"); break;
|
||||||
|
case DW_LANG_C_plus_plus: printf ("(C++)"); break;
|
||||||
case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
|
case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
|
||||||
case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
|
case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
|
||||||
|
case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
|
||||||
|
case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
|
||||||
|
case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
|
||||||
|
case DW_LANG_Modula2: printf ("(Modula 2)"); break;
|
||||||
/* DWARF 2.1 values. */
|
/* DWARF 2.1 values. */
|
||||||
|
case DW_LANG_Java: printf ("(Java)"); break;
|
||||||
case DW_LANG_C99: printf ("(ANSI C99)"); break;
|
case DW_LANG_C99: printf ("(ANSI C99)"); break;
|
||||||
case DW_LANG_Ada95: printf ("(ADA 95)"); break;
|
case DW_LANG_Ada95: printf ("(ADA 95)"); break;
|
||||||
case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
|
case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
|
||||||
|
/* DWARF 3 values. */
|
||||||
|
case DW_LANG_PLI: printf ("(PLI)"); break;
|
||||||
|
case DW_LANG_ObjC: printf ("(Objective C)"); break;
|
||||||
|
case DW_LANG_ObjC_plus_plus: printf ("(Objective C++)"); break;
|
||||||
|
case DW_LANG_UPC: printf ("(Unified Parallel C)"); break;
|
||||||
|
case DW_LANG_D: printf ("(D)"); break;
|
||||||
/* MIPS extension. */
|
/* MIPS extension. */
|
||||||
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
|
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
|
||||||
/* UPC extension. */
|
/* UPC extension. */
|
||||||
case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
|
case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
|
||||||
default:
|
default:
|
||||||
printf ("(Unknown: %lx)", uvalue);
|
if (uvalue >= DW_LANG_lo_user && uvalue <= DW_LANG_hi_user)
|
||||||
|
printf ("(implementation defined: %lx)", uvalue);
|
||||||
|
else
|
||||||
|
printf ("(Unknown: %lx)", uvalue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1684,6 +1695,13 @@ process_debug_info (struct dwarf_section *section, void *file,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!do_loc)
|
||||||
|
printf (_(" <%d><%lx>: Abbrev Number: %lu"),
|
||||||
|
level,
|
||||||
|
(unsigned long) (tags - section_begin
|
||||||
|
- bytes_read),
|
||||||
|
abbrev_number);
|
||||||
|
|
||||||
/* Scan through the abbreviation list until we reach the
|
/* Scan through the abbreviation list until we reach the
|
||||||
correct entry. */
|
correct entry. */
|
||||||
for (entry = first_abbrev;
|
for (entry = first_abbrev;
|
||||||
|
@ -1693,18 +1711,18 @@ process_debug_info (struct dwarf_section *section, void *file,
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
|
if (!do_loc)
|
||||||
|
{
|
||||||
|
printf ("\n");
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
warn (_("Unable to locate entry %lu in the abbreviation table\n"),
|
warn (_("Unable to locate entry %lu in the abbreviation table\n"),
|
||||||
abbrev_number);
|
abbrev_number);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!do_loc)
|
if (!do_loc)
|
||||||
printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
|
printf (_(" (%s)\n"), get_TAG_name (entry->tag));
|
||||||
level,
|
|
||||||
(unsigned long) (tags - section_begin
|
|
||||||
- bytes_read),
|
|
||||||
abbrev_number,
|
|
||||||
get_TAG_name (entry->tag));
|
|
||||||
|
|
||||||
switch (entry->tag)
|
switch (entry->tag)
|
||||||
{
|
{
|
||||||
|
@ -1724,14 +1742,20 @@ process_debug_info (struct dwarf_section *section, void *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (attr = entry->first_attr; attr; attr = attr->next)
|
for (attr = entry->first_attr; attr; attr = attr->next)
|
||||||
tags = read_and_display_attr (attr->attribute,
|
{
|
||||||
attr->form,
|
if (! do_loc)
|
||||||
tags, cu_offset,
|
/* Show the offset from where the tag was extracted. */
|
||||||
compunit.cu_pointer_size,
|
printf (" <%2lx>", tags - section_begin);
|
||||||
offset_size,
|
|
||||||
compunit.cu_version,
|
tags = read_and_display_attr (attr->attribute,
|
||||||
&debug_information [unit],
|
attr->form,
|
||||||
do_loc);
|
tags, cu_offset,
|
||||||
|
compunit.cu_pointer_size,
|
||||||
|
offset_size,
|
||||||
|
compunit.cu_version,
|
||||||
|
&debug_information [unit],
|
||||||
|
do_loc);
|
||||||
|
}
|
||||||
|
|
||||||
if (entry->children)
|
if (entry->children)
|
||||||
++level;
|
++level;
|
||||||
|
@ -2507,7 +2531,6 @@ display_debug_str (struct dwarf_section *section,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
display_debug_info (struct dwarf_section *section, void *file)
|
display_debug_info (struct dwarf_section *section, void *file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* readelf.c -- display contents of an ELF format file
|
/* readelf.c -- display contents of an ELF format file
|
||||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
Originally developed by Eric Youngdale <eric@andante.jic.com>
|
Originally developed by Eric Youngdale <eric@andante.jic.com>
|
||||||
|
@ -80,6 +80,24 @@
|
||||||
#include "elf/external.h"
|
#include "elf/external.h"
|
||||||
#include "elf/internal.h"
|
#include "elf/internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
|
||||||
|
we can obtain the H8 reloc numbers. We need these for the
|
||||||
|
get_reloc_size() function. We include h8.h again after defining
|
||||||
|
RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
|
||||||
|
|
||||||
|
#include "elf/h8.h"
|
||||||
|
#undef _ELF_H8_H
|
||||||
|
|
||||||
|
/* Undo the effects of #including reloc-macros.h. */
|
||||||
|
|
||||||
|
#undef START_RELOC_NUMBERS
|
||||||
|
#undef RELOC_NUMBER
|
||||||
|
#undef FAKE_RELOC
|
||||||
|
#undef EMPTY_RELOC
|
||||||
|
#undef END_RELOC_NUMBERS
|
||||||
|
#undef _RELOC_MACROS_H
|
||||||
|
|
||||||
/* The following headers use the elf/reloc-macros.h file to
|
/* The following headers use the elf/reloc-macros.h file to
|
||||||
automatically generate relocation recognition functions
|
automatically generate relocation recognition functions
|
||||||
such as elf_mips_reloc_type() */
|
such as elf_mips_reloc_type() */
|
||||||
|
@ -7644,6 +7662,7 @@ disassemble_section (Elf_Internal_Shdr *section, FILE *file)
|
||||||
static int
|
static int
|
||||||
dump_section (Elf_Internal_Shdr *section, FILE *file)
|
dump_section (Elf_Internal_Shdr *section, FILE *file)
|
||||||
{
|
{
|
||||||
|
Elf_Internal_Shdr *relsec;
|
||||||
bfd_size_type bytes;
|
bfd_size_type bytes;
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
@ -7667,6 +7686,26 @@ dump_section (Elf_Internal_Shdr *section, FILE *file)
|
||||||
if (!start)
|
if (!start)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* If the section being dumped has relocations against it the user might
|
||||||
|
be expecting these relocations to have been applied. Check for this
|
||||||
|
case and issue a warning message in order to avoid confusion.
|
||||||
|
FIXME: Maybe we ought to have an option that dumps a section with
|
||||||
|
relocs applied ? */
|
||||||
|
for (relsec = section_headers;
|
||||||
|
relsec < section_headers + elf_header.e_shnum;
|
||||||
|
++relsec)
|
||||||
|
{
|
||||||
|
if (relsec->sh_type != SHT_RELA
|
||||||
|
|| SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
|
||||||
|
|| SECTION_HEADER (relsec->sh_info) != section
|
||||||
|
|| relsec->sh_size == 0
|
||||||
|
|| SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
data = start;
|
data = start;
|
||||||
|
|
||||||
while (bytes)
|
while (bytes)
|
||||||
|
@ -7708,9 +7747,47 @@ dump_section (Elf_Internal_Shdr *section, FILE *file)
|
||||||
|
|
||||||
free (start);
|
free (start);
|
||||||
|
|
||||||
|
putchar ('\n');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the number of bytes affected by a given reloc.
|
||||||
|
This information is architecture and reloc dependent.
|
||||||
|
Returns 4 by default, although this is not always correct.
|
||||||
|
It should return 0 if a decision cannot be made.
|
||||||
|
FIXME: This is not the correct way to solve this problem.
|
||||||
|
The proper way is to have target specific reloc sizing functions
|
||||||
|
created by the reloc-macros.h header, in the same way that it
|
||||||
|
already creates the reloc naming functions. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
get_reloc_size (Elf_Internal_Rela * reloc)
|
||||||
|
{
|
||||||
|
switch (elf_header.e_machine)
|
||||||
|
{
|
||||||
|
case EM_H8S:
|
||||||
|
case EM_H8_300:
|
||||||
|
case EM_H8_300H:
|
||||||
|
case EM_H8_500:
|
||||||
|
switch (ELF32_R_TYPE (reloc->r_info))
|
||||||
|
{
|
||||||
|
/* PR gas/3800 - without this information we do not correctly
|
||||||
|
decode the debug information generated by the h8300 assembler. */
|
||||||
|
case R_H8_DIR16:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* FIXME: We need to extend this switch statement to cope with other
|
||||||
|
architecture's relocs. (When those relocs are used against debug
|
||||||
|
sections, and when their size is not 4). But see the multiple
|
||||||
|
inclusions of <elf/h8.h> for an example of the hoops that we need
|
||||||
|
to jump through in order to obtain the reloc numbers. */
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Apply addends of RELA relocations. */
|
/* Apply addends of RELA relocations. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -7720,15 +7797,10 @@ debug_apply_rela_addends (void *file,
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr *relsec;
|
Elf_Internal_Shdr *relsec;
|
||||||
unsigned char *end = start + section->sh_size;
|
unsigned char *end = start + section->sh_size;
|
||||||
/* FIXME: The relocation field size is relocation type dependent. */
|
|
||||||
unsigned int reloc_size = 4;
|
|
||||||
|
|
||||||
if (!is_relocatable)
|
if (!is_relocatable)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (section->sh_size < reloc_size)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (relsec = section_headers;
|
for (relsec = section_headers;
|
||||||
relsec < section_headers + elf_header.e_shnum;
|
relsec < section_headers + elf_header.e_shnum;
|
||||||
++relsec)
|
++relsec)
|
||||||
|
@ -7756,6 +7828,16 @@ debug_apply_rela_addends (void *file,
|
||||||
for (rp = rela; rp < rela + nrelas; ++rp)
|
for (rp = rela; rp < rela + nrelas; ++rp)
|
||||||
{
|
{
|
||||||
unsigned char *loc;
|
unsigned char *loc;
|
||||||
|
unsigned int reloc_size;
|
||||||
|
|
||||||
|
reloc_size = get_reloc_size (rp);
|
||||||
|
if (reloc_size == 0)
|
||||||
|
{
|
||||||
|
warn (_("skipping relocation of unknown size against offset 0x%lx in section %s\n"),
|
||||||
|
(unsigned long) rp->r_offset,
|
||||||
|
SECTION_NAME (section));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
loc = start + rp->r_offset;
|
loc = start + rp->r_offset;
|
||||||
if ((loc + reloc_size) > end)
|
if ((loc + reloc_size) > end)
|
||||||
|
|
Loading…
Reference in a new issue