From: Julian Seward Date: Tue, 20 Sep 2011 21:59:50 +0000 (+0000) Subject: A refactoring change; no functional effect. struct _DebugInfo X-Git-Tag: svn/VALGRIND_3_7_0~196 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=042bb40c53b1c5fb1af7e0eba713d72c8d529c91;p=thirdparty%2Fvalgrind.git A refactoring change; no functional effect. struct _DebugInfo contains a bunch of fields which are used as a very simple state machine that observes mmap calls and decides when to read debuginfo for the associated file. This change moves these fields into their own structure, struct _DebugInfoFSM, for cleanness, so as to make it clear they have a common purpose. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12041 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 3a4b621ac5..6a9c177b02 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -176,8 +176,8 @@ DebugInfo* alloc_DebugInfo( const UChar* filename ) vg_assert(filename); di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); - di->handle = handle_counter++; - di->filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); + di->handle = handle_counter++; + di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); /* Everything else -- pointers, sizes, arrays -- is zeroed by ML_(dinfo_zalloc). Now set up the debugging-output flags. */ @@ -204,11 +204,11 @@ static void free_DebugInfo ( DebugInfo* di ) GExpr* gexpr; vg_assert(di != NULL); - if (di->filename) ML_(dinfo_free)(di->filename); - if (di->loctab) ML_(dinfo_free)(di->loctab); - if (di->cfsi) ML_(dinfo_free)(di->cfsi); - if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); - if (di->fpo) ML_(dinfo_free)(di->fpo); + if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename); + if (di->loctab) ML_(dinfo_free)(di->loctab); + if (di->cfsi) ML_(dinfo_free)(di->cfsi); + if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); + if (di->fpo) ML_(dinfo_free)(di->fpo); if (di->symtab) { /* We have to visit all the entries so as to free up any @@ -307,7 +307,8 @@ static void discard_DebugInfo ( DebugInfo* di ) "Discarding syms at %#lx-%#lx in %s due to %s()\n", di->text_avma, di->text_avma + di->text_size, - curr->filename ? curr->filename : (UChar*)"???", + curr->fsm.filename ? curr->fsm.filename + : (UChar*)"???", reason); vg_assert(*prev_next_ptr == curr); *prev_next_ptr = curr->next; @@ -390,24 +391,24 @@ static Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) vg_assert(di1); vg_assert(di2); - if (di1->have_rx_map && di2->have_rx_map - && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, - di2->rx_map_avma, di2->rx_map_size)) + if (di1->fsm.have_rx_map && di2->fsm.have_rx_map + && ranges_overlap(di1->fsm.rx_map_avma, di1->fsm.rx_map_size, + di2->fsm.rx_map_avma, di2->fsm.rx_map_size)) return True; - if (di1->have_rx_map && di2->have_rw_map - && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, - di2->rw_map_avma, di2->rw_map_size)) + if (di1->fsm.have_rx_map && di2->fsm.have_rw_map + && ranges_overlap(di1->fsm.rx_map_avma, di1->fsm.rx_map_size, + di2->fsm.rw_map_avma, di2->fsm.rw_map_size)) return True; - if (di1->have_rw_map && di2->have_rx_map - && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, - di2->rx_map_avma, di2->rx_map_size)) + if (di1->fsm.have_rw_map && di2->fsm.have_rx_map + && ranges_overlap(di1->fsm.rw_map_avma, di1->fsm.rw_map_size, + di2->fsm.rx_map_avma, di2->fsm.rx_map_size)) return True; - if (di1->have_rw_map && di2->have_rw_map - && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, - di2->rw_map_avma, di2->rw_map_size)) + if (di1->fsm.have_rw_map && di2->fsm.have_rw_map + && ranges_overlap(di1->fsm.rw_map_avma, di1->fsm.rw_map_size, + di2->fsm.rw_map_avma, di2->fsm.rw_map_size)) return True; return False; @@ -467,8 +468,8 @@ static DebugInfo* find_or_create_DebugInfo_for ( UChar* filename ) DebugInfo* di; vg_assert(filename); for (di = debugInfo_list; di; di = di->next) { - vg_assert(di->filename); - if (0==VG_(strcmp)(di->filename, filename)) + vg_assert(di->fsm.filename); + if (0==VG_(strcmp)(di->fsm.filename, filename)) break; } if (!di) { @@ -492,31 +493,33 @@ static void check_CFSI_related_invariants ( DebugInfo* di ) /* This fn isn't called until after debuginfo for this object has been successfully read. And that shouldn't happen until we have both a r-x and rw- mapping for the object. Hence: */ - vg_assert(di->have_rx_map); - vg_assert(di->have_rw_map); + vg_assert(di->fsm.have_rx_map); + vg_assert(di->fsm.have_rw_map); /* degenerate case: r-x section is empty */ - if (di->rx_map_size == 0) { + if (di->fsm.rx_map_size == 0) { vg_assert(di->cfsi == NULL); return; } /* normal case: r-x section is nonempty */ /* invariant (0) */ - vg_assert(di->rx_map_size > 0); + vg_assert(di->fsm.rx_map_size > 0); /* invariant (1) */ for (di2 = debugInfo_list; di2; di2 = di2->next) { if (di2 == di) continue; - if (di2->rx_map_size == 0) + if (di2->fsm.rx_map_size == 0) continue; - vg_assert(di->rx_map_avma + di->rx_map_size <= di2->rx_map_avma - || di2->rx_map_avma + di2->rx_map_size <= di->rx_map_avma); + vg_assert( + di->fsm.rx_map_avma + di->fsm.rx_map_size <= di2->fsm.rx_map_avma + || di2->fsm.rx_map_avma + di2->fsm.rx_map_size <= di->fsm.rx_map_avma + ); } di2 = NULL; /* invariant (2) */ if (di->cfsi) { vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ - vg_assert(di->cfsi_minavma >= di->rx_map_avma); - vg_assert(di->cfsi_maxavma < di->rx_map_avma + di->rx_map_size); + vg_assert(di->cfsi_minavma >= di->fsm.rx_map_avma); + vg_assert(di->cfsi_maxavma < di->fsm.rx_map_avma + di->fsm.rx_map_size); } /* invariants (3) and (4) */ if (di->cfsi) { @@ -643,7 +646,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; if (!quiet && VG_(clo_verbosity) > 1) { VG_(memset)(&fake_di, 0, sizeof(fake_di)); - fake_di.filename = filename; + fake_di.fsm.filename = filename; ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); } return 0; @@ -737,7 +740,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) if (sr_Err(fd) != VKI_EACCES) { DebugInfo fake_di; VG_(memset)(&fake_di, 0, sizeof(fake_di)); - fake_di.filename = filename; + fake_di.fsm.filename = filename; ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header"); } return 0; @@ -750,7 +753,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) if (nread < 0) { DebugInfo fake_di; VG_(memset)(&fake_di, 0, sizeof(fake_di)); - fake_di.filename = filename; + fake_di.fsm.filename = filename; ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); return 0; } @@ -774,11 +777,11 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) if (is_rx_map) { /* We have a text-like mapping. Note the details. */ - if (!di->have_rx_map) { - di->have_rx_map = True; - di->rx_map_avma = a; - di->rx_map_size = seg->end + 1 - seg->start; - di->rx_map_foff = seg->offset; + if (!di->fsm.have_rx_map) { + di->fsm.have_rx_map = True; + di->fsm.rx_map_avma = a; + di->fsm.rx_map_size = seg->end + 1 - seg->start; + di->fsm.rx_map_foff = seg->offset; } else { /* FIXME: complain about a second text-like mapping */ } @@ -786,11 +789,11 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) if (is_rw_map) { /* We have a data-like mapping. Note the details. */ - if (!di->have_rw_map) { - di->have_rw_map = True; - di->rw_map_avma = a; - di->rw_map_size = seg->end + 1 - seg->start; - di->rw_map_foff = seg->offset; + if (!di->fsm.have_rw_map) { + di->fsm.have_rw_map = True; + di->fsm.rw_map_avma = a; + di->fsm.rw_map_size = seg->end + 1 - seg->start; + di->fsm.rw_map_foff = seg->offset; } else { /* FIXME: complain about a second data-like mapping */ } @@ -799,15 +802,15 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) /* If we don't have an rx and rw mapping, or if we already have debuginfo for this mapping for whatever reason, go no further. */ - if ( ! (di->have_rx_map && di->have_rw_map && !di->have_dinfo) ) + if ( ! (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) ) return 0; /* Ok, so, finally, let's try to read the debuginfo. */ - vg_assert(di->filename); + vg_assert(di->fsm.filename); TRACE_SYMTAB("\n"); TRACE_SYMTAB("------ start ELF OBJECT " "------------------------------\n"); - TRACE_SYMTAB("------ name = %s\n", di->filename); + TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); TRACE_SYMTAB("\n"); /* We're going to read symbols and debug info for the avma @@ -855,7 +858,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) } TRACE_SYMTAB("\n"); - TRACE_SYMTAB("------ name = %s\n", di->filename); + TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); TRACE_SYMTAB("------ end ELF OBJECT " "------------------------------\n"); TRACE_SYMTAB("\n"); @@ -1100,7 +1103,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, { DebugInfo* di = find_or_create_DebugInfo_for(exename); /* this di must be new, since we just nuked any old stuff in the range */ - vg_assert(di && !di->have_rx_map && !di->have_rw_map); + vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); vg_assert(!di->have_dinfo); /* don't set up any of the di-> fields; let @@ -1172,10 +1175,10 @@ static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, /* Consider any symbol in the r-x mapped area to be text. See Comment_Regarding_Text_Range_Checks in storage.c for details. */ - inRange = di->have_rx_map - && di->rx_map_size > 0 - && di->rx_map_avma <= ptr - && ptr < di->rx_map_avma + di->rx_map_size; + inRange = di->fsm.have_rx_map + && di->fsm.rx_map_size > 0 + && di->fsm.rx_map_avma <= ptr + && ptr < di->fsm.rx_map_avma + di->fsm.rx_map_size; } else { inRange = (di->data_present && di->data_size > 0 @@ -1467,7 +1470,7 @@ Bool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) && di->text_size > 0 && di->text_avma <= a && a < di->text_avma + di->text_size) { - VG_(strncpy_safely)(buf, di->filename, nbuf); + VG_(strncpy_safely)(buf, di->fsm.filename, nbuf); buf[nbuf-1] = 0; return True; } @@ -3602,7 +3605,7 @@ const UChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) const UChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) { - return di->filename; + return di->fsm.filename; } PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) @@ -3674,7 +3677,7 @@ VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, VG_(printf)( "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " "data=%#lx,%ld bss=%#lx,%ld\n", - a, di, di->filename, + a, di, di->fsm.filename, di->got_avma, di->got_size, di->plt_avma, di->plt_size, di->data_avma, di->data_size, @@ -3744,9 +3747,9 @@ VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, vg_assert(n_name >= 8); - if (di && di->filename) { + if (di && di->fsm.filename) { Int i, j; - Int fnlen = VG_(strlen)(di->filename); + Int fnlen = VG_(strlen)(di->fsm.filename); Int start_at = 1 + fnlen - n_name; if (start_at < 0) start_at = 0; vg_assert(start_at < fnlen); @@ -3754,8 +3757,8 @@ VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, while (True) { vg_assert(j >= 0 && j < n_name); vg_assert(i >= 0 && i <= fnlen); - name[j] = di->filename[i]; - if (di->filename[i] == 0) break; + name[j] = di->fsm.filename[i]; + if (di->fsm.filename[i] == 0) break; i++; j++; } vg_assert(i == fnlen); diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index 0cf8a72057..fa57d99ff7 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -394,14 +394,54 @@ ML_(cmp_for_DiAddrRange_range) ( const void* keyV, const void* elemV ); information pertaining to one mapped ELF object. This type is exported only abstractly - in pub_tool_debuginfo.h. */ +/* First though, here's an auxiliary data structure. It is only ever + used as part of a struct _DebugInfo. We use it to record + observations about mappings and permission changes to the + associated file, so as to decide when to read debug info. It's + essentially an ultra-trivial finite state machine which, when it + reaches an accept state, signals that we should now read debug info + from the object into the associated struct _DebugInfo. The accept + state is arrived at when have_rx_map and have_rw_map both become + true. + + This is all rather ad-hoc; for example it has no way to record more + than one rw or rx mapping for a given object, not because such + events have never been observed, but because we've never needed to + note more than the first one of any such in order when to decide to + read debug info. It may be that in future we need to track more + state in order to make the decision, so this struct would then get + expanded. +*/ +struct _DebugInfoFSM +{ + UChar* filename; /* in mallocville (VG_AR_DINFO) */ + + Bool have_rx_map; /* did we see a r?x mapping yet for the file? */ + Bool have_rw_map; /* did we see a rw? mapping yet for the file? */ + + Addr rx_map_avma; /* these fields record the file offset, length */ + SizeT rx_map_size; /* and map address of the r?x mapping we believe */ + OffT rx_map_foff; /* is the .text segment mapping */ + + Addr rw_map_avma; /* ditto, for the rw? mapping we believe is the */ + SizeT rw_map_size; /* .data segment mapping */ + OffT rw_map_foff; +}; + + +/* To do with the string table in struct _DebugInfo (::strchunks) */ #define SEGINFO_STRCHUNKSIZE (64*1024) + /* We may encounter more than one .eh_frame section in an object -- unusual but apparently allowed by ELF. See http://sourceware.org/bugzilla/show_bug.cgi?id=12675 */ #define N_EHFRAME_SECTS 2 + +/* So, the main structure for holding debug info for one object. */ + struct _DebugInfo { /* Admin stuff */ @@ -431,28 +471,20 @@ struct _DebugInfo { Bool ddump_line; /* mimic /usr/bin/readelf --debug-dump=line */ Bool ddump_frames; /* mimic /usr/bin/readelf --debug-dump=frames */ - /* Fields that must be filled in before we can start reading - anything from the ELF file. These fields are filled in by - VG_(di_notify_mmap) and its immediate helpers. */ - - UChar* filename; /* in mallocville (VG_AR_DINFO) */ - - Bool have_rx_map; /* did we see a r?x mapping yet for the file? */ - Bool have_rw_map; /* did we see a rw? mapping yet for the file? */ - - Addr rx_map_avma; /* these fields record the file offset, length */ - SizeT rx_map_size; /* and map address of the r?x mapping we believe */ - OffT rx_map_foff; /* is the .text segment mapping */ - - Addr rw_map_avma; /* ditto, for the rw? mapping we believe is the */ - SizeT rw_map_size; /* .data segment mapping */ - OffT rw_map_foff; - - /* Once both a rw? and r?x mapping for .filename have been - observed, we can go on to read the symbol tables and debug info. - .have_dinfo flags when that has happened. */ - /* If have_dinfo is False, then all fields except "*rx_map*" and - "*rw_map*" are invalid and should not be consulted. */ + /* The "decide when it is time to read debuginfo" state machine. + This structure must get filled in before we can start reading + anything from the ELF/MachO file. This structure is filled in + by VG_(di_notify_mmap) and its immediate helpers. */ + struct _DebugInfoFSM fsm; + + /* Once the ::fsm has reached an accept state -- typically, when + both a rw? and r?x mapping for .filename have been observed -- + we can go on to read the symbol tables and debug info. + .have_dinfo changes from False to True when the debug info has + been completely read in and postprocessed (canonicalised) and is + now suitable for querying. */ + /* If have_dinfo is False, then all fields below this point are + invalid and should not be consulted. */ Bool have_dinfo; /* initially False */ /* All the rest of the fields in this structure are filled in once diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 870d77ecbc..71a4e7b98d 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -3765,7 +3765,7 @@ void ML_(read_callframe_info_dwarf3) VG_(printf)("CFI info: szB %ld, _avma %#lx, _image %p\n", frame_size, frame_avma, frame_image ); VG_(printf)("CFI info: name %s\n", - di->filename ); + di->fsm.filename ); } /* Loop over CIEs/FDEs */ diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index da38af333a..08bb4f2343 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -532,9 +532,10 @@ Bool get_elf_symbol_info ( "Comment_Regarding_Text_Range_Checks" in storage.c for background. */ Bool in_rx; - vg_assert(di->have_rx_map); - in_rx = (!(*sym_avma_out + *sym_size_out <= di->rx_map_avma - || *sym_avma_out >= di->rx_map_avma + di->rx_map_size)); + vg_assert(di->fsm.have_rx_map); + in_rx = (!(*sym_avma_out + *sym_size_out <= di->fsm.rx_map_avma + || *sym_avma_out >= di->fsm.rx_map_avma + + di->fsm.rx_map_size)); if (in_text) vg_assert(in_rx); if (!in_rx) { @@ -548,7 +549,8 @@ Bool get_elf_symbol_info ( } else { if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) { TRACE_SYMTAB( - "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata / .bss / .sbss svma ranges\n", + "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata " + "/ .bss / .sbss svma ranges\n", *sym_avma_out, *sym_avma_out + *sym_size_out); return False; } @@ -876,7 +878,8 @@ Char *find_buildid(Addr image, UWord n_image) Word i; for (i = 0; i < ehdr->e_phnum; i++) { - ElfXX_Phdr* phdr = (ElfXX_Phdr*)(image + ehdr->e_phoff + i * ehdr->e_phentsize); + ElfXX_Phdr* phdr + = (ElfXX_Phdr*)(image + ehdr->e_phoff + i * ehdr->e_phentsize); if (phdr->p_type == PT_NOTE) { ElfXX_Off offset = phdr->p_offset; @@ -889,10 +892,12 @@ Char *find_buildid(Addr image, UWord n_image) if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 && note->n_type == NT_GNU_BUILD_ID) { - buildid = ML_(dinfo_zalloc)("di.fbi.1", note->n_descsz * 2 + 1); + buildid = ML_(dinfo_zalloc)("di.fbi.1", + note->n_descsz * 2 + 1); for (j = 0; j < note->n_descsz; j++) { - VG_(sprintf)(buildid + VG_(strlen)(buildid), "%02x", desc[j]); + VG_(sprintf)(buildid + VG_(strlen)(buildid), + "%02x", desc[j]); } } @@ -1018,7 +1023,8 @@ Addr open_debug_file( Char* name, Char* buildid, UInt crc, /*OUT*/UWord* size ) vg_assert(!sr_isError(res)); if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, - " .. build-id mismatch (found %s wanted %s)\n", debug_buildid, buildid); + " .. build-id mismatch (found %s wanted %s)\n", + debug_buildid, buildid); ML_(dinfo_free)(debug_buildid); return 0; } @@ -1211,12 +1217,12 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) Char* buildid = NULL; vg_assert(di); - vg_assert(di->have_rx_map == True); - vg_assert(di->have_rw_map == True); - vg_assert(di->rx_map_size > 0); - vg_assert(di->rw_map_size > 0); + vg_assert(di->fsm.have_rx_map == True); + vg_assert(di->fsm.have_rw_map == True); + vg_assert(di->fsm.rx_map_size > 0); + vg_assert(di->fsm.rw_map_size > 0); vg_assert(di->have_dinfo == False); - vg_assert(di->filename); + vg_assert(di->fsm.filename); vg_assert(!di->symtab); vg_assert(!di->loctab); vg_assert(!di->cfsi); @@ -1227,8 +1233,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* If these don't hold true, it means that m_syswrap/m_aspacemgr managed to do a mapping where the start isn't page aligned. Which sounds pretty bogus to me. */ - vg_assert(VG_IS_PAGE_ALIGNED(di->rx_map_avma)); - vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma)); + vg_assert(VG_IS_PAGE_ALIGNED(di->fsm.rx_map_avma)); + vg_assert(VG_IS_PAGE_ALIGNED(di->fsm.rw_map_avma)); /* ---------------------------------------------------------- At this point, there is very little information in the @@ -1247,13 +1253,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) oimage = (Addr)NULL; if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)) VG_(message)(Vg_DebugMsg, "Reading syms from %s (%#lx)\n", - di->filename, di->rx_map_avma ); + di->fsm.filename, di->fsm.rx_map_avma ); /* mmap the object image aboard, so that we can read symbols and line number info out of it. It will be munmapped immediately thereafter; it is only aboard transiently. */ - fd = VG_(open)(di->filename, VKI_O_RDONLY, 0); + fd = VG_(open)(di->fsm.filename, VKI_O_RDONLY, 0); if (sr_isError(fd)) { ML_(symerr)(di, True, "Can't open .so/.exe to read symbols?!"); return False; @@ -1274,7 +1280,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) VG_(close)(sr_Res(fd)); if (sr_isError(sres)) { - VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n", di->filename ); + VG_(message)(Vg_UserMsg, "warning: mmap failed on %s\n", + di->fsm.filename ); VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" ); return False; } @@ -1322,9 +1329,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) TRACE_SYMTAB("shdr: img %p nent %ld ent_szB %ld\n", shdr_img, shdr_nent, shdr_ent_szB); TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lu\n", - di->rx_map_avma, di->rx_map_size, di->rx_map_foff); + di->fsm.rx_map_avma, di->fsm.rx_map_size, di->fsm.rx_map_foff); TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lu\n", - di->rw_map_avma, di->rw_map_size, di->rw_map_foff); + di->fsm.rw_map_avma, di->fsm.rw_map_size, di->fsm.rw_map_foff); if (phdr_nent == 0 || !contained_within( @@ -1394,35 +1401,39 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) goto out; } prev_svma = phdr->p_vaddr; - if (phdr->p_offset >= di->rx_map_foff - && phdr->p_offset < di->rx_map_foff + di->rx_map_size - && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size + if (phdr->p_offset >= di->fsm.rx_map_foff + && phdr->p_offset < di->fsm.rx_map_foff + di->fsm.rx_map_size + && phdr->p_offset + phdr->p_filesz + <= di->fsm.rx_map_foff + di->fsm.rx_map_size && (phdr->p_flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_X)) { if (n_rx == N_RX_RW_AREAS) { ML_(symerr)(di, True, - "N_RX_RW_AREAS is too low; increase and recompile."); + "N_RX_RW_AREAS is too low; " + "increase and recompile."); goto out; } rx[n_rx].svma_base = phdr->p_vaddr; rx[n_rx].svma_limit = phdr->p_vaddr + phdr->p_memsz; - rx[n_rx].bias = di->rx_map_avma - di->rx_map_foff + rx[n_rx].bias = di->fsm.rx_map_avma - di->fsm.rx_map_foff + phdr->p_offset - phdr->p_vaddr; n_rx++; TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rx\n", i); } else - if (phdr->p_offset >= di->rw_map_foff - && phdr->p_offset < di->rw_map_foff + di->rw_map_size - && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size + if (phdr->p_offset >= di->fsm.rw_map_foff + && phdr->p_offset < di->fsm.rw_map_foff + di->fsm.rw_map_size + && phdr->p_offset + phdr->p_filesz + <= di->fsm.rw_map_foff + di->fsm.rw_map_size && (phdr->p_flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_W)) { if (n_rw == N_RX_RW_AREAS) { ML_(symerr)(di, True, - "N_RX_RW_AREAS is too low; increase and recompile."); + "N_RX_RW_AREAS is too low; " + "increase and recompile."); goto out; } rw[n_rw].svma_base = phdr->p_vaddr; rw[n_rw].svma_limit = phdr->p_vaddr + phdr->p_memsz; - rw[n_rw].bias = di->rw_map_avma - di->rw_map_foff + rw[n_rw].bias = di->fsm.rw_map_avma - di->fsm.rw_map_foff + phdr->p_offset - phdr->p_vaddr; n_rw++; TRACE_SYMTAB("PT_LOAD[%ld]: acquired as rw\n", i); @@ -1491,15 +1502,17 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) TRACE_SYMTAB("\n"); TRACE_SYMTAB("------ Examining the section headers ------\n"); TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n", - di->rx_map_avma, - di->rx_map_foff, di->rx_map_foff + di->rx_map_size - 1 ); + di->fsm.rx_map_avma, + di->fsm.rx_map_foff, + di->fsm.rx_map_foff + di->fsm.rx_map_size - 1 ); for (i = 0; i < n_rx; i++) { TRACE_SYMTAB("rx[%ld]: contains svmas %#lx .. %#lx with bias %#lx\n", i, rx[i].svma_base, rx[i].svma_limit - 1, rx[i].bias ); } TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n", - di->rw_map_avma, - di->rw_map_foff, di->rw_map_foff + di->rw_map_size - 1 ); + di->fsm.rw_map_avma, + di->fsm.rw_map_foff, + di->fsm.rw_map_foff + di->fsm.rw_map_size - 1 ); for (i = 0; i < n_rw; i++) { TRACE_SYMTAB("rw[%ld]: contains svmas %#lx .. %#lx with bias %#lx\n", i, rw[i].svma_base, rw[i].svma_limit - 1, rw[i].bias ); @@ -1724,8 +1737,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is " "mapped r-x only - ignoring .bss syms\n"); - VG_(message)(Vg_UserMsg, " %s\n", di->filename - ? di->filename + VG_(message)(Vg_UserMsg, " %s\n", di->fsm.filename + ? di->fsm.filename : (UChar*)"(null?!)" ); } } else @@ -2079,11 +2092,12 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) crc = *(UInt *)(debuglink_img + crc_offset); /* See if we can find a matching debug file */ - dimage = find_debug_file( di, di->filename, buildid, + dimage = find_debug_file( di, di->fsm.filename, buildid, debuglink_img, crc, &n_dimage ); } else { /* See if we can find a matching debug file */ - dimage = find_debug_file( di, di->filename, buildid, NULL, 0, &n_dimage ); + dimage = find_debug_file( di, di->fsm.filename, buildid, + NULL, 0, &n_dimage ); } ML_(dinfo_free)(buildid); @@ -2162,21 +2176,27 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) i, phdr_ent_szB ); if (phdr->p_type == PT_LOAD) { if (rx_dsvma_limit == 0 - && phdr->p_offset >= di->rx_map_foff - && phdr->p_offset < di->rx_map_foff + di->rx_map_size - && phdr->p_offset + phdr->p_filesz <= di->rx_map_foff + di->rx_map_size) { + && phdr->p_offset >= di->fsm.rx_map_foff + && phdr->p_offset + < di->fsm.rx_map_foff + di->fsm.rx_map_size + && phdr->p_offset + phdr->p_filesz + <= di->fsm.rx_map_foff + di->fsm.rx_map_size) { /* rx_dsvma_base = phdr->p_vaddr; */ /* UNUSED */ rx_dsvma_limit = phdr->p_vaddr + phdr->p_memsz; - rx_dbias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr; + rx_dbias = di->fsm.rx_map_avma - di->fsm.rx_map_foff + + phdr->p_offset - phdr->p_vaddr; } else if (rw_dsvma_limit == 0 - && phdr->p_offset >= di->rw_map_foff - && phdr->p_offset < di->rw_map_foff + di->rw_map_size - && phdr->p_offset + phdr->p_filesz <= di->rw_map_foff + di->rw_map_size) { + && phdr->p_offset >= di->fsm.rw_map_foff + && phdr->p_offset + < di->fsm.rw_map_foff + di->fsm.rw_map_size + && phdr->p_offset + phdr->p_filesz + <= di->fsm.rw_map_foff + di->fsm.rw_map_size) { /* rw_dsvma_base = phdr->p_vaddr; */ /* UNUSED */ rw_dsvma_limit = phdr->p_vaddr + phdr->p_memsz; - rw_dbias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr; + rw_dbias = di->fsm.rw_map_avma - di->fsm.rw_map_foff + + phdr->p_offset - phdr->p_vaddr; } } } @@ -2204,7 +2224,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) di->sec##_debug_bias \ = di->sec##_bias + \ di->sec##_svma - di->sec##_debug_svma; \ - TRACE_SYMTAB("acquiring ." #sec " debug svma = %#lx .. %#lx\n", \ + TRACE_SYMTAB("acquiring ." #sec \ + " debug svma = %#lx .. %#lx\n", \ di->sec##_debug_svma, \ di->sec##_debug_svma + di->sec##_size - 1); \ TRACE_SYMTAB("acquiring ." #sec " debug bias = %#lx\n", \ @@ -2402,7 +2423,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } } VG_(umsg)("VARINFO: %7lu vars %7ld text_size %s\n", - nVars, di->text_size, di->filename); + nVars, di->text_size, di->fsm.filename); } out: { diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index 71ad4b4e65..a7207504dc 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -86,8 +86,8 @@ doesn't make much sense. Here, we use text_bias as empirically producing the most ranges that fall inside the text segments for a multi-dll program. Of course, it could still be nonsense :-) */ -#define BIAS_FOR_SYMBOLS (di->rx_map_avma) -#define BIAS_FOR_LINETAB (di->rx_map_avma) +#define BIAS_FOR_SYMBOLS (di->fsm.rx_map_avma) +#define BIAS_FOR_LINETAB (di->fsm.rx_map_avma) #define BIAS_FOR_LINETAB2 (di->text_bias) #define BIAS_FOR_FPO (di->text_bias) /* Using di->text_bias for the FPOs causes 981 in range and 1 out of @@ -2259,7 +2259,7 @@ Bool ML_(read_pdb_debug_info)( + OFFSET_OF(IMAGE_NT_HEADERS, OptionalHeader) + ntheaders_avma->FileHeader.SizeOfOptionalHeader; - di->rx_map_avma = (Addr)obj_avma; + di->fsm.rx_map_avma = (Addr)obj_avma; /* Iterate over PE(?) headers. Try to establish the text_bias, that's all we really care about. */ @@ -2290,35 +2290,35 @@ Bool ML_(read_pdb_debug_info)( the real text section and valgrind will compute the wrong avma value and hence the wrong bias. */ if (!(pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { - di->have_rx_map = True; - if (di->rx_map_avma == 0) { - di->rx_map_avma = mapped_avma; + di->fsm.have_rx_map = True; + if (di->fsm.rx_map_avma == 0) { + di->fsm.rx_map_avma = mapped_avma; } - if (di->rx_map_size==0) { - di->rx_map_foff = pe_sechdr_avma->PointerToRawData; + if (di->fsm.rx_map_size==0) { + di->fsm.rx_map_foff = pe_sechdr_avma->PointerToRawData; } di->text_present = True; if (di->text_avma==0) { di->text_avma = mapped_avma; } di->text_size += pe_sechdr_avma->Misc.VirtualSize; - di->rx_map_size += pe_sechdr_avma->Misc.VirtualSize; + di->fsm.rx_map_size += pe_sechdr_avma->Misc.VirtualSize; } } else if (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { - di->have_rw_map = True; - if (di->rw_map_avma == 0) { - di->rw_map_avma = mapped_avma; + di->fsm.have_rw_map = True; + if (di->fsm.rw_map_avma == 0) { + di->fsm.rw_map_avma = mapped_avma; } - if (di->rw_map_size==0) { - di->rw_map_foff = pe_sechdr_avma->PointerToRawData; + if (di->fsm.rw_map_size==0) { + di->fsm.rw_map_foff = pe_sechdr_avma->PointerToRawData; } di->data_present = True; if (di->data_avma==0) { di->data_avma = mapped_avma; } - di->rw_map_size += pe_sechdr_avma->Misc.VirtualSize; + di->fsm.rw_map_size += pe_sechdr_avma->Misc.VirtualSize; di->data_size += pe_sechdr_avma->Misc.VirtualSize; } else if (pe_sechdr_avma->Characteristics @@ -2331,29 +2331,29 @@ Bool ML_(read_pdb_debug_info)( mapped_avma = VG_PGROUNDDN(mapped_avma); mapped_end_avma = VG_PGROUNDUP(mapped_end_avma); - /* Urr. These tests are bogus; ->rx_map_avma is not necessarily + /* Urr. These tests are bogus; ->fsm.rx_map_avma is not necessarily the start of the text section. */ if ((1 /*VG_(needs).data_syms*/ || (pe_sechdr_avma->Characteristics & IMAGE_SCN_CNT_CODE)) - && mapped_avma >= di->rx_map_avma - && mapped_avma <= (di->rx_map_avma+di->text_size) - && mapped_end_avma > (di->rx_map_avma+di->text_size)) { - UInt newsz = mapped_end_avma - di->rx_map_avma; + && mapped_avma >= di->fsm.rx_map_avma + && mapped_avma <= (di->fsm.rx_map_avma+di->text_size) + && mapped_end_avma > (di->fsm.rx_map_avma+di->text_size)) { + UInt newsz = mapped_end_avma - di->fsm.rx_map_avma; if (newsz > di->text_size) { /* extending the mapping is always needed for PE files under WINE */ di->text_size = newsz; - di->rx_map_size = newsz; + di->fsm.rx_map_size = newsz; } } } - if (di->have_rx_map && di->have_rw_map && !di->have_dinfo) { - vg_assert(di->filename); + if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { + vg_assert(di->fsm.filename); TRACE_SYMTAB("\n"); TRACE_SYMTAB("------ start PE OBJECT with PDB INFO " "---------------------\n"); - TRACE_SYMTAB("------ name = %s\n", di->filename); + TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); TRACE_SYMTAB("\n"); } @@ -2366,14 +2366,17 @@ Bool ML_(read_pdb_debug_info)( if (VG_(clo_verbosity) > 1) { VG_(message)(Vg_DebugMsg, "rx_map: avma %#lx size %7lu foff %llu\n", - di->rx_map_avma, di->rx_map_size, (Off64T)di->rx_map_foff); + di->fsm.rx_map_avma, di->fsm.rx_map_size, + (Off64T)di->fsm.rx_map_foff); VG_(message)(Vg_DebugMsg, "rw_map: avma %#lx size %7lu foff %llu\n", - di->rw_map_avma, di->rw_map_size, (Off64T)di->rw_map_foff); + di->fsm.rw_map_avma, di->fsm.rw_map_size, + (Off64T)di->fsm.rw_map_foff); VG_(message)(Vg_DebugMsg, " text: avma %#lx svma %#lx size %7lu bias %#lx\n", - di->text_avma, di->text_svma, di->text_size, di->text_bias); + di->text_avma, di->text_svma, + di->text_size, di->text_bias); } /* @@ -2429,7 +2432,7 @@ Bool ML_(read_pdb_debug_info)( } TRACE_SYMTAB("\n"); - TRACE_SYMTAB("------ name = %s\n", di->filename); + TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); TRACE_SYMTAB("------ end PE OBJECT with PDB INFO " "--------------------\n"); TRACE_SYMTAB("\n"); diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 4dbd3bb5fa..6142cb061a 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -74,7 +74,8 @@ void ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg ) or below, since that won't already have been shown */ VG_(message)(Vg_DebugMsg, "When reading debug info from %s:\n", - (di && di->filename) ? di->filename : (UChar*)"???"); + (di && di->fsm.filename) ? di->fsm.filename + : (UChar*)"???"); } VG_(message)(Vg_DebugMsg, "%s\n", msg); @@ -396,9 +397,9 @@ void ML_(addLineInfo) ( struct _DebugInfo* di, /* Rule out ones which are completely outside the r-x mapped area. See "Comment_Regarding_Text_Range_Checks" elsewhere in this file for background and rationale. */ - vg_assert(di->have_rx_map && di->have_rw_map); - if (next-1 < di->rx_map_avma - || this >= di->rx_map_avma + di->rx_map_size ) { + vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); + if (next-1 < di->fsm.rx_map_avma + || this >= di->fsm.rx_map_avma + di->fsm.rx_map_size ) { if (0) VG_(message)(Vg_DebugMsg, "warning: ignoring line info entry falling " @@ -467,17 +468,17 @@ void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi_orig ) would fall within a single procedure. */ vg_assert(cfsi.len < 5000000); - vg_assert(di->have_rx_map && di->have_rw_map); + vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); /* If we have an empty r-x mapping (is that possible?) then the DiCfSI can't possibly fall inside it. In which case skip. */ - if (di->rx_map_size == 0) + if (di->fsm.rx_map_size == 0) return; /* Rule out ones which are completely outside the r-x mapped area. See "Comment_Regarding_Text_Range_Checks" elsewhere in this file for background and rationale. */ - if (cfsi.base + cfsi.len - 1 < di->rx_map_avma - || cfsi.base >= di->rx_map_avma + di->rx_map_size) { + if (cfsi.base + cfsi.len - 1 < di->fsm.rx_map_avma + || cfsi.base >= di->fsm.rx_map_avma + di->fsm.rx_map_size) { static Int complaints = 10; if (VG_(clo_trace_cfi) || complaints > 0) { complaints--; @@ -505,25 +506,26 @@ void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi_orig ) will fail. See "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in priv_storage.h for background. */ - if (cfsi.base < di->rx_map_avma) { + if (cfsi.base < di->fsm.rx_map_avma) { /* Lower end is outside the mapped area. Hence upper end must be inside it. */ if (0) VG_(printf)("XXX truncate lower\n"); - vg_assert(cfsi.base + cfsi.len - 1 >= di->rx_map_avma); - delta = (SSizeT)(di->rx_map_avma - cfsi.base); + vg_assert(cfsi.base + cfsi.len - 1 >= di->fsm.rx_map_avma); + delta = (SSizeT)(di->fsm.rx_map_avma - cfsi.base); vg_assert(delta > 0); vg_assert(delta < (SSizeT)cfsi.len); cfsi.base += delta; cfsi.len -= delta; } else - if (cfsi.base + cfsi.len - 1 > di->rx_map_avma + di->rx_map_size - 1) { + if (cfsi.base + cfsi.len - 1 > di->fsm.rx_map_avma + + di->fsm.rx_map_size - 1) { /* Upper end is outside the mapped area. Hence lower end must be inside it. */ if (0) VG_(printf)("XXX truncate upper\n"); - vg_assert(cfsi.base <= di->rx_map_avma + di->rx_map_size - 1); + vg_assert(cfsi.base <= di->fsm.rx_map_avma + di->fsm.rx_map_size - 1); delta = (SSizeT)( (cfsi.base + cfsi.len - 1) - - (di->rx_map_avma + di->rx_map_size - 1) ); + - (di->fsm.rx_map_avma + di->fsm.rx_map_size - 1) ); vg_assert(delta > 0); vg_assert(delta < (SSizeT)cfsi.len); cfsi.len -= delta; } @@ -537,9 +539,9 @@ void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi_orig ) vg_assert(cfsi.len > 0); /* Similar logic applies for the next two assertions. */ - vg_assert(cfsi.base >= di->rx_map_avma); + vg_assert(cfsi.base >= di->fsm.rx_map_avma); vg_assert(cfsi.base + cfsi.len - 1 - <= di->rx_map_avma + di->rx_map_size - 1); + <= di->fsm.rx_map_avma + di->fsm.rx_map_size - 1); if (di->cfsi_used == di->cfsi_size) { new_sz = 2 * di->cfsi_size; @@ -927,10 +929,10 @@ void ML_(addVar)( struct _DebugInfo* di, /* This is assured us by top level steering logic in debuginfo.c, and it is re-checked at the start of ML_(read_elf_debug_info). */ - vg_assert(di->have_rx_map && di->have_rw_map); + vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); if (level > 0 - && (aMax < di->rx_map_avma - || aMin >= di->rx_map_avma + di->rx_map_size)) { + && (aMax < di->fsm.rx_map_avma + || aMin >= di->fsm.rx_map_avma + di->fsm.rx_map_size)) { if (VG_(clo_verbosity) >= 0) { VG_(message)(Vg_DebugMsg, "warning: addVar: in range %#lx .. %#lx outside " @@ -1858,7 +1860,7 @@ Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr ) Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr ) { - Addr const addr = ptr - di->rx_map_avma; + Addr const addr = ptr - di->fsm.rx_map_avma; Addr a_mid_lo, a_mid_hi; Word mid, size, lo = 0,