* readelf.c (display_debug_info): Add to abbrev_offset the addend
authorAlexandre Oliva <aoliva@redhat.com>
Wed, 8 Aug 2001 11:17:46 +0000 (11:17 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Wed, 8 Aug 2001 11:17:46 +0000 (11:17 +0000)
of any RELA relocation for the abbrev_offset memory location that
refers to the .debug_abbrev section symbol.

binutils/ChangeLog
binutils/readelf.c

index 51e5e01..41bc735 100644 (file)
@@ -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.
index fc7e0e3..ddad104 100644 (file)
@@ -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);