Author: sewardj
Date: 2008-01-08 23:59:03 +0000 (Tue, 08 Jan 2008)
New Revision: 7328

Log:
A lot more tidying up.  Make x86-linux work again.

Modified:
   branches/DATASYMS/coregrind/m_debuginfo/readelf.c


Modified: branches/DATASYMS/coregrind/m_debuginfo/readelf.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readelf.c   2008-01-08 17:44:04 UTC 
(rev 7327)
+++ branches/DATASYMS/coregrind/m_debuginfo/readelf.c   2008-01-08 23:59:03 UTC 
(rev 7328)
@@ -833,16 +833,16 @@
    Bool          res, ok;
    SysRes        fd, sres;
    Word          i;
-   OffT          offset_oimage = 0;
-   Addr          dimage = 0;
-   UWord         n_dimage = 0;
-   OffT          offset_dimage = 0;
    Bool          debug = False;
 
    /* Image addresses for the ELF file we're working with. */
    Addr          oimage   = 0;
    UWord         n_oimage = 0;
 
+   /* Ditto for any ELF debuginfo file that we might happen to load. */
+   Addr          dimage   = 0;
+   UWord         n_dimage = 0;
+
    /* ELF header for the main file.  Should == oimage since is at
       start of file. */
    ElfXX_Ehdr* ehdr_img = NULL;
