From 971c52d48c08fb06d37218f115dba4d882947944 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Mon, 26 Jan 2009 13:02:16 +0000 Subject: [PATCH] Merge from the trunk, a bunch of changes to fix ELF segment mapping and bias computation problems: 9020 Improve detection of where ELF sections have been mapped 9021 Don't assume that all global variables are in the data section 9022 Removed unused round_Addr_upwards function. 9024 Handle the rodata and sbss sections 9025 Accept zero size text segments. 9026 Don't worry about an unmapped, zero sized, bss segment. 9053 Fix aix5 build breakage following r9021. git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_4_BRANCH@9067 --- coregrind/m_debuginfo/d3basics.c | 76 +++++++-- coregrind/m_debuginfo/debuginfo.c | 26 +-- coregrind/m_debuginfo/priv_d3basics.h | 6 +- coregrind/m_debuginfo/priv_storage.h | 12 ++ coregrind/m_debuginfo/readdwarf.c | 1 + coregrind/m_debuginfo/readdwarf3.c | 1 + coregrind/m_debuginfo/readelf.c | 219 ++++++++++++++------------ coregrind/m_debuginfo/readxcoff.c | 1 + coregrind/m_debuginfo/storage.c | 1 + coregrind/m_debuginfo/tytypes.c | 1 + 10 files changed, 212 insertions(+), 132 deletions(-) diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 7f932910e3..64f6027644 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -35,6 +35,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" #include "pub_core_options.h" @@ -45,6 +46,7 @@ #include "priv_misc.h" #include "priv_d3basics.h" /* self */ +#include "priv_storage.h" HChar* ML_(pp_DW_children) ( DW_children hashch ) { @@ -372,7 +374,6 @@ static Long read_leb128S( UChar **data ) return (Long)val; } - /* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree and {FP,SP}_REG decls */ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs ) @@ -400,12 +401,52 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs ) return False; } +/* Convert a stated address to an actual address */ +static Bool bias_address( Addr* a, const DebugInfo* di ) +{ + if (di->text_present + && di->text_size > 0 + && *a >= di->text_svma && *a < di->text_svma + di->text_size) { + *a += di->text_bias; + } + else if (di->data_present + && di->data_size > 0 + && *a >= di->data_svma && *a < di->data_svma + di->data_size) { + *a += di->data_bias; + } + else if (di->sdata_present + && di->sdata_size > 0 + && *a >= di->sdata_svma && *a < di->sdata_svma + di->sdata_size) { + *a += di->sdata_bias; + } + else if (di->rodata_present + && di->rodata_size > 0 + && *a >= di->rodata_svma && *a < di->rodata_svma + di->rodata_size) { + *a += di->rodata_bias; + } + else if (di->bss_present + && di->bss_size > 0 + && *a >= di->bss_svma && *a < di->bss_svma + di->bss_size) { + *a += di->bss_bias; + } + else if (di->sbss_present + && di->sbss_size > 0 + && *a >= di->sbss_svma && *a < di->sbss_svma + di->sbss_size) { + *a += di->sbss_bias; + } + else { + return False; + } + + return True; +} + /* Evaluate a standard DWARF3 expression. See detailed description in priv_d3basics.h. */ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, GExpr* fbGX, RegSummary* regs, - Addr data_bias, + const DebugInfo* di, Bool push_initial_zero ) { # define N_EXPR_STACK 20 @@ -508,14 +549,21 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, horrible prelinking-induced complications as described in "Comment_Regarding_DWARF3_Text_Biasing" in readdwarf3.c? Currently I don't know. */ - PUSH( *(Addr*)expr + data_bias ); - expr += sizeof(Addr); + a1 = *(Addr*)expr; + if (bias_address(&a1, di)) { + PUSH( a1 ); + expr += sizeof(Addr); + } + else { + FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address " + "in unknown section"); + } break; case DW_OP_fbreg: if (!fbGX) FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with " "no expr for fbreg present"); - fbval = ML_(evaluate_GX)(fbGX, NULL, regs, data_bias); + fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di); /* Convert fbval into something we can use. If we got a Value, no problem. However, as per D3 spec sec 3.3.5 (Low Level Information) sec 2, we could also get a @@ -621,7 +669,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, /* Evaluate a so-called Guarded (DWARF3) expression. See detailed description in priv_d3basics.h. */ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, - RegSummary* regs, Addr data_bias ) + RegSummary* regs, const DebugInfo* di ) { GXResult res; Addr aMin, aMax; @@ -655,7 +703,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, /* Assert this is the first guard. */ vg_assert(nGuards == 1); res = ML_(evaluate_Dwarf3_Expr)( - p, (UWord)nbytes, fbGX, regs, data_bias, + p, (UWord)nbytes, fbGX, regs, di, False/*push_initial_zero*/ ); /* Now check there are no more guards. */ p += (UWord)nbytes; @@ -665,7 +713,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, if (aMin <= regs->ip && regs->ip <= aMax) { /* found a matching range. Evaluate the expression. */ return ML_(evaluate_Dwarf3_Expr)( - p, (UWord)nbytes, fbGX, regs, data_bias, + p, (UWord)nbytes, fbGX, regs, di, False/*push_initial_zero*/ ); } } @@ -689,7 +737,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, * there's more than one subexpression, all of which successfully evaluate to a constant, but they don't all produce the same constant. */ -GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ) +GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di ) { GXResult res; Addr aMin, aMax; @@ -730,8 +778,14 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ) /* Peer at this particular subexpression, to see if it's obviously a constant. */ if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) { - thisResult.b = True; - thisResult.ul = (ULong)(*(Addr*)(p+1)) + (ULong)data_bias; + Addr a = *(Addr*)(p+1); + if (bias_address(&a, di)) { + thisResult.b = True; + thisResult.ul = (ULong)a; + } + else if (!badness) { + badness = "trivial GExpr denotes constant address in unknown section"; + } } else if (nbytes == 2 + sizeof(Addr) && *p == DW_OP_addr diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index f244f0255d..6239d9035b 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1928,7 +1928,7 @@ static Bool data_address_is_in_var ( /*OUT*/UWord* offset, DiVariable* var, RegSummary* regs, Addr data_addr, - Addr data_bias ) + const DebugInfo* di ) { MaybeULong mul; SizeT var_szB; @@ -1965,7 +1965,7 @@ static Bool data_address_is_in_var ( /*OUT*/UWord* offset, return False; } - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); if (show) { VG_(printf)("VVVV: -> "); @@ -2243,7 +2243,7 @@ Bool consider_vars_in_frame ( /*OUT*/Char* dname1, var->name,arange->aMin,arange->aMax,ip); if (data_address_is_in_var( &offset, di->admin_tyents, var, ®s, - data_addr, di->data_bias )) { + data_addr, di )) { OffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, di->admin_tyents, @@ -2342,7 +2342,7 @@ Bool VG_(get_data_description)( /*OUT*/Char* dname1, fail. */ if (data_address_is_in_var( &offset, di->admin_tyents, var, NULL/* RegSummary* */, - data_addr, di->data_bias )) { + data_addr, di )) { OffT residual_offset = 0; XArray* described = ML_(describe_type)( &residual_offset, di->admin_tyents, @@ -2467,7 +2467,7 @@ Bool VG_(get_data_description)( /*OUT*/Char* dname1, static void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, XArray* /* TyEnt */ tyents, - Addr ip, Addr data_bias, DiVariable* var, + Addr ip, const DebugInfo* di, DiVariable* var, Bool arrays_only ) { GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; @@ -2512,22 +2512,22 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, regs.fp = 0; regs.ip = ip; regs.sp = 6 * 1024; - res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 0; regs.ip = ip; regs.sp = 7 * 1024; - res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 6 * 1024; regs.ip = ip; regs.sp = 0; - res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); regs.fp = 7 * 1024; regs.ip = ip; regs.sp = 0; - res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); vg_assert(res_sp_6k.kind == res_sp_7k.kind); vg_assert(res_sp_6k.kind == res_fp_6k.kind); @@ -2549,7 +2549,7 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, if (sp_delta == 1024 && fp_delta == 0) { regs.sp = regs.fp = 0; regs.ip = ip; - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); tl_assert(res.kind == GXR_Value); if (debug) VG_(printf)(" %5ld .. %5ld (sp) %s\n", @@ -2568,7 +2568,7 @@ void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, if (sp_delta == 0 && fp_delta == 1024) { regs.sp = regs.fp = 0; regs.ip = ip; - res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); tl_assert(res.kind == GXR_Value); if (debug) VG_(printf)(" %5ld .. %5ld (FP) %s\n", @@ -2698,7 +2698,7 @@ void* /* really, XArray* of StackBlock */ VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", var->name,arange->aMin,arange->aMax,ip); analyse_deps( res, di->admin_tyents, ip, - di->data_bias, var, arrays_only ); + di, var, arrays_only ); } } @@ -2781,7 +2781,7 @@ void* /* really, XArray* of GlobalBlock */ it. */ if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); VG_(printf)("\n"); } - res = ML_(evaluate_trivial_GX)( var->gexpr, di->data_bias ); + res = ML_(evaluate_trivial_GX)( var->gexpr, di ); /* Not a constant address => not interesting */ if (res.kind != GXR_Value) { diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h index 1113bf064d..1810ca6c2c 100644 --- a/coregrind/m_debuginfo/priv_d3basics.h +++ b/coregrind/m_debuginfo/priv_d3basics.h @@ -621,7 +621,7 @@ void ML_(pp_GXResult) ( GXResult res ); NULL but the frame base is still needed, then evaluation of gx as a whole will fail. */ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, - RegSummary* regs, Addr data_bias ); + RegSummary* regs, const DebugInfo* di ); /* This is a subsidiary of ML_(evaluate_GX), which just evaluates a single standard DWARF3 expression. Conventions w.r.t regs and fbGX @@ -632,7 +632,7 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX, recursive. */ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, GExpr* fbGX, RegSummary* regs, - Addr data_bias, + const DebugInfo* di, Bool push_initial_zero ); /* Evaluate a very simple Guarded (DWARF3) expression. The expression @@ -642,7 +642,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, location is denoted, a frame base expression is required, or the expression is not manifestly a constant. The range of addresses covered by the guard is also ignored. */ -GXResult ML_(evaluate_trivial_GX)( GExpr* gx, Addr data_bias ); +GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di ); #endif /* ndef __PRIV_D3BASICS_H */ diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index eb17460085..327f8c2bd2 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -366,12 +366,24 @@ struct _DebugInfo { Addr sdata_avma; SizeT sdata_size; OffT sdata_bias; + /* .rodata */ + Bool rodata_present; + Addr rodata_svma; + Addr rodata_avma; + SizeT rodata_size; + OffT rodata_bias; /* .bss */ Bool bss_present; Addr bss_svma; Addr bss_avma; SizeT bss_size; OffT bss_bias; + /* .sbss */ + Bool sbss_present; + Addr sbss_svma; + Addr sbss_avma; + SizeT sbss_size; + OffT sbss_bias; /* .plt */ Bool plt_present; Addr plt_avma; diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index de050c7033..a6fe190484 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -34,6 +34,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 48e8dbe68e..44a832c2da 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -133,6 +133,7 @@ groupies always show up at the top of performance profiles. */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" #include "pub_core_libcassert.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index b5e6be4a16..5558aae5d3 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -36,6 +36,7 @@ #include "pub_core_basics.h" #include "pub_core_vki.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcbase.h" #include "pub_core_libcprint.h" #include "pub_core_libcassert.h" @@ -219,7 +220,7 @@ Bool get_elf_symbol_info ( ) { Bool plausible, is_in_opd; - Bool in_text, in_data, in_sdata, in_bss; + Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss; /* Set defaults */ *sym_name_out = sym_name; @@ -276,12 +277,26 @@ Bool get_elf_symbol_info ( *is_text_out = False; *sym_avma_out += di->sdata_bias; } else + if (di->rodata_present + && di->rodata_size > 0 + && sym_svma >= di->rodata_svma + && sym_svma < di->rodata_svma + di->rodata_size) { + *is_text_out = False; + *sym_avma_out += di->rodata_bias; + } else 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 + if (di->sbss_present + && di->sbss_size > 0 + && sym_svma >= di->sbss_svma + && sym_svma < di->sbss_svma + di->sbss_size) { + *is_text_out = False; + *sym_avma_out += di->sbss_bias; } else { /* Assume it's in .text. Is this a good idea? */ *is_text_out = True; @@ -450,12 +465,24 @@ Bool get_elf_symbol_info ( && !(*sym_avma_out + *sym_size_out <= di->sdata_avma || *sym_avma_out >= di->sdata_avma + di->sdata_size); + in_rodata + = di->rodata_present + && di->rodata_size > 0 + && !(*sym_avma_out + *sym_size_out <= di->rodata_avma + || *sym_avma_out >= di->rodata_avma + di->rodata_size); + in_bss = 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); + in_sbss + = di->sbss_present + && di->sbss_size > 0 + && !(*sym_avma_out + *sym_size_out <= di->sbss_avma + || *sym_avma_out >= di->sbss_avma + di->sbss_size); + if (*is_text_out) { /* This used to reject any symbol falling outside the text @@ -479,9 +506,9 @@ Bool get_elf_symbol_info ( return False; } } else { - if (!(in_data || in_sdata || in_bss)) { + if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) { TRACE_SYMTAB( - "ignore -- %#lx .. %#lx outside .data / .sdata / .bss 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; } @@ -955,15 +982,6 @@ static void* INDEX_BIS ( void* base, Word idx, Word scale ) { return (void*)( ((UChar*)base) + idx * scale ); } -static Addr round_Addr_upwards ( Addr a, UInt align ) -{ - if (align > 0) { - vg_assert(-1 != VG_(log2)(align)); - a = VG_ROUNDUP(a, align); - } - return a; -} - /* Find the file offset corresponding to SVMA by using the program headers. This is taken from binutils-2.17/binutils/readelf.c @@ -1027,15 +1045,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) UWord shdr_ent_szB = 0; UChar* shdr_strtab_img = NULL; - /* To do with figuring out where .sbss is relative to .bss. A - kludge at the best of times. */ - SizeT sbss_size; - Addr sbss_svma; - UInt bss_align; - UInt sbss_align; - UInt data_align; - SizeT bss_totsize; - Addr gen_bss_lowest_svma; + /* SVMAs covered by rx and rw segments and corresponding bias. */ + Addr rx_svma_base = 0; + Addr rx_svma_limit = 0; + OffT rx_bias = 0; + Addr rw_svma_base = 0; + Addr rw_svma_limit = 0; + OffT rw_bias = 0; vg_assert(di); vg_assert(di->have_rx_map == True); @@ -1203,6 +1219,22 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) goto out; } prev_svma = phdr->p_vaddr; + if (rx_svma_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) { + rx_svma_base = phdr->p_vaddr; + rx_svma_limit = phdr->p_vaddr + phdr->p_memsz; + rx_bias = di->rx_map_avma - di->rx_map_foff + phdr->p_offset - phdr->p_vaddr; + } + else if (rw_svma_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) { + rw_svma_base = phdr->p_vaddr; + rw_svma_limit = phdr->p_vaddr + phdr->p_memsz; + rw_bias = di->rw_map_avma - di->rw_map_foff + phdr->p_offset - phdr->p_vaddr; + } } /* Try to get the soname. If there isn't one, use "NONE". @@ -1254,14 +1286,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) di->soname = "NONE"; } - /*SizeT*/ sbss_size = 0; - /*Addr */ sbss_svma = 0; - /*UInt */ bss_align = 0; - /*UInt */ sbss_align = 0; - - /* UInt */ data_align = 0; - /* SizeT */ bss_totsize = 0; - /* Addr */ gen_bss_lowest_svma = ~((Addr)0); + vg_assert(rx_svma_limit != 0); + vg_assert(rw_svma_limit != 0); /* Now read the section table. */ TRACE_SYMTAB("\n"); @@ -1270,9 +1296,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) 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 ); + TRACE_SYMTAB("rx: contains svmas %#lx .. %#lx with bias %#lx\n", + rx_svma_base, rx_svma_limit - 1, rx_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 ); + TRACE_SYMTAB("rw: contains svmas %#lx .. %#lx with bias %#lx\n", + rw_svma_base, rw_svma_limit - 1, rw_bias ); for (i = 0; i < shdr_nent; i++) { ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB ); @@ -1282,10 +1312,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) UWord size = shdr->sh_size; UInt alyn = shdr->sh_addralign; Bool bits = !(shdr->sh_type == SHT_NOBITS); - 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; + Bool inrx = svma >= rx_svma_base && svma < rx_svma_limit; + Bool inrw = svma >= rw_svma_base && svma < rw_svma_limit; TRACE_SYMTAB(" [sec %2ld] %s %s al%2u foff %6ld .. %6ld " " svma %p name \"%s\"\n", @@ -1313,17 +1341,17 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) goto out; \ } while (0) - /* Find avma-s for: .text .data .sdata .bss .plt .got .opd + /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd and .eh_frame */ - /* Accept .text where mapped as rx (code) */ + /* Accept .text where mapped as rx (code), even if zero-sized */ if (0 == VG_(strcmp)(name, ".text")) { - if (inrx && size > 0 && !di->text_present) { + 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_avma = svma + rx_bias; di->text_size = size; - di->text_bias = di->text_avma - svma; + di->text_bias = rx_bias; TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n", di->text_svma, di->text_svma + di->text_size - 1); @@ -1339,13 +1367,11 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .data where mapped as rw (data), even if zero-sized */ if (0 == VG_(strcmp)(name, ".data")) { 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_avma = svma + rw_bias; di->data_size = size; - di->data_bias = di->data_avma - svma; + di->data_bias = rw_bias; TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n", di->data_svma, di->data_svma + di->data_size - 1); @@ -1361,13 +1387,11 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .sdata where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".sdata")) { 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_avma = svma + rw_bias; di->sdata_size = size; - di->sdata_bias = di->sdata_avma - svma; + di->sdata_bias = rw_bias; TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n", di->sdata_svma, di->sdata_svma + di->sdata_size - 1); @@ -1380,20 +1404,34 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } } + /* Accept .rodata where mapped as rx (data), even if zero-sized */ + if (0 == VG_(strcmp)(name, ".rodata")) { + if (inrx && size >= 0 && !di->rodata_present) { + di->rodata_present = True; + di->rodata_svma = svma; + di->rodata_avma = svma + rx_bias; + di->rodata_size = size; + di->rodata_bias = rx_bias; + TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n", + di->rodata_svma, + di->rodata_svma + di->rodata_size - 1); + TRACE_SYMTAB("acquiring .rodata avma = %#lx .. %#lx\n", + di->rodata_avma, + di->rodata_avma + di->rodata_size - 1); + TRACE_SYMTAB("acquiring .rodata bias = %#lx\n", di->rodata_bias); + } else { + BAD(".rodata"); + } + } + /* Accept .bss where mapped as rw (data), even if zero-sized */ if (0 == VG_(strcmp)(name, ".bss")) { 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_avma = svma + rw_bias; di->bss_size = size; - di->bss_bias = di->bss_avma - svma; - bss_align = alyn; + di->bss_bias = rw_bias; TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n", di->bss_svma, di->bss_svma + di->bss_size - 1); @@ -1413,7 +1451,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) di->bss_avma = 0; di->bss_size = 0; di->bss_bias = 0; - bss_align = 0; if (!VG_(clo_xml)) { VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is " "mapped r-x only - ignoring .bss syms"); @@ -1423,14 +1460,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } } else - if ((!inrw) && (!inrx) && size > 0 && !di->bss_present) { + 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; di->bss_bias = 0; - bss_align = 0; } else { BAD(".bss"); } @@ -1438,38 +1474,29 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* 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); - sbss_size = size; - sbss_svma = svma; - sbss_align = alyn; + if (inrw && size > 0 && !di->sbss_present) { + di->sbss_present = True; + di->sbss_svma = svma; + di->sbss_avma = svma + rw_bias; + di->sbss_size = size; + di->sbss_bias = rw_bias; + TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", + di->sbss_svma, + di->sbss_svma + di->sbss_size - 1); + TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n", + di->sbss_avma, + di->sbss_avma + di->sbss_size - 1); + TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", di->sbss_bias); } else { BAD(".sbss"); } } - /* 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); - } else { - BAD(".dynbss"); - } - } - /* Accept .got where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".got")) { 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_avma = svma + rw_bias; di->got_size = size; TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma); } else { @@ -1481,7 +1508,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".got.plt")) { if (inrw && size > 0 && !di->gotplt_present) { di->gotplt_present = True; - di->gotplt_avma = di->rw_map_avma + foff - di->rw_map_foff; + di->gotplt_avma = svma + rw_bias; di->gotplt_size = size; TRACE_SYMTAB("acquiring .got.plt avma = %#lx\n", di->gotplt_avma); } else if (size != 0) { @@ -1495,7 +1522,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".plt")) { 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_avma = svma + rx_bias; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); } else { @@ -1507,7 +1534,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".plt")) { 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_avma = svma + rw_bias; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); } else { @@ -1519,7 +1546,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".plt")) { 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_avma = svma + rw_bias; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); } else @@ -1542,7 +1569,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".opd")) { 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_avma = svma + rw_bias; di->opd_size = size; TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma); } else { @@ -1556,13 +1583,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (0 == VG_(strcmp)(name, ".eh_frame")) { 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_avma = svma + rx_bias; di->ehframe_size = size; TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma); } else if (inrw && size > 0 && !di->ehframe_present) { di->ehframe_present = True; - di->ehframe_avma = di->rw_map_avma + foff - di->rw_map_foff; + di->ehframe_avma = svma + rw_bias; di->ehframe_size = size; TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma); } else { @@ -1574,24 +1601,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } - /* Kludge: ignore all previous computations for .bss avma range, - and simply assume that .bss immediately follows .data/.sdata.*/ - if (1) { - SizeT data_al = round_Addr_upwards(di->data_avma, data_align) - - 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); - di->bss_bias = di->data_bias; - TRACE_SYMTAB("kludged .bss svma = %#lx .. %#lx\n", - di->bss_svma, di->bss_svma + di->bss_size - 1); - TRACE_SYMTAB("kludged .bss avma = %#lx .. %#lx\n", - di->bss_avma, di->bss_avma + di->bss_size - 1); - TRACE_SYMTAB("kludged .bss bias = %#lx\n", di->bss_bias); - } - if (0) VG_(printf)("YYYY text_: avma %#lx size %ld bias %#lx\n", di->text_avma, di->text_size, di->text_bias); diff --git a/coregrind/m_debuginfo/readxcoff.c b/coregrind/m_debuginfo/readxcoff.c index e4442131c5..aaf4ccb6f7 100644 --- a/coregrind/m_debuginfo/readxcoff.c +++ b/coregrind/m_debuginfo/readxcoff.c @@ -58,6 +58,7 @@ #include "pub_core_xarray.h" #include "priv_misc.h" #include "priv_tytypes.h" +#include "pub_tool_debuginfo.h" #include "priv_d3basics.h" #include "priv_storage.h" #include "priv_readxcoff.h" /* self */ diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index d705f0d177..7241778b21 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -39,6 +39,7 @@ #include "pub_core_basics.h" #include "pub_core_options.h" /* VG_(clo_verbosity) */ +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcbase.h" #include "pub_core_libcprint.h" diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c index ad80691f7c..1d38869151 100644 --- a/coregrind/m_debuginfo/tytypes.c +++ b/coregrind/m_debuginfo/tytypes.c @@ -34,6 +34,7 @@ */ #include "pub_core_basics.h" +#include "pub_core_debuginfo.h" #include "pub_core_libcassert.h" #include "pub_core_libcbase.h" #include "pub_core_libcprint.h" -- 2.47.2