Author: sewardj Date: 2008-02-19 21:11:13 +0000 (Tue, 19 Feb 2008) New Revision: 7426
Log: Lots more tidying, and a bug fix. * rename VG_(seginfo_start), VG_(seginfo_size), VG_(seginfo_sym_offset) to VG_(seginfo_get_text_avma), VG_(seginfo_get_text_size), VG_(seginfo_get_text_bias). This gives them terminology consistent with the rest of m_debuginfo, and makes it clearer what they actually do :-) * tidy up and formalise hacks^H^H^H^H^Hcarefully designed techniques for figuring out where the .bss and .data sections got mapped. This involves ensuring that a DebugInfo can correctly distinguish between "a .text, .data, etc section which is mapped but of zero size, from one which is not mapped." * fix stupid typo causing incorrect identification of .debug_loc sections from debuginfo files * get rid of various commented out bits of code Modified: branches/DATASYMS/callgrind/bb.c branches/DATASYMS/callgrind/fn.c branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c branches/DATASYMS/coregrind/m_debuginfo/readelf.c branches/DATASYMS/coregrind/m_debuginfo/storage.c branches/DATASYMS/include/pub_tool_debuginfo.h Modified: branches/DATASYMS/callgrind/bb.c =================================================================== --- branches/DATASYMS/callgrind/bb.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/callgrind/bb.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -203,15 +203,17 @@ obj = CLG_(get_obj_node)( di ); /* Update symbol offset in object if remapped */ - offset = di ? VG_(seginfo_sym_offset)(di):0; + /* FIXME (or at least check this) 2008 Feb 19: 'offset' is + only correct for text symbols, not for data symbols */ + offset = di ? VG_(seginfo_get_text_bias)(di):0; if (obj->offset != offset) { - Addr start = di ? VG_(seginfo_start)(di) : 0; + Addr start = di ? VG_(seginfo_get_text_avma)(di) : 0; CLG_DEBUG(0, "Mapping changed for '%s': %p -> %p\n", obj->name, obj->start, start); /* Size should be the same, and offset diff == start diff */ - CLG_ASSERT( obj->size == (di ? VG_(seginfo_size)(di) : 0) ); + CLG_ASSERT( obj->size == (di ? VG_(seginfo_get_text_size)(di) : 0) ); CLG_ASSERT( obj->start - start == obj->offset - offset ); obj->offset = offset; obj->start = start; Modified: branches/DATASYMS/callgrind/fn.c =================================================================== --- branches/DATASYMS/callgrind/fn.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/callgrind/fn.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -194,9 +194,12 @@ } CLG_(stat).distinct_objs ++; new->number = CLG_(stat).distinct_objs; - new->start = di ? VG_(seginfo_start)(di) : 0; - new->size = di ? VG_(seginfo_size)(di) : 0; - new->offset = di ? VG_(seginfo_sym_offset)(di) : 0; + /* JRS 2008 Feb 19: maybe rename .start/.size/.offset to + .text_avma/.text_size/.test_bias to make it clearer what these + fields really mean */ + new->start = di ? VG_(seginfo_get_text_avma)(di) : 0; + new->size = di ? VG_(seginfo_get_text_size)(di) : 0; + new->offset = di ? VG_(seginfo_get_text_bias)(di) : 0; new->next = next; // not only used for debug output (see static.c) Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -314,7 +314,8 @@ while (True) { if (curr == NULL) break; - if (curr->text_size > 0 + if (curr->text_present + && curr->text_size > 0 && (start+length - 1 < curr->text_avma || curr->text_avma + curr->text_size - 1 < start)) { /* no overlap */ @@ -792,26 +793,27 @@ for (di = debugInfo_list; di != NULL; di = di->next) { if (findText) { - inRange = di->text_size > 0 + inRange = di->text_present + && di->text_size > 0 && di->text_avma <= ptr && ptr < di->text_avma + di->text_size; } else { - inRange = (di->data_size > 0 + inRange = (di->data_present + && di->data_size > 0 && di->data_avma <= ptr && ptr < di->data_avma + di->data_size) || - (di->sdata_size > 0 + (di->sdata_present + && di->sdata_size > 0 && di->sdata_avma <= ptr && ptr < di->sdata_avma + di->sdata_size) || - (di->bss_size > 0 + (di->bss_present + && di->bss_size > 0 && di->bss_avma <= ptr && ptr < di->bss_avma + di->bss_size); } - /* Note this short-circuit check relies on the assumption that - .bss is mapped immediately after .data. This is an assumption - that readelf.c makes anyway. */ if (!inRange) continue; sno = ML_(search_one_symtab) ( @@ -836,7 +838,8 @@ Int lno; DebugInfo* di; for (di = debugInfo_list; di != NULL; di = di->next) { - if (di->text_avma <= ptr + if (di->text_present + && di->text_avma <= ptr && ptr < di->text_avma + di->text_size) { lno = ML_(search_one_loctab) ( di, ptr ); if (lno == -1) goto not_found; @@ -1017,7 +1020,8 @@ DebugInfo* di; vg_assert(nbuf > 0); for (di = debugInfo_list; di != NULL; di = di->next) { - if (di->text_avma <= a + if (di->text_present + && di->text_avma <= a && a < di->text_avma + di->text_size) { VG_(strncpy_safely)(buf, di->filename, nbuf); if (di->memname) { @@ -1044,7 +1048,8 @@ { DebugInfo* di; for (di = debugInfo_list; di != NULL; di = di->next) { - if (di->text_avma <= a + if (di->text_present + && di->text_avma <= a && a < di->text_avma + di->text_size) { return di; } @@ -1785,7 +1790,7 @@ for (di = debugInfo_list; di; di = di->next) { n_steps++; /* text segment missing? unlikely, but handle it .. */ - if (di->text_size == 0) + if (!di->text_present || di->text_size == 0) continue; /* Ok. So does this text mapping bracket the ip? */ if (di->text_avma <= ip && ip < di->text_avma + di->text_size) @@ -1915,7 +1920,7 @@ XArray* vars; /* text segment missing? unlikely, but handle it .. */ - if (di->text_size == 0) + if (!di->text_present || di->text_size == 0) continue; /* any var info at all? */ if (!di->varinfo) @@ -2029,14 +2034,14 @@ return di->next; } -Addr VG_(seginfo_start)(const DebugInfo* di) +Addr VG_(seginfo_get_text_avma)(const DebugInfo* di) { - return di->text_avma; + return di->text_present ? di->text_avma : 0; } -SizeT VG_(seginfo_size)(const DebugInfo* di) +SizeT VG_(seginfo_get_text_size)(const DebugInfo* di) { - return di->text_size; + return di->text_present ? di->text_size : 0; } const UChar* VG_(seginfo_soname)(const DebugInfo* di) @@ -2049,9 +2054,9 @@ return di->filename; } -ULong VG_(seginfo_sym_offset)(const DebugInfo* di) +ULong VG_(seginfo_get_text_bias)(const DebugInfo* di) { - return di->text_bias; + return di->text_present ? di->text_bias : 0; } Int VG_(seginfo_syms_howmany) ( const DebugInfo *si ) @@ -2061,14 +2066,14 @@ void VG_(seginfo_syms_getidx) ( const DebugInfo *si, Int idx, - /*OUT*/Addr* addr, + /*OUT*/Addr* avma, /*OUT*/Addr* tocptr, /*OUT*/UInt* size, /*OUT*/HChar** name, /*OUT*/Bool* isText ) { vg_assert(idx >= 0 && idx < si->symtab_used); - if (addr) *addr = si->symtab[idx].addr; + if (avma) *avma = si->symtab[idx].addr; if (tocptr) *tocptr = si->symtab[idx].tocptr; if (size) *size = si->symtab[idx].size; if (name) *name = (HChar*)si->symtab[idx].name; @@ -2118,32 +2123,44 @@ di->data_avma, di->data_size, di->bss_avma, di->bss_size); - if (di->text_size > 0 + if (di->text_present + && di->text_size > 0 && a >= di->text_avma && a < di->text_avma + di->text_size) { res = Vg_SectText; break; } - if (di->data_size > 0 + if (di->data_present + && di->data_size > 0 && a >= di->data_avma && a < di->data_avma + di->data_size) { res = Vg_SectData; break; } - if (di->bss_size > 0 + if (di->sdata_present + && di->sdata_size > 0 + && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { + res = Vg_SectData; + break; + } + if (di->bss_present + && di->bss_size > 0 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { res = Vg_SectBSS; break; } - if (di->plt_size > 0 + if (di->plt_present + && di->plt_size > 0 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { res = Vg_SectPLT; break; } - if (di->got_size > 0 + if (di->got_present + && di->got_size > 0 && a >= di->got_avma && a < di->got_avma + di->got_size) { res = Vg_SectGOT; break; } - if (di->opd_size > 0 + if (di->opd_present + && di->opd_size > 0 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { res = Vg_SectOPD; break; Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-02-19 21:11:13 UTC (rev 7426) @@ -293,40 +293,50 @@ VG_AR_DINFO. */ UChar* soname; - /* Description of some important mapped sections. In each case if - the _size field is zero, the section isn't present. Certainly - text_ is mandatory on all platforms; not sure about the rest - though. */ + /* Description of some important mapped segments. The presence or + absence of the mapping is denoted by the _present field, since + in some obscure circumstances (to do with data/sdata/bss) it is + possible for the mapping to be present but have zero size. + Certainly text_ is mandatory on all platforms; not sure about + the rest though. */ /* .text */ + Bool text_present; Addr text_avma; Addr text_svma; SizeT text_size; OffT text_bias; /* .data */ + Bool data_present; Addr data_svma; Addr data_avma; SizeT data_size; OffT data_bias; /* .sdata */ + Bool sdata_present; Addr sdata_svma; Addr sdata_avma; SizeT sdata_size; OffT sdata_bias; /* .bss */ + Bool bss_present; Addr bss_svma; Addr bss_avma; SizeT bss_size; OffT bss_bias; /* .plt */ + Bool plt_present; Addr plt_avma; SizeT plt_size; /* .got */ + Bool got_present; Addr got_avma; SizeT got_size; - /* .opd -- needed on ppc64-linux */ + /* .opd -- needed on ppc64-linux for finding symbols */ + Bool opd_present; Addr opd_avma; SizeT opd_size; - /* .ehframe -- needed on amd64-linux */ + /* .ehframe -- needed on amd64-linux for stack unwinding */ + Bool ehframe_present; Addr ehframe_avma; SizeT ehframe_size; Modified: branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/coregrind/m_debuginfo/readdwarf3.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -109,21 +109,14 @@ /*------------------------------------------------------------*/ -/*--- The "new" DWARF3 reader -- enumerations and types ---*/ +/*--- The "new" DWARF3 reader ---*/ /*------------------------------------------------------------*/ #define TRACE_D3(format, args...) \ if (td3) { VG_(printf)(format, ## args); } - - -//////////////////////////////////////////////////////////////// - #define D3_INVALID_CUOFF ((void*)(-1UL)) #define D3_FAKEVOID_CUOFF ((void*)(-2UL)) -/*------------------------------------------------------------*/ -/*--- The "new" DWARF3 reader ---*/ -/*------------------------------------------------------------*/ typedef struct { @@ -541,6 +534,9 @@ "Overrun whilst reading .debug_loc section(2)" ); set_position_of_Cursor( &loc, debug_loc_offset ); + TRACE_D3("make_general_GX (.debug_loc_offset = %lu, img = %p) {\n", + debug_loc_offset, get_address_of_Cursor( &loc ) ); + /* Who frees this xa? It is freed before this fn exits. */ xa = VG_(newXA)( ML_(dinfo_zalloc), ML_(dinfo_free), sizeof(UChar) ); @@ -558,6 +554,7 @@ UWord w1 = get_UWord( &loc ); UWord w2 = get_UWord( &loc ); + TRACE_D3(" %08lx %08lx\n", w1, w2); if (w1 == 0 && w2 == 0) break; /* end of list */ @@ -571,8 +568,13 @@ /* else enumerate [w1+base, w2+base) */ /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" (sec 2.17.2) */ - if (w1 > w2) + if (w1 > w2) { + TRACE_D3("negative range is for .debug_loc expr at " + "file offset %lu\n", + debug_loc_offset); cc->barf( "negative range in .debug_loc section" ); + } + /* ignore zero length ranges */ acquire = w1 < w2; len = (UWord)get_UShort( &loc ); @@ -615,6 +617,9 @@ VG_(deleteXA)( xa ); gx->next = NULL; + + TRACE_D3("}\n"); + return gx; } @@ -1110,7 +1115,7 @@ /* cts, ctsSzB, ctsMemSzB are derived from a DW_AT_location and so refer either to a location expression or to a location list. Figure out which, and in both cases bundle the expression or - location list into a so-called GExpr (guarded expression. */ + location list into a so-called GExpr (guarded expression). */ __attribute__((noinline)) static GExpr* get_GX ( CUConst* cc, Bool td3, ULong cts, Int ctsSzB, UWord ctsMemSzB ) Modified: branches/DATASYMS/coregrind/m_debuginfo/readelf.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/readelf.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/coregrind/m_debuginfo/readelf.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -255,30 +255,35 @@ /* Try to figure out exactly which section the symbol is from and bias accordingly. Screws up if the previously deduced section svma address ranges are wrong. */ - if (di->text_size > 0 + if (di->text_present + && di->text_size > 0 && sym_svma >= di->text_svma && sym_svma < di->text_svma + di->text_size) { *is_text_out = True; *sym_avma_out += di->text_bias; } else - if (di->data_size > 0 + if (di->data_present + && di->data_size > 0 && sym_svma >= di->data_svma && sym_svma < di->data_svma + di->data_size) { *is_text_out = False; *sym_avma_out += di->data_bias; } else - if (di->sdata_size > 0 + if (di->sdata_present + && di->sdata_size > 0 && sym_svma >= di->sdata_svma && sym_svma < di->sdata_svma + di->sdata_size) { *is_text_out = False; *sym_avma_out += di->sdata_bias; } else - if (di->bss_size > 0 + if (di->bss_present + && di->bss_size > 0 && sym_svma >= di->bss_svma && sym_svma < di->bss_svma + di->bss_size) { *is_text_out = False; *sym_avma_out += di->bss_bias; } else { + /* Assume it's in .text. Is this a good idea? */ *is_text_out = True; *sym_avma_out += di->text_bias; } @@ -292,6 +297,7 @@ && *is_text_out && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE && sym->st_size > 0 + && di->opd_present && di->opd_size > 0 && *sym_avma_out >= di->opd_avma && *sym_avma_out < di->opd_avma + di->opd_size) @@ -321,13 +327,15 @@ /* If it's apparently in a GOT or PLT, it's really a reference to a symbol defined elsewhere, so ignore it. */ - if (di->got_size > 0 + if (di->got_present + && di->got_size > 0 && *sym_avma_out >= di->got_avma && *sym_avma_out < di->got_avma + di->got_size) { TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name); return False; } - if (di->plt_size > 0 + if (di->plt_present + && di->plt_size > 0 && *sym_avma_out >= di->plt_avma && *sym_avma_out < di->plt_avma + di->plt_size) { TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name); @@ -344,7 +352,8 @@ */ is_in_opd = False; - if (di->opd_size > 0 + if (di->opd_present + && di->opd_size > 0 && *sym_avma_out >= di->opd_avma && *sym_avma_out < di->opd_avma + di->opd_size) { # if !defined(VGP_ppc64_linux) @@ -424,22 +433,26 @@ ignore it. */ in_text - = di->text_size > 0 + = di->text_present + && di->text_size > 0 && !(*sym_avma_out + *sym_size_out <= di->text_avma || *sym_avma_out >= di->text_avma + di->text_size); in_data - = di->data_size > 0 + = di->data_present + && di->data_size > 0 && !(*sym_avma_out + *sym_size_out <= di->data_avma || *sym_avma_out >= di->data_avma + di->data_size); in_sdata - = di->sdata_size > 0 + = di->sdata_present + && di->sdata_size > 0 && !(*sym_avma_out + *sym_size_out <= di->sdata_avma || *sym_avma_out >= di->sdata_avma + di->sdata_size); in_bss - = di->bss_size > 0 + = di->bss_present + && di->bss_size > 0 && !(*sym_avma_out + *sym_size_out <= di->bss_avma || *sym_avma_out >= di->bss_avma + di->bss_size); @@ -467,7 +480,7 @@ section. This would completely mess up function redirection and intercepting. This assert ensures that any symbols that make it into the symbol table on ppc64-linux don't point into .opd. */ - if (di->opd_size > 0) { + if (di->opd_present && di->opd_size > 0) { vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma || *sym_avma_out >= di->opd_avma + di->opd_size); } @@ -827,7 +840,7 @@ * not match the value from the main object file. */ static -Addr open_debug_file( Char* name, UInt crc, UWord* size ) +Addr open_debug_file( Char* name, UInt crc, /*OUT*/UWord* size ) { SysRes fd, sres; struct vki_stat stat_buf; @@ -843,7 +856,7 @@ } if (VG_(clo_verbosity) > 1) - VG_(message)(Vg_DebugMsg, "Reading debug info from %s...", name); + VG_(message)(Vg_DebugMsg, "Reading debug info from %s ..", name); *size = stat_buf.st_size; @@ -861,7 +874,7 @@ vg_assert(!res.isError); if (VG_(clo_verbosity) > 1) VG_(message)(Vg_DebugMsg, - "... CRC mismatch (computed %08x wanted %08x)", calccrc, crc); + ".. CRC mismatch (computed %08x wanted %08x)", calccrc, crc); return 0; } @@ -872,7 +885,9 @@ * Try to find a separate debug file for a given object file. */ static -Addr find_debug_file( Char* objpath, Char* debugname, UInt crc, UWord* size ) +Addr find_debug_file( struct _DebugInfo* di, + Char* objpath, Char* debugname, + UInt crc, /*OUT*/UWord* size ) { Char *objdir = ML_(dinfo_strdup)(objpath); Char *objdirptr; @@ -883,7 +898,7 @@ *objdirptr = '\0'; debugpath = ML_(dinfo_zalloc)( - VG_(strlen)(objdir) + VG_(strlen)(debugname) + 16); + VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32); VG_(sprintf)(debugpath, "%s/%s", objdir, debugname); @@ -895,6 +910,11 @@ } } + if (addr) { + TRACE_SYMTAB("\n"); + TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath); + } + ML_(dinfo_free)(debugpath); ML_(dinfo_free)(objdir); @@ -1002,6 +1022,8 @@ 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->have_dinfo == False); vg_assert(di->filename); vg_assert(!di->memname); @@ -1019,15 +1041,15 @@ vg_assert(VG_IS_PAGE_ALIGNED(di->rw_map_avma)); /* ---------------------------------------------------------- - Phase 1. At this point, there is very little information in - the DebugInfo. We only know that something that looks like an - ELF file has been mapped rx-ishly as recorded with the - di->*rx_map* fields and has also been mapped rw-ishly as - recorded with the di->*rw_map* fields. In this phase we - examine the file's ELF Program Header, and, by comparing that - against the di->*r{w,x}_map* info, try to figure out the AVMAs - for the sections we care about, that should have been mapped: - text, data, got, plt, and toc. + At this point, there is very little information in the + DebugInfo. We only know that something that looks like an ELF + file has been mapped rx-ishly as recorded with the di->*rx_map* + fields and has also been mapped rw-ishly as recorded with the + di->*rw_map* fields. First we examine the file's ELF Program + Header, and, by comparing that against the di->*r{w,x}_map* + info, try to figure out the AVMAs for the sections we care + about, that should have been mapped: text, data, sdata, bss got, + plt, and toc. ---------------------------------------------------------- */ oimage = (Addr)NULL; @@ -1201,57 +1223,9 @@ di->soname = ML_(dinfo_strdup)(strtab+stroff); } } + } /* for (i = 0; i < phdr_nent; i++) ... */ + } /* look for the soname */ -//zz if (o_phdr->p_type != PT_LOAD) -//zz continue; -//zz -//zz if (!offset_set) { -//zz offset_set = True; -//zz offset_oimage = si->text_start_avma - o_phdr->p_vaddr; -//zz baseaddr = o_phdr->p_vaddr; -//zz } -//zz -//zz // Get the data and bss start/size if appropriate -//zz mapped = o_phdr->p_vaddr + offset_oimage; -//zz mapped_end = mapped + o_phdr->p_memsz; -//zz if (si->data_start_avma == 0 && -//zz (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) { -//zz si->data_start_avma = mapped; -//zz si->data_size = o_phdr->p_filesz; -//zz si->bss_start_avma = mapped + o_phdr->p_filesz; -//zz if (o_phdr->p_memsz > o_phdr->p_filesz) -//zz si->bss_size = o_phdr->p_memsz - o_phdr->p_filesz; -//zz else -//zz si->bss_size = 0; -//zz } -//zz -//zz mapped = mapped & ~(VKI_PAGE_SIZE-1); -//zz mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1); -//zz -//zz if (VG_(needs).data_syms -//zz && mapped >= si->text_start_avma -//zz && mapped <= (si->text_start_avma + si->text_size) -//zz && mapped_end > (si->text_start_avma + si->text_size)) { -//zz /* XXX jrs 2007 Jan 11: what's going on here? If data -//zz syms are involved, surely we shouldn't be messing with -//zz the segment's text_size unless there is an assumption -//zz that the data segment has been mapped immediately after -//zz the text segment. Which doesn't sound good to me. */ -//zz UInt newsz = mapped_end - si->text_start_avma; -//zz if (newsz > si->text_size) { -//zz if (0) -//zz VG_(printf)("extending mapping %p..%p %d -> ..%p %d\n", -//zz si->text_start_avma, -//zz si->text_start_avma + si->text_size, -//zz si->text_size, -//zz si->text_start_avma + newsz, newsz); -//zz -//zz si->text_size = newsz; -//zz } -//zz } - } - } - /* If, after looking at all the program headers, we still didn't find a soname, add a fake one. */ if (di->soname == NULL) { @@ -1285,10 +1259,10 @@ UWord size = shdr->sh_size; UInt alyn = shdr->sh_addralign; Bool bits = !(shdr->sh_type == SHT_NOBITS); - Bool inrx = size > 0 && foff >= di->rx_map_foff - && foff < di->rx_map_foff + di->rx_map_size; - Bool inrw = size > 0 && foff >= di->rw_map_foff - && foff < di->rw_map_foff + di->rw_map_size; + Bool inrx = foff >= di->rx_map_foff + && foff < di->rx_map_foff + di->rx_map_size; + Bool inrw = foff >= di->rw_map_foff + && foff < di->rw_map_foff + di->rw_map_size; TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld " " svma %p name \"%s\"\n", @@ -1316,11 +1290,13 @@ goto out; \ } while (0) - /* Find avma-s for: .text .data .bss .plt .got .opd .eh_frame */ + /* Find avma-s for: .text .data .sdata .bss .plt .got .opd + and .eh_frame */ /* Accept .text where mapped as rx (code) */ if (0 == VG_(strcmp)(name, ".text")) { - if (inrx && size > 0 && di->text_size == 0) { + if (inrx && size > 0 && !di->text_present) { + di->text_present = True; di->text_svma = svma; di->text_avma = di->rx_map_avma + foff - di->rx_map_foff; di->text_size = size; @@ -1337,10 +1313,12 @@ } } - /* Accept .data where mapped as rw (data) */ + /* Accept .data where mapped as rw (data), even if zero-sized */ if (0 == VG_(strcmp)(name, ".data")) { - if (inrw && size > 0 && di->data_size == 0) { -if (alyn > data_align) data_align = alyn; + if (inrw && size >= 0 && !di->data_present) { + if (alyn > data_align) + data_align = alyn; + di->data_present = True; di->data_svma = svma; di->data_avma = di->rw_map_avma + foff - di->rw_map_foff; di->data_size = size; @@ -1359,8 +1337,10 @@ /* Accept .sdata where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".sdata")) { - if (inrw && size > 0 && di->sdata_size == 0) { -if (alyn > data_align) data_align = alyn; + if (inrw && size > 0 && !di->sdata_present) { + if (alyn > data_align) + data_align = alyn; + di->sdata_present = True; di->sdata_svma = svma; di->sdata_avma = di->rw_map_avma + foff - di->rw_map_foff; di->sdata_size = size; @@ -1377,12 +1357,15 @@ } } - /* Accept .bss where mapped as rw (data) */ + /* Accept .bss where mapped as rw (data), even if zero-sized */ if (0 == VG_(strcmp)(name, ".bss")) { - if (inrw && size > 0 && di->bss_size == 0) { -bss_totsize += round_Addr_upwards(size, alyn); -if (svma < gen_bss_lowest_svma) gen_bss_lowest_svma = svma; -TRACE_SYMTAB("increasing total bss-like size to %ld\n", bss_totsize); + if (inrw && size >= 0 && !di->bss_present) { + bss_totsize += round_Addr_upwards(size, alyn); + if (svma < gen_bss_lowest_svma) + gen_bss_lowest_svma = svma; + TRACE_SYMTAB("increasing total bss-like size to %ld\n", + bss_totsize); + di->bss_present = True; di->bss_svma = svma; di->bss_avma = di->rw_map_avma + foff - di->rw_map_foff; di->bss_size = size; @@ -1396,8 +1379,9 @@ di->bss_avma + di->bss_size - 1); TRACE_SYMTAB("acquiring .bss bias = %p\n", di->bss_bias); } else - if ((!inrw) && (!inrx) && size > 0 && di->bss_size == 0) { + if ((!inrw) && (!inrx) && size > 0 && !di->bss_present) { /* File contains a .bss, but it didn't get mapped. Ignore. */ + di->bss_present = False; di->bss_svma = 0; di->bss_avma = 0; di->bss_size = 0; @@ -1411,9 +1395,11 @@ /* Accept .sbss where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".sbss")) { if (inrw && size > 0 && sbss_size == 0) { -bss_totsize += round_Addr_upwards(size, alyn); -if (svma < gen_bss_lowest_svma) gen_bss_lowest_svma = svma; -TRACE_SYMTAB("increasing total bss-like size to %ld\n", bss_totsize); + bss_totsize += round_Addr_upwards(size, alyn); + if (svma < gen_bss_lowest_svma) + gen_bss_lowest_svma = svma; + TRACE_SYMTAB("increasing total bss-like size to %ld\n", + bss_totsize); sbss_size = size; sbss_svma = svma; sbss_align = alyn; @@ -1422,12 +1408,14 @@ } } - /* Accept .sbss where mapped as rw (data) */ + /* Accept .dynbss where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".dynbss")) { if (inrw && size > 0 /* && sbss_size == 0*/) { -bss_totsize += round_Addr_upwards(size, alyn); -if (svma < gen_bss_lowest_svma) gen_bss_lowest_svma = svma; -TRACE_SYMTAB("increasing total bss-like size to %ld\n", bss_totsize); + bss_totsize += round_Addr_upwards(size, alyn); + if (svma < gen_bss_lowest_svma) + gen_bss_lowest_svma = svma; + TRACE_SYMTAB("increasing total bss-like size to %ld\n", + bss_totsize); } else { BAD(".dynbss"); } @@ -1435,7 +1423,8 @@ /* Accept .got where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".got")) { - if (inrw && size > 0 && di->got_size == 0) { + if (inrw && size > 0 && !di->got_present) { + di->got_present = True; di->got_avma = di->rw_map_avma + foff - di->rw_map_foff; di->got_size = size; TRACE_SYMTAB("acquiring .got avma = %p\n", di->got_avma); @@ -1448,7 +1437,8 @@ # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) /* Accept .plt where mapped as rx (code) */ if (0 == VG_(strcmp)(name, ".plt")) { - if (inrx && size > 0 && di->plt_size == 0) { + if (inrx && size > 0 && !di->plt_present) { + di->plt_present = True; di->plt_avma = di->rx_map_avma + foff - di->rx_map_foff; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %p\n", di->plt_avma); @@ -1459,7 +1449,8 @@ # elif defined(VGP_ppc32_linux) /* Accept .plt where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".plt")) { - if (inrw && size > 0 && di->plt_size == 0) { + if (inrw && size > 0 && !di->plt_present) { + di->plt_present = True; di->plt_avma = di->rw_map_avma + foff - di->rw_map_foff; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %p\n", di->plt_avma); @@ -1470,15 +1461,17 @@ # elif defined(VGP_ppc64_linux) /* Accept .plt where mapped as rw (data), or unmapped */ if (0 == VG_(strcmp)(name, ".plt")) { - if (inrw && size > 0 && di->plt_size == 0) { + if (inrw && size > 0 && !di->plt_present) { + di->plt_present = True; di->plt_avma = di->rw_map_avma + foff - di->rw_map_foff; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %p\n", di->plt_avma); } else - if ((!inrw) && (!inrx) && size > 0 && di->plt_size == 0) { + if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) { /* File contains a .plt, but it didn't get mapped. Presumably it is not required on this platform. At least don't reject the situation as invalid. */ + di->plt_present = True; di->plt_avma = 0; di->plt_size = 0; } else { @@ -1491,7 +1484,8 @@ /* Accept .opd where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".opd")) { - if (inrw && size > 0 && di->opd_size == 0) { + if (inrw && size > 0 && !di->opd_present) { + di->opd_present = True; di->opd_avma = di->rw_map_avma + foff - di->rw_map_foff; di->opd_size = size; TRACE_SYMTAB("acquiring .opd avma = %p\n", di->opd_avma); @@ -1502,7 +1496,8 @@ /* Accept .eh_frame where mapped as rx (code) (?!) */ if (0 == VG_(strcmp)(name, ".eh_frame")) { - if (inrx && size > 0 && di->ehframe_size == 0) { + if (inrx && size > 0 && !di->ehframe_present) { + di->ehframe_present = True; di->ehframe_avma = di->rx_map_avma + foff - di->rx_map_foff; di->ehframe_size = size; TRACE_SYMTAB("acquiring .eh_frame avma = %p\n", di->ehframe_avma); @@ -1515,57 +1510,6 @@ } -#if 0 - /* We found a .sbss section too. If if immediately adjoins the - .bss, pretend it's a part of .bss. This is a hack. Fortunately - .sbss (small-items .bss section) seems to exist on - ppc32/64-linux, so if this screws up it at least won't affect - the main x86/amd64-linux ports. */ - if (di->bss_size > 0 && sbss_size > 0) { - - if (round_Addr_upwards(sbss_svma + sbss_size, bss_align) - == di->bss_svma) { - /* Immediately precedes .bss */ - di->bss_size += (di->bss_svma - sbss_svma); - di->bss_bias += (di->bss_svma - sbss_svma); - di->bss_svma -= (di->bss_svma - sbss_svma); - /* but don't mess with .bss avma or bias */ - TRACE_SYMTAB("found .sbss of size %ld immediately preceding .bss\n", - sbss_size); - TRACE_SYMTAB("revised .bss svma = %p .. %p\n", - di->bss_svma, di->bss_svma + di->bss_size - 1); - TRACE_SYMTAB("revised .bss avma = %p .. %p\n", - di->bss_avma, di->bss_avma + di->bss_size - 1); - TRACE_SYMTAB("revised .bss bias = %p\n", di->bss_bias); - } - else - if (round_Addr_upwards(di->bss_svma + di->bss_size, sbss_align) - == sbss_svma) { - /* Immediately follows .bss */ - di->bss_size += (sbss_svma - di->bss_svma); - /* but don't mess with .bss avma or bias */ - TRACE_SYMTAB("found .sbss of size %ld immediately following .bss\n", - sbss_size); - TRACE_SYMTAB("revised .bss svma = %p .. %p\n", - di->bss_svma, di->bss_svma + di->bss_size - 1); - TRACE_SYMTAB("revised .bss avma = %p .. %p\n", - di->bss_avma, di->bss_avma + di->bss_size - 1); - TRACE_SYMTAB("revised .bss bias = %p\n", di->bss_bias); - } - else { - /* Can't ascertain relative position. Complain and - ignore. */ - TRACE_SYMTAB("found .sbss of size %ld but not immediately " - "preceding/following .bss\n", - sbss_size); - TRACE_SYMTAB("therefore ignoring it\n"); - ML_(symerr)(di, True, ".sbss which is not adjacent to .bss"); - } - - } -#endif - -#if 1 /* Kludge: ignore all previous computations for .bss avma range, and simply assume that .bss immediately follows .data/.sdata.*/ if (1) { @@ -1573,7 +1517,6 @@ - di->data_avma; TRACE_SYMTAB("data_al = %ld\n", data_al); bss_totsize += data_al; - di->bss_svma = gen_bss_lowest_svma; di->bss_size = bss_totsize; di->bss_avma = di->data_avma + (di->bss_svma - di->data_svma); @@ -1584,7 +1527,6 @@ di->bss_avma, di->bss_avma + di->bss_size - 1); TRACE_SYMTAB("kludged .bss bias = %p\n", di->bss_bias); } -#endif if (0) VG_(printf)("YYYY text_: avma %p size %ld bias %p\n", di->text_avma, di->text_size, di->text_bias); @@ -1714,7 +1656,8 @@ crc = *(UInt *)(debuglink_img + crc_offset); /* See if we can find a matching debug file */ - dimage = find_debug_file(di->filename, debuglink_img, crc, &n_dimage); + dimage = find_debug_file( di, di->filename, debuglink_img, + crc, &n_dimage ); if (dimage != 0 && n_dimage >= sizeof(ElfXX_Ehdr) @@ -1834,7 +1777,7 @@ FIND(need_dwarf2, ".debug_str", debug_str_sz, debug_str_img) FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz, debug_ranges_img) - FIND(need_dwarf2, ".debug_str", debug_loc_sz, debug_loc_img) + FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img) FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img) FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img) Modified: branches/DATASYMS/coregrind/m_debuginfo/storage.c =================================================================== --- branches/DATASYMS/coregrind/m_debuginfo/storage.c 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/coregrind/m_debuginfo/storage.c 2008-02-19 21:11:13 UTC (rev 7426) @@ -305,7 +305,9 @@ /* vg_assert(this < di->text_avma + di->size && next-1 >= di->text_avma); */ - if (this >= di->text_avma + di->text_size || next-1 < di->text_avma) { + if (!di->text_present + || this >= di->text_avma + di->text_size + || next-1 < di->text_avma) { if (0) VG_(message)(Vg_DebugMsg, "warning: ignoring line info entry falling " @@ -371,7 +373,8 @@ /* Rule out ones which are completely outside the text segment. These probably indicate some kind of bug, but for the meantime ignore them. */ - if ( cfsi->base + cfsi->len - 1 < di->text_avma + if ( !di->text_present + || cfsi->base + cfsi->len - 1 < di->text_avma || di->text_avma + di->text_size - 1 < cfsi->base ) { static Int complaints = 3; if (VG_(clo_trace_cfi) || complaints > 0) { @@ -711,7 +714,8 @@ /* Ignore any variables whose aMin .. aMax (that is, range of text addresses for which they actually exist) falls outside the text segment. Is this indicative of a bug in the reader? Maybe. */ - if (di->text_size > 0 + if (di->text_present + && di->text_size > 0 && level > 0 && (aMax < di->text_avma || aMin >= di->text_avma + di->text_size)) { @@ -971,12 +975,12 @@ vg_assert(0); out: if (preferA && !preferB) { - TRACE_SYMTAB("sym at %p: prefer '%s' over '%s'\n", + TRACE_SYMTAB("sym at %p: prefer '%s' to '%s'\n", a->addr, a->name, b->name ); return a; } if (preferB && !preferA) { - TRACE_SYMTAB("sym at %p: prefer '%s' over '%s'\n", + TRACE_SYMTAB("sym at %p: prefer '%s' to '%s'\n", b->addr, b->name, a->name ); return b; } @@ -1019,7 +1023,7 @@ di->symtab[di->symtab_used++] = di->symtab[i]; } } - TRACE_SYMTAB( "%d merged\n", n_merged); + TRACE_SYMTAB( "canonicaliseSymtab: %d symbols merged\n", n_merged); } while (n_merged > 0); Modified: branches/DATASYMS/include/pub_tool_debuginfo.h =================================================================== --- branches/DATASYMS/include/pub_tool_debuginfo.h 2008-02-19 12:51:29 UTC (rev 7425) +++ branches/DATASYMS/include/pub_tool_debuginfo.h 2008-02-19 21:11:13 UTC (rev 7426) @@ -112,16 +112,16 @@ /* A way to get information about what segments are mapped */ typedef struct _DebugInfo DebugInfo; -/* Returns NULL if the DebugInfo isn't found. It doesn't matter if debug info - is present or not. */ +/* Returns NULL if the DebugInfo isn't found. It doesn't matter if + debug info is present or not. */ extern DebugInfo* VG_(find_seginfo) ( Addr a ); /* Fish bits out of DebugInfos. */ -extern Addr VG_(seginfo_start) ( const DebugInfo *di ); -extern SizeT VG_(seginfo_size) ( const DebugInfo *di ); -extern const UChar* VG_(seginfo_soname) ( const DebugInfo *di ); -extern const UChar* VG_(seginfo_filename) ( const DebugInfo *di ); -extern ULong VG_(seginfo_sym_offset)( const DebugInfo *di ); +extern Addr VG_(seginfo_get_text_avma)( const DebugInfo *di ); +extern SizeT VG_(seginfo_get_text_size)( const DebugInfo *di ); +extern const UChar* VG_(seginfo_soname) ( const DebugInfo *di ); +extern const UChar* VG_(seginfo_filename) ( const DebugInfo *di ); +extern ULong VG_(seginfo_get_text_bias)( const DebugInfo *di ); /* Function for traversing the seginfo list. When called with NULL it returns the first element; otherwise it returns the given element's @@ -135,7 +135,7 @@ extern Int VG_(seginfo_syms_howmany) ( const DebugInfo *di ); extern void VG_(seginfo_syms_getidx) ( const DebugInfo *di, Int idx, - /*OUT*/Addr* addr, + /*OUT*/Addr* avma, /*OUT*/Addr* tocptr, /*OUT*/UInt* size, /*OUT*/HChar** name, ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Valgrind-developers mailing list Valgrind-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-developers