@@ -1007,9 +1007,8 @@
    vg_assert(di->soname == NULL);
 
    {
-//zz      Bool offset_set = False;
       ElfXX_Addr prev_addr = 0;
-      Addr baseaddr = 0;
+      Addr       baseaddr = 0;
 
       for (i = 0; i < phdr_nent; i++) {
          ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
@@ -1147,12 +1146,11 @@
 
       /* Find avma-s for: .text .data .bss .plt .got .opd .eh_frame */
 
-      /* Accept .text where mapped as rx */
+      /* Accept .text where mapped as rx (code) */
       if (0 == VG_(strcmp)(name, ".text")) {
          if (inrx && size > 0 && di->text_size == 0) {
             di->text_avma = di->rx_map_avma + foff - di->rx_map_foff;
-            di->text_size = //di->rx_map_size; //size;
-                            size;
+            di->text_size = size;
             di->text_bias = VG_PGROUNDDN(di->text_avma) - VG_PGROUNDDN(svma);
             if (debug)
                VG_(printf)("acquiring .text avma = %p\n", di->text_avma);
@@ -1161,7 +1159,7 @@
          }
       }
 
-      /* Accept .data where mapped as rw */
+      /* Accept .data where mapped as rw (data) */
       if (0 == VG_(strcmp)(name, ".data")) {
          if (inrw && size > 0 && di->data_size == 0) {
             di->data_avma = di->rw_map_avma + foff - di->rw_map_foff;
@@ -1174,7 +1172,7 @@
          }
       }
 
-      /* Accept .bss where mapped as rw */
+      /* Accept .bss where mapped as rw (data) */
       if (0 == VG_(strcmp)(name, ".bss")) {
          if (inrw && size > 0 && di->bss_size == 0) {
             di->bss_avma = di->rw_map_avma + foff - di->rw_map_foff;
@@ -1186,7 +1184,31 @@
          }
       }
 
-      /* Accept .opd where mapped as rw */
+      /* Accept .got where mapped as rw (data) */
+      if (0 == VG_(strcmp)(name, ".got")) {
+         if (inrw && size > 0 && di->got_size == 0) {
+            di->got_avma = di->rw_map_avma + foff - di->rw_map_foff;
+            di->got_size = size;
+            if (debug)
+               VG_(printf)("acquiring .got avma = %p\n", di->got_avma);
+         } else {
+            BAD(".got");
+         }
+      }
+
+      /* Accept .plt where mapped as rx (code) */
+      if (0 == VG_(strcmp)(name, ".plt")) {
+         if (inrx && size > 0 && di->plt_size == 0) {
+            di->plt_avma = di->rx_map_avma + foff - di->rx_map_foff;
+            di->plt_size = size;
+            if (debug)
+               VG_(printf)("acquiring .plt avma = %p\n", di->plt_avma);
+         } else {
+            BAD(".plt");
+         }
+      }
+
+      /* Accept .opd where mapped as rw (data) */
       if (0 == VG_(strcmp)(name, ".opd")) {
          if (inrw && size > 0 && di->opd_size == 0) {
             di->opd_avma = di->rw_map_avma + foff - di->rw_map_foff;
@@ -1198,10 +1220,10 @@
          }
       }
 
-      /* Accept .eh_frame where mapped as rx */
+      /* Accept .eh_frame where mapped as rx (code) (?!) */
       if (0 == VG_(strcmp)(name, ".eh_frame")) {
          if (inrx && size > 0 && di->ehframe_size == 0) {
-            di->ehframe_avma = VG_PGROUNDDN(di->rx_map_avma + foff - 
di->rx_map_foff);
+            di->ehframe_avma = di->rx_map_avma + foff - di->rx_map_foff;
             di->ehframe_size = size;
             if (debug)
                VG_(printf)("acquiring .eh_frame avma = %p\n", 
di->ehframe_avma);
@@ -1236,13 +1258,14 @@
    /* Find interesting sections, read the symbol table(s), read any debug
       information */
    {
-      /* IMAGE addresses: pointers to start of sections (in the
-         oimage, not in the running image) -- image addresses */
+      /* IMAGE addresses: pointers to start of sections in the
+         transiently loaded oimage, not in the fragments of the file
+         mapped in by the guest's dynamic linker. */
       UChar*     strtab_img      = NULL; /* .strtab */
       ElfXX_Sym* symtab_img      = NULL; /* .symtab */
       UChar*     dynstr_img      = NULL; /* .dynstr */
       ElfXX_Sym* dynsym_img      = NULL; /* .dynsym */
-      Char*      debuglink_img   = NULL; /* .gnu_debuglink */
+      UChar*     debuglink_img   = NULL; /* .gnu_debuglink */
       UChar*     stab_img        = NULL; /* .stab         (stabs)  */
       UChar*     stabstr_img     = NULL; /* .stabstr      (stabs)  */
       UChar*     debug_line_img  = NULL; /* .debug_line   (dwarf2) */
@@ -1252,69 +1275,58 @@
       UChar*     dwarf1d_img     = NULL; /* .debug        (dwarf1) */
       UChar*     dwarf1l_img     = NULL; /* .line         (dwarf1) */
       UChar*     ehframe_img     = NULL; /* .eh_frame     (dwarf2) */
-      UChar*     opd_filea_img   = NULL; /* .opd          (dwarf2, 
ppc64-linux) */
-      UChar*     dummy_filea_img = NULL;
+      UChar*     opd_img         = NULL; /* .opd          (dwarf2, 
ppc64-linux) */
 
-      OffT       symtab_offset   = offset_oimage;
-      OffT       dynsym_offset   = offset_oimage;
-      OffT       debug_offset    = offset_oimage;
-      OffT       opd_offset      = offset_oimage;
-
       /* Section sizes, in bytes */
-      UInt       strtab_sz       = 0;
-      UInt       symtab_sz       = 0;
-      UInt       dynstr_sz       = 0;
-      UInt       dynsym_sz       = 0;
-      UInt       debuglink_sz    = 0;
-      UInt       stab_sz         = 0;
-      UInt       stabstr_sz      = 0;
-      UInt       debug_line_sz   = 0;
-      UInt       debug_info_sz   = 0;
-      UInt       debug_abbv_sz   = 0;
-      UInt       debug_str_sz    = 0;
-      UInt       dwarf1d_sz      = 0;
-      UInt       dwarf1l_sz      = 0;
-      UInt       ehframe_sz      = 0;
+      SizeT      strtab_sz       = 0;
+      SizeT      symtab_sz       = 0;
+      SizeT      dynstr_sz       = 0;
+      SizeT      dynsym_sz       = 0;
+      SizeT      debuglink_sz    = 0;
+      SizeT      stab_sz         = 0;
+      SizeT      stabstr_sz      = 0;
+      SizeT      debug_line_sz   = 0;
+      SizeT      debug_info_sz   = 0;
+      SizeT      debug_abbv_sz   = 0;
+      SizeT      debug_str_sz    = 0;
+      SizeT      dwarf1d_sz      = 0;
+      SizeT      dwarf1l_sz      = 0;
+      SizeT      ehframe_sz      = 0;
 
-      /* Section actual virtual addresses */
-      Addr       ehframe_avma    = 0;
-
       /* Find all interesting sections */
 
       /* What FIND does: it finds the section called SEC_NAME.  The
-        size of it is assigned to SEC_SIZE.  The address that it will
-        appear in the running image is assigned to SEC_VMA (note,
-        this will be meaningless for sections which are not marked
-        loadable.  Even for sections which are marked loadable, the
+        size of it is assigned to SEC_SIZE.  The address of the
+        section in the transiently loaded oimage is assigned to
+        SEC_FILEA.  Even for sections which are marked loadable, the
         client's ld.so may not have loaded them yet, so there is no
-        guarantee that we can safely prod around in any such area)
-        The address of the section in the transiently loaded oimage
-        is assigned to SEC_FILEA.  Because the entire object file is
-        transiently mapped aboard for inspection, it's always safe to
-        inspect that area. */
+        guarantee that we can safely prod around in any such area).
+        Because the entire object file is transiently mapped aboard
+        for inspection, it's always safe to inspect that area. */
 
       for (i = 0; i < ehdr_img->e_shnum; i++) {
 
-#        define FIND(sec_name, sec_size, sec_filea) \
-         if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
-                                        + shdr_img[i].sh_name)) { \
-            Bool nobits; \
-            sec_filea = (void*)(oimage + shdr_img[i].sh_offset); \
-            sec_size  = shdr_img[i].sh_size; \
-            nobits = shdr_img[i].sh_type == SHT_NOBITS; \
-            TRACE_SYMTAB( "%18s: filea %p .. %p, vma %p .. %p\n", \
-                          sec_name, (UChar*)sec_filea, \
-                          ((UChar*)sec_filea) + sec_size - 1); \
-            /* SHT_NOBITS sections have zero size in the file. */ \
-            if ( shdr_img[i].sh_offset \
-                 + (nobits ? 0 : sec_size) > n_oimage ) { \
-               ML_(symerr)("   section beyond image end?!"); \
-               goto out; \
+#        define FIND(sec_name, sec_size, sec_img) \
+         do { ElfXX_Shdr* shdr \
+                 = INDEX_BIS( shdr_img, i, shdr_ent_szB ); \
+            if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
+                                           + shdr->sh_name)) { \
+               Bool nobits; \
+               sec_img  = (void*)(oimage + shdr->sh_offset); \
+               sec_size = shdr->sh_size; \
+               nobits   = shdr->sh_type == SHT_NOBITS; \
+               TRACE_SYMTAB( "%18s: filea %p .. %p, vma %p .. %p\n", \
+                             sec_name, (UChar*)sec_img, \
+                             ((UChar*)sec_img) + sec_size - 1); \
+               /* SHT_NOBITS sections have zero size in the file. */ \
+               if ( shdr->sh_offset \
+                    + (nobits ? 0 : sec_size) > n_oimage ) { \
+                  ML_(symerr)("   section beyond image end?!"); \
+                  goto out; \
+               } \
             } \
-         }
+         } while (0);
 
-         /* Nb: must find where .got and .plt sections will be in the
-          * executable image, not in the object image transiently loaded. */
          /*   NAME              SIZE           IMAGE addr */
          FIND(".dynsym",        dynsym_sz,     dynsym_img)
          FIND(".dynstr",        dynstr_sz,     dynstr_img)
@@ -1335,10 +1347,6 @@
          FIND(".line",          dwarf1l_sz,    dwarf1l_img)
          FIND(".eh_frame",      ehframe_sz,    ehframe_img)
 
-         FIND(".got",           di->got_size,  dummy_filea_img)
-         FIND(".plt",           di->plt_size,  dummy_filea_img)
-         FIND(".opd",           di->opd_size,  opd_filea_img)
-
 #        undef FIND
       }
          
@@ -1354,75 +1362,117 @@
 
          /* See if we can find a matching debug file */
          dimage = find_debug_file(di->filename, debuglink_img, crc, &n_dimage);
-         if (dimage != 0) {
-            ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage;
 
-            if (n_dimage >= sizeof(ElfXX_Ehdr) 
-                && ML_(is_elf_object_file(ehdr_dimg, n_dimage))
-                && ehdr_dimg->e_phoff + ehdr_dimg->e_phnum*sizeof(ElfXX_Phdr) 
<= n_dimage
-                && ehdr_dimg->e_shoff + ehdr_dimg->e_shnum*sizeof(ElfXX_Shdr) 
<= n_dimage)
-            {
-               Bool need_symtab = (NULL == symtab_img);
-               Bool need_stabs  = (NULL == stab_img);
-               Bool need_dwarf2 = (NULL == debug_info_img);
-               Bool need_dwarf1 = (NULL == dwarf1d_img);
-               ElfXX_Shdr* shdr;
-               UChar* sh_strtab;
+         if (dimage != 0 
+             && n_dimage >= sizeof(ElfXX_Ehdr)
+             && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
 
-               for (i = 0; i < ehdr_dimg->e_phnum; i++) {
-                  ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + 
ehdr_dimg->e_phoff))[i];
-                  if (o_phdr->p_type == PT_LOAD) {
-                     offset_dimage = di->text_avma - o_phdr->p_vaddr;
-                     break;
-                  }
-               }
+            /* Pull out and validate program header and section header info */
+            ElfXX_Ehdr* ehdr_dimg        = (ElfXX_Ehdr*)dimage;
+            ElfXX_Phdr* phdr_dimg        = (ElfXX_Phdr*)( ((UChar*)ehdr_dimg)
+                                                          + ehdr_dimg->e_phoff 
);
+            UWord       phdr_dnent       = ehdr_dimg->e_phnum;
+            UWord       phdr_dent_szB    = ehdr_dimg->e_phentsize;
+            ElfXX_Shdr* shdr_dimg        = (ElfXX_Shdr*)( ((UChar*)ehdr_dimg)
+                                                          + ehdr_dimg->e_shoff 
);
+            UWord       shdr_dnent       = ehdr_dimg->e_shnum;
+            UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
+            UChar*      shdr_strtab_dimg = NULL;
 
-               debug_offset = offset_dimage;
-               if (need_symtab)
-                  symtab_offset = offset_dimage;
+            Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
 
-               shdr = (ElfXX_Shdr*)(dimage + ehdr_dimg->e_shoff);
-               sh_strtab = (UChar*)(dimage + 
shdr[ehdr_dimg->e_shstrndx].sh_offset);
+            if (phdr_dnent == 0
+                || !contained_within(
+                       dimage, n_dimage,
+                       (Addr)phdr_dimg, phdr_dnent * phdr_dent_szB)) {
+               ML_(symerr)("Missing or invalid ELF Program Header Table 
(debuginfo file)");
+               goto out;
+            }
 
-               /* Same deal as previous FIND, except simpler - doesn't
-                  look for avma, only oimage address. */
+            if (shdr_dnent == 0
+                || !contained_within(
+                       dimage, n_dimage,
+                       (Addr)shdr_dimg, shdr_dnent * shdr_dent_szB)) {
+               ML_(symerr)("Missing or invalid ELF Section Header Table 
(debuginfo file)");
+               goto out;
+            }
 
-               /* Find all interesting sections */
-               for (i = 0; i < ehdr_dimg->e_shnum; i++) {
+            /* Also find the section header's string table, and validate. */
+            /* checked previously by is_elf_object_file: */
+            vg_assert( ehdr_dimg->e_shstrndx != SHN_UNDEF );
 
-#                 define FIND(condition, sec_name, sec_size, sec_filea)        
\
+            shdr_strtab_dimg
+               = (UChar*)( ((UChar*)ehdr_dimg)
+                           + shdr_dimg[ehdr_dimg->e_shstrndx].sh_offset);
+            if (!contained_within( dimage, n_dimage,
+                                   (Addr)shdr_strtab_dimg,
+                                   1/*bogus, but we don't know the real size*/ 
)) {
+               ML_(symerr)("Invalid ELF Section Header String Table (debuginfo 
file)");
+               goto out;
+            }
+
+            need_symtab = (NULL == symtab_img);
+            need_stabs  = (NULL == stab_img);
+            need_dwarf2 = (NULL == debug_info_img);
+            need_dwarf1 = (NULL == dwarf1d_img);
+
+            for (i = 0; i < ehdr_dimg->e_phnum; i++) {
+               ElfXX_Phdr* phdr 
+                  = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff), i, 
phdr_ent_szB );
+               if (phdr->p_type == PT_LOAD) {
+                  //offset_dimage = di->text_avma - phdr->p_vaddr;
+                  // FIXME: update di->text_bias at this point?
+                  // or can we assume the SVMAs in the debuginfo
+                  // file (hence, the biases) are the same as
+                  // established from the main file?
+                  break;
+               }
+            }
+
+            /* Same deal as previous FIND, except only do it for those
+               sections for which we didn't find anything useful in
+               the main file. */
+
+            /* Find all interesting sections */
+            for (i = 0; i < ehdr_dimg->e_shnum; i++) {
+
+#              define FIND(condition, sec_name, sec_size, sec_img)     \
+               do { ElfXX_Shdr* shdr \
+                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
                   if (condition \
-                      && 0 == VG_(strcmp)(sec_name, sh_strtab + 
shdr[i].sh_name)) { \
+                      && 0 == VG_(strcmp)(sec_name, \
+                                          shdr_strtab_dimg + shdr->sh_name)) { 
\
                      Bool nobits; \
-                     if (0 != sec_filea) \
+                     if (0 != sec_img) \
                         VG_(core_panic)("repeated section!\n"); \
-                     sec_filea = (void*)(dimage + shdr[i].sh_offset); \
-                     sec_size  = shdr[i].sh_size; \
-                     nobits = shdr[i].sh_type == SHT_NOBITS; \
+                     sec_img  = (void*)(dimage + shdr->sh_offset); \
+                     sec_size = shdr->sh_size; \
+                     nobits   = shdr->sh_type == SHT_NOBITS; \
                      TRACE_SYMTAB( "%18s: filea %p .. %p\n", \
-                                   sec_name, (UChar*)sec_filea, \
-                                             ((UChar*)sec_filea) + sec_size - 
1); \
+                                   sec_name, (UChar*)sec_img, \
+                                             ((UChar*)sec_img) + sec_size - 
1); \
                      /* SHT_NOBITS sections have zero size in the file. */ \
-                     if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > 
n_dimage ) { \
+                     if ( shdr->sh_offset \
+                          + (nobits ? 0 : sec_size) > n_dimage ) { \
                         ML_(symerr)("   section beyond image end?!"); \
                         goto out; \
                      } \
-                  }
+                  } \
+               } while (0);
 
-                  /*   ??           NAME             SIZE           IMAGE addr 
*/
-                  FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
-                  FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
-                  FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
-                  FIND(need_stabs,  ".stabstr",      stabstr_sz,    
stabstr_img)
-                  FIND(need_dwarf2, ".debug_line",   debug_line_sz, 
debug_line_img)
-                  FIND(need_dwarf2, ".debug_info",   debug_info_sz, 
debug_info_img)
-                  FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, 
debug_abbv_img)
-                  FIND(need_dwarf2, ".debug_str",    debug_str_sz,  
debug_str_img)
-                  FIND(need_dwarf1, ".debug",        dwarf1d_sz,    
dwarf1d_img)
-                  FIND(need_dwarf1, ".line",         dwarf1l_sz,    
dwarf1l_img)
+               /* NEEDED?        NAME             SIZE           IMAGE addr */
+               FIND(need_symtab, ".symtab",       symtab_sz,     symtab_img)
+               FIND(need_symtab, ".strtab",       strtab_sz,     strtab_img)
+               FIND(need_stabs,  ".stab",         stab_sz,       stab_img)
+               FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
+               FIND(need_dwarf2, ".debug_line",   debug_line_sz, 
debug_line_img)
+               FIND(need_dwarf2, ".debug_info",   debug_info_sz, 
debug_info_img)
+               FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, 
debug_abbv_img)
+               FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
+               FIND(need_dwarf1, ".debug",        dwarf1d_sz,    dwarf1d_img)
+               FIND(need_dwarf1, ".line",         dwarf1l_sz,    dwarf1l_img)
 
