aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-02-06 15:15:13 +0000
committerNick Clifton <nickc@redhat.com>2007-02-06 15:15:13 +0000
commit4b78141aa2794cc7c43bf1573d132ed2951244cf (patch)
treedb165365b755a4b84de2d7fce0f15259556c2f77
parent7b5030c061711ca87f39eaa5363937d9f4ededb7 (diff)
downloadgdb-4b78141aa2794cc7c43bf1573d132ed2951244cf.zip
gdb-4b78141aa2794cc7c43bf1573d132ed2951244cf.tar.gz
gdb-4b78141aa2794cc7c43bf1573d132ed2951244cf.tar.bz2
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.
-rw-r--r--binutils/ChangeLog15
-rw-r--r--binutils/dwarf.c67
-rw-r--r--binutils/readelf.c94
3 files changed, 148 insertions, 28 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index cd39f65..b4f78a0 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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>
* readelf.c (dump_relocations): Don't check for
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index fe75b63..ad709b9 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -1,5 +1,5 @@
/* dwarf.c -- display DWARF contents of a BFD binary file
- Copyright 2005, 2006
+ Copyright 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GNU Binutils.
@@ -1213,26 +1213,37 @@ read_and_display_attr_value (unsigned long attribute,
case DW_AT_language:
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_C: printf ("(non-ANSI C)"); 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_Cobol85: printf ("(Cobol 85)"); 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_Cobol74: printf ("(Cobol 74)"); break;
- case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
+ case DW_LANG_Modula2: printf ("(Modula 2)"); break;
/* DWARF 2.1 values. */
+ case DW_LANG_Java: printf ("(Java)"); break;
case DW_LANG_C99: printf ("(ANSI C99)"); break;
case DW_LANG_Ada95: printf ("(ADA 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. */
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
/* UPC extension. */
case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
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;
@@ -1684,6 +1695,13 @@ process_debug_info (struct dwarf_section *section, void *file,
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
correct entry. */
for (entry = first_abbrev;
@@ -1693,18 +1711,18 @@ process_debug_info (struct dwarf_section *section, void *file,
if (entry == NULL)
{
+ if (!do_loc)
+ {
+ printf ("\n");
+ fflush (stdout);
+ }
warn (_("Unable to locate entry %lu in the abbreviation table\n"),
abbrev_number);
return 0;
}
if (!do_loc)
- printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
- level,
- (unsigned long) (tags - section_begin
- - bytes_read),
- abbrev_number,
- get_TAG_name (entry->tag));
+ printf (_(" (%s)\n"), get_TAG_name (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)
- tags = read_and_display_attr (attr->attribute,
- attr->form,
- tags, cu_offset,
- compunit.cu_pointer_size,
- offset_size,
- compunit.cu_version,
- &debug_information [unit],
- do_loc);
+ {
+ if (! do_loc)
+ /* Show the offset from where the tag was extracted. */
+ printf (" <%2lx>", tags - section_begin);
+
+ tags = read_and_display_attr (attr->attribute,
+ attr->form,
+ tags, cu_offset,
+ compunit.cu_pointer_size,
+ offset_size,
+ compunit.cu_version,
+ &debug_information [unit],
+ do_loc);
+ }
if (entry->children)
++level;
@@ -2507,7 +2531,6 @@ display_debug_str (struct dwarf_section *section,
return 1;
}
-
static int
display_debug_info (struct dwarf_section *section, void *file)
{
diff --git a/binutils/readelf.c b/binutils/readelf.c
index f1f849f..b1b5c5c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -1,5 +1,5 @@
/* 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.
Originally developed by Eric Youngdale <eric@andante.jic.com>
@@ -80,6 +80,24 @@
#include "elf/external.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
automatically generate relocation recognition functions
such as elf_mips_reloc_type() */
@@ -7644,6 +7662,7 @@ disassemble_section (Elf_Internal_Shdr *section, FILE *file)
static int
dump_section (Elf_Internal_Shdr *section, FILE *file)
{
+ Elf_Internal_Shdr *relsec;
bfd_size_type bytes;
bfd_vma addr;
unsigned char *data;
@@ -7667,6 +7686,26 @@ dump_section (Elf_Internal_Shdr *section, FILE *file)
if (!start)
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;
while (bytes)
@@ -7708,9 +7747,47 @@ dump_section (Elf_Internal_Shdr *section, FILE *file)
free (start);
+ putchar ('\n');
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. */
static int
@@ -7720,15 +7797,10 @@ debug_apply_rela_addends (void *file,
{
Elf_Internal_Shdr *relsec;
unsigned char *end = start + section->sh_size;
- /* FIXME: The relocation field size is relocation type dependent. */
- unsigned int reloc_size = 4;
if (!is_relocatable)
return 1;
- if (section->sh_size < reloc_size)
- return 1;
-
for (relsec = section_headers;
relsec < section_headers + elf_header.e_shnum;
++relsec)
@@ -7756,6 +7828,16 @@ debug_apply_rela_addends (void *file,
for (rp = rela; rp < rela + nrelas; ++rp)
{
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;
if ((loc + reloc_size) > end)