]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
If read_lib_symbols() fails, once again discard the SegInfo.
authorNicholas Nethercote <njn@valgrind.org>
Sun, 26 Jun 2005 02:19:17 +0000 (02:19 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Sun, 26 Jun 2005 02:19:17 +0000 (02:19 +0000)
And some other minor cleanups.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4027

coregrind/m_debuginfo/priv_symtab.h
coregrind/m_debuginfo/symtab.c

index 65c062670546d98467745f768fe944eb0d691a21..f74ba2e5e4226e36578b4b427d76241a9ae7322f 100644 (file)
@@ -171,7 +171,7 @@ extern void ML_(ppCfiSI)   ( CfiSI* );
 struct _SegInfo {
    struct _SegInfo* next;      /* list of SegInfos */
 
-   Int         ref;
+   Int   ref;
 
    /* Description of the mapped segment. */
    Addr   start;
index 729128dea6d906a35ecbaf0f53fa8ba462c0b7c6..379a5e8cd8414001339b90a891a1c6afd94e57da 100644 (file)
 
 #include <elf.h>          /* ELF defns */
 
+/* The root structure for the entire symbol table system.  It is a
+   linked list of SegInfos.  Note that this entire mechanism assumes
+   that what we read from /proc/self/maps doesn't contain overlapping
+   address ranges, and as a result the SegInfos in this list describe
+   disjoint address ranges. 
+*/
 static SegInfo* segInfo_list = NULL;
 
 /*------------------------------------------------------------*/
@@ -1290,12 +1296,15 @@ Bool read_lib_symbols ( SegInfo* si )
 
       si->offset = 0;
 
+      vg_assert(si->soname == NULL);
+
       for (i = 0; i < ehdr->e_phnum; i++) {
         ElfXX_Phdr *o_phdr;
         ElfXX_Addr mapped, mapped_end;
 
         o_phdr = &((ElfXX_Phdr *)(oimage + ehdr->e_phoff))[i];
 
+         // Try to get the soname.
         if (o_phdr->p_type == PT_DYNAMIC && si->soname == NULL) {
            const ElfXX_Dyn *dyn = (const ElfXX_Dyn *)(oimage + o_phdr->p_offset);
            Int stroff = -1;
@@ -1329,15 +1338,16 @@ Bool read_lib_symbols ( SegInfo* si )
            baseaddr = o_phdr->p_vaddr;
         }
 
+         // Make sure the Phdrs are in order
         if (o_phdr->p_vaddr < prev_addr) {
            ML_(symerr)("ELF Phdrs are out of order!?");
             goto out;
         }
         prev_addr = o_phdr->p_vaddr;
 
+         // Get the data and bss start/size if appropriate
         mapped = o_phdr->p_vaddr + si->offset;
         mapped_end = mapped + o_phdr->p_memsz;
-
         if (si->data_start == 0 &&
             (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) {
            si->data_start = mapped;
@@ -1348,14 +1358,13 @@ Bool read_lib_symbols ( SegInfo* si )
            else
               si->bss_size = 0;
         }
-
-        mapped = mapped & ~(VKI_PAGE_SIZE-1);
-        mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
-
 #if 0
         /* 20050228: disabled this until VG_(next_segment) can be
            reinstated in some clean incarnation of the low level
            memory manager. */
+        mapped = mapped & ~(VKI_PAGE_SIZE-1);
+        mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
+
         if (VG_(needs).data_syms &&
             (mapped >= si->start && mapped <= (si->start+si->size)) &&
             (mapped_end > (si->start+si->size))) {
@@ -1444,8 +1453,6 @@ Bool read_lib_symbols ( SegInfo* si )
       Addr       dummy_addr      = 0;
       Addr       ehframe_addr    = 0;
 
-      Bool       has_debuginfo = False;
-
       /* Find all interesting sections */
       for (i = 0; i < ehdr->e_shnum; i++) {
 #        define FIND(sec_name, sec_data, sec_size, sec_addr, in_exec, type) \
@@ -1567,14 +1574,12 @@ Bool read_lib_symbols ( SegInfo* si )
          appears reading stabs stuff on amd64-linux doesn't work, so
          we ignore it. */
 #     if !defined(VGP_amd64_linux)
-      if (stab != NULL && stabstr != NULL) {
-         has_debuginfo = True;
+      if (stab && stabstr) {
          ML_(read_debuginfo_stabs) ( si, stab, stab_sz, 
                                          stabstr, stabstr_sz );
       }
 #     endif
       if (debug_line) {
-         has_debuginfo = True;
          ML_(read_debuginfo_dwarf2) ( si, 
                                       debug_info,   debug_info_sz,
                                       debug_abbv,
@@ -1582,13 +1587,8 @@ Bool read_lib_symbols ( SegInfo* si )
                                       debug_str );
       }
       if (dwarf1d && dwarf1l) {
-         has_debuginfo = True;
          ML_(read_debuginfo_dwarf1) ( si, dwarf1d, dwarf1d_sz, 
                                           dwarf1l, dwarf1l_sz );
-      } 
-      if (!has_debuginfo) {
-         ML_(symerr)("   object doesn't have any line number info");
-         goto out;
       }
    }
    res = True;
@@ -1610,61 +1610,35 @@ Bool read_lib_symbols ( SegInfo* si )
 /*--- Main entry point for symbols table reading.          ---*/
 /*------------------------------------------------------------*/
 
-/* The root structure for the entire symbol table system.  It is a
-   linked list of SegInfos.  Note that this entire mechanism assumes
-   that what we read from /proc/self/maps doesn't contain overlapping
-   address ranges, and as a result the SegInfos in this list describe
-   disjoint address ranges. 
-*/
-SegInfo *VG_(read_seg_symbols) ( Addr seg_addr, SizeT seg_len,
-                                 OffT seg_offset, const Char* seg_filename)
+static SegInfo*
+alloc_SegInfo(Addr start, SizeT size, OffT foffset, const Char* filename)
 {
-   SegInfo* si;
+   SegInfo* si = VG_(arena_calloc)(VG_AR_SYMTAB, 1, sizeof(SegInfo));
 
-   VGP_PUSHCC(VgpReadSyms);
+   si->start    = start;
+   si->size     = size;
+   si->foffset  = foffset;
+   si->filename = VG_(arena_strdup)(VG_AR_SYMTAB, filename);
 
-   /* Get the record initialised right. */
-   si = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(SegInfo));
+   si->ref = 1;
 
-   VG_(memset)(si, 0, sizeof(*si));
-   si->start    = seg_addr;
-   si->size     = seg_len;
-   si->foffset  = seg_offset;
-   si->filename = VG_(arena_strdup)(VG_AR_SYMTAB, seg_filename);
+   // Everything else -- pointers, sizes, arrays -- is zeroed by calloc.
 
-   si->ref = 1;
+   return si;
+}
 
-   si->symtab = NULL;
-   si->symtab_size = si->symtab_used = 0;
-   si->loctab = NULL;
-   si->loctab_size = si->loctab_used = 0;
-   si->strchunks = NULL;
-   si->scopetab = NULL;
-   si->scopetab_size = si->scopetab_used = 0;
-   si->cfisi = NULL;
-   si->cfisi_size = si->cfisi_used = 0;
-   si->cfisi_minaddr = si->cfisi_maxaddr = 0;
-
-   si->stab_typetab = NULL;
-
-   si->plt_start  = si->plt_size  = 0;
-   si->got_start  = si->got_size  = 0;
-   si->data_start = si->data_size = 0;
-   si->bss_start  = si->bss_size  = 0;
-
-   /* And actually fill it up. */
-   if (!read_lib_symbols ( si ) && 0) {
-      /* XXX this interacts badly with the prevN optimization in
-         addStr().  Since this frees the si, the si pointer value can
-         be recycled, which confuses the curr_si == si test.  For now,
-         this code is disabled, and everything is included in the
-         segment list, even if it is a bad ELF file.  Ironically,
-         running this under valgrind itself hides the problem, because
-         it doesn't recycle pointers... */
-      // [Nb: the prevN optimization has now been removed from addStr().
-      //  However, when I try reactivating this path of the branch I get
-      //  seg faults...  --njn 13-Jun-2005]
+SegInfo *VG_(read_seg_symbols) ( Addr seg_addr, SizeT seg_len,
+                                 OffT seg_offset, const Char* seg_filename)
+{
+   SegInfo* si = alloc_SegInfo(seg_addr, seg_len, seg_offset, seg_filename);
+
+   VGP_PUSHCC(VgpReadSyms);
+
+   if (!read_lib_symbols ( si )) {
+      // Something went wrong (eg. bad ELF file).
       freeSegInfo( si );
+      si = NULL;
+
    } else {
       // Prepend si to segInfo_list
       si->next = segInfo_list;