-#                 undef FIND
-               }
+#              undef FIND
             }
          }
       }
@@ -1441,14 +1491,14 @@
          read_elf_symtab = read_elf_symtab__normal;
 #        endif
          read_elf_symtab(di, "symbol table",
-                         symtab_img, symtab_sz, di->text_bias, 
/*symtab_offset,*/
+                         symtab_img, symtab_sz, di->text_bias,
                          strtab_img, strtab_sz, 
-                         opd_filea_img, opd_offset);
+                         opd_img, di->data_bias/*opd_offset*/);
 
          read_elf_symtab(di, "dynamic symbol table",
-                         dynsym_img, dynsym_sz, di->text_bias, 
/*dynsym_offset,*/
+                         dynsym_img, dynsym_sz, di->text_bias,
                          dynstr_img, dynstr_sz, 
-                         opd_filea_img, opd_offset);
+                         opd_img, di->data_bias/*opd_offset*/);
       }
 
       /* Read .eh_frame (call-frame-info) if any */
@@ -1462,7 +1512,7 @@
          we ignore it. */
 #     if !defined(VGP_amd64_linux)
       if (stab_img && stabstr_img) {
-         ML_(read_debuginfo_stabs) ( di, debug_offset, stab_img, stab_sz, 
+         ML_(read_debuginfo_stabs) ( di, di->text_bias, stab_img, stab_sz, 
                                          stabstr_img, stabstr_sz );
       }
 #     endif
@@ -1473,7 +1523,7 @@
          before using it. */
       if (debug_info_img && debug_abbv_img && debug_line_img
                                            /* && debug_str_img */) {
-         ML_(read_debuginfo_dwarf2) ( di, di->text_bias, /*debug_offset,*/ 
+         ML_(read_debuginfo_dwarf2) ( di, di->text_bias,
                                       debug_info_img,   debug_info_sz,
                                       debug_abbv_img,
                                       debug_line_img,   debug_line_sz,


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to