aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c63
2 files changed, 69 insertions, 0 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 51e5e01..41bc735 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2001-08-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * readelf.c (display_debug_info): Add to abbrev_offset the addend
+ of any RELA relocation for the abbrev_offset memory location that
+ refers to the .debug_abbrev section symbol.
+
2001-08-07 H.J. Lu <hjl@gnu.org>
* readelf.c (process_file): Return 0 if OK, otherwise return 1.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index fc7e0e3..ddad104 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7026,6 +7026,7 @@ display_debug_info (section, start, file)
{
DWARF2_External_CompUnit * external;
DWARF2_Internal_CompUnit compunit;
+ Elf32_Internal_Shdr * relsec;
unsigned char * tags;
int i;
int level;
@@ -7038,6 +7039,68 @@ display_debug_info (section, start, file)
compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
+ /* Check for RELA relocations in the abbrev_offset address, and
+ apply them. */
+ for (relsec = section_headers;
+ relsec < section_headers + elf_header.e_shnum;
+ ++relsec)
+ {
+ unsigned long nrelas, nsyms;
+ Elf_Internal_Rela *rela, *rp;
+ Elf32_Internal_Shdr *symsec;
+ Elf_Internal_Sym *symtab;
+ Elf_Internal_Sym *sym;
+
+ if (relsec->sh_type != SHT_RELA
+ || section_headers + relsec->sh_info != section)
+ continue;
+
+ if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
+ & rela, & nrelas))
+ return 0;
+
+ symsec = section_headers + relsec->sh_link;
+ nsyms = symsec->sh_size / symsec->sh_entsize;
+ symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
+
+ for (rp = rela; rp < rela + nrelas; ++rp)
+ {
+ if (rp->r_offset
+ != (bfd_vma) ((unsigned char *) &external->cu_abbrev_offset
+ - section_begin))
+ continue;
+
+ if (is_32bit_elf)
+ {
+ sym = symtab + ELF32_R_SYM (rp->r_info);
+
+ if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
+ {
+ warn (_("Skipping unexpected symbol type %u"),
+ ELF32_ST_TYPE (sym->st_info));
+ continue;
+ }
+ }
+ else
+ {
+ sym = symtab + ELF64_R_SYM (rp->r_info);
+
+ if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
+ {
+ warn (_("Skipping unexpected symbol type %u"),
+ ELF64_ST_TYPE (sym->st_info));
+ continue;
+ }
+ }
+
+ compunit.cu_abbrev_offset += rp->r_addend;
+ break;
+ }
+
+ free (rela);
+ break;
+ }
+
tags = start + sizeof (* external);
cu_offset = start - section_begin;
start += compunit.cu_length + sizeof (external->cu_length);