]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Keep track of the svma and bias values for the debug data separately
authorTom Hughes <tom@compton.nu>
Mon, 9 Mar 2009 09:19:03 +0000 (09:19 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 9 Mar 2009 09:19:03 +0000 (09:19 +0000)
as they may be different to those for other sections of the ELF file
if we have separated debug information and the main file has been
prelinked since they were split. Fixes bug #185816.

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

coregrind/m_debuginfo/d3basics.c
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readdwarf.c
coregrind/m_debuginfo/readdwarf3.c
coregrind/m_debuginfo/readelf.c
coregrind/m_debuginfo/readstabs.c

index 50af1a26b27d18907e183678f04fe012a29da459..ceed0c97ac35bb94c82b46bfef3ac3588b4f9b9e 100644 (file)
@@ -406,33 +406,33 @@ 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;
+       && *a >= di->text_debug_svma && *a < di->text_debug_svma + di->text_size) {
+      *a += di->text_debug_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;
+            && *a >= di->data_debug_svma && *a < di->data_debug_svma + di->data_size) {
+      *a += di->data_debug_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;
+            && *a >= di->sdata_debug_svma && *a < di->sdata_debug_svma + di->sdata_size) {
+      *a += di->sdata_debug_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;
+            && *a >= di->rodata_debug_svma && *a < di->rodata_debug_svma + di->rodata_size) {
+      *a += di->rodata_debug_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;
+            && *a >= di->bss_debug_svma && *a < di->bss_debug_svma + di->bss_size) {
+      *a += di->bss_debug_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;
+            && *a >= di->sbss_debug_svma && *a < di->sbss_debug_svma + di->sbss_size) {
+      *a += di->sbss_debug_bias;
    }
    else {
       return False;
@@ -541,14 +541,8 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
       switch (opcode) {
          case DW_OP_addr:
             /* Presumably what is given in the Dwarf3 is a SVMA (how
-               could it be otherwise?)  So we add the data bias on
-               before pushing the result.  FIXME: how can we be sure
-               the data bias is intended, not the text bias?  I don't
-               know. */
-            /* Furthermore, do we need to take into account the
-               horrible prelinking-induced complications as described
-               in "Comment_Regarding_DWARF3_Text_Biasing" in
-               readdwarf3.c?  Currently I don't know. */
+               could it be otherwise?)  So we add the appropriate bias
+               on before pushing the result. */
             a1 = *(Addr*)expr;
             if (bias_address(&a1, di)) {
                PUSH( a1 ); 
index a466aeb7097426da5f04d6f6c3640d431fe4be63..918a8418443edefe6049b71c0fae93e97765fefa 100644 (file)
@@ -354,36 +354,48 @@ struct _DebugInfo {
    Addr     text_svma;
    SizeT    text_size;
    PtrdiffT text_bias;
+   Addr     text_debug_svma;
+   PtrdiffT text_debug_bias;
    /* .data */
    Bool     data_present;
    Addr     data_svma;
    Addr     data_avma;
    SizeT    data_size;
    PtrdiffT data_bias;
+   Addr     data_debug_svma;
+   PtrdiffT data_debug_bias;
    /* .sdata */
    Bool     sdata_present;
    Addr     sdata_svma;
    Addr     sdata_avma;
    SizeT    sdata_size;
    PtrdiffT sdata_bias;
+   Addr     sdata_debug_svma;
+   PtrdiffT sdata_debug_bias;
    /* .rodata */
    Bool     rodata_present;
    Addr     rodata_svma;
    Addr     rodata_avma;
    SizeT    rodata_size;
    PtrdiffT rodata_bias;
+   Addr     rodata_debug_svma;
+   PtrdiffT rodata_debug_bias;
    /* .bss */
    Bool     bss_present;
    Addr     bss_svma;
    Addr     bss_avma;
    SizeT    bss_size;
    PtrdiffT bss_bias;
+   Addr     bss_debug_svma;
+   PtrdiffT bss_debug_bias;
    /* .sbss */
    Bool     sbss_present;
    Addr     sbss_svma;
    Addr     sbss_avma;
    SizeT    sbss_size;
    PtrdiffT sbss_bias;
+   Addr     sbss_debug_svma;
+   PtrdiffT sbss_debug_bias;
    /* .plt */
    Bool   plt_present;
    Addr          plt_avma;
index 3a23e355444c9f94ec7b9bd7911a3716fcc31f18..05f9a46113ab4d9dfb2309892df056b4d713c9ac 100644 (file)
@@ -362,7 +362,7 @@ Word process_extended_line_op( struct _DebugInfo* di,
    switch (op_code) {
       case DW_LNE_end_sequence:
          if (0) VG_(printf)("1001: si->o %#lx, smr.a %#lx\n",
-                            di->text_bias, state_machine_regs.address );
+                            di->text_debug_bias, state_machine_regs.address );
          /* JRS: added for compliance with spec; is pointless due to
             reset_state_machine below */
          state_machine_regs.end_sequence = 1; 
@@ -380,8 +380,8 @@ Word process_extended_line_op( struct _DebugInfo* di,
                   filename, 
                   lookupDir( state_machine_regs.last_file,
                              fnidx2dir, dirnames ),
-                  di->text_bias + state_machine_regs.last_address, 
-                  di->text_bias + state_machine_regs.address, 
+                  di->text_debug_bias + state_machine_regs.last_address, 
+                  di->text_debug_bias + state_machine_regs.address, 
                   state_machine_regs.last_line, 0
                );
             }
@@ -724,7 +724,7 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
          if (0) VG_(printf)("smr.a += %#x\n", adv );
          adv = (op_code % info.li_line_range) + info.li_line_base;
          if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
-                            di->text_bias, state_machine_regs.address );
+                            di->text_debug_bias, state_machine_regs.address );
          state_machine_regs.line += adv;
 
          if (di->ddump_line)
@@ -747,8 +747,8 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
                   filename,
                   lookupDir( state_machine_regs.last_file,
                              &fnidx2dir, &dirnames ),
-                  di->text_bias + state_machine_regs.last_address, 
-                  di->text_bias + state_machine_regs.address, 
+                  di->text_debug_bias + state_machine_regs.last_address, 
+                  di->text_debug_bias + state_machine_regs.address, 
                   state_machine_regs.last_line, 
                   0
                );
@@ -771,7 +771,7 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
 
          case DW_LNS_copy:
             if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
-                               di->text_bias, state_machine_regs.address );
+                               di->text_debug_bias, state_machine_regs.address );
             if (state_machine_regs.is_stmt) {
                /* only add a statement if there was a previous boundary */
                if (state_machine_regs.last_address) {
@@ -786,8 +786,8 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
                      filename,
                      lookupDir( state_machine_regs.last_file,
                                 &fnidx2dir, &dirnames ),
-                     di->text_bias + state_machine_regs.last_address, 
-                     di->text_bias + state_machine_regs.address,
+                     di->text_debug_bias + state_machine_regs.last_address, 
+                     di->text_debug_bias + state_machine_regs.address,
                      state_machine_regs.last_line, 
                      0
                   );
@@ -3629,7 +3629,7 @@ void ML_(read_callframe_info_dwarf3)
             adi.encoding      = the_CIEs[this_CIE].address_encoding;
             adi.ehframe_image = ehframe_image;
             adi.ehframe_avma  = di->ehframe_avma;
-            adi.text_bias     = di->text_bias;
+            adi.text_bias     = di->text_debug_bias;
             show_CF_instructions( the_CIEs[this_CIE].instrs, 
                                   the_CIEs[this_CIE].ilen, &adi,
                                   the_CIEs[this_CIE].code_a_f,
@@ -3676,7 +3676,7 @@ void ML_(read_callframe_info_dwarf3)
          adi.encoding      = the_CIEs[cie].address_encoding;
          adi.ehframe_image = ehframe_image;
          adi.ehframe_avma  = di->ehframe_avma;
-         adi.text_bias     = di->text_bias;
+         adi.text_bias     = di->text_debug_bias;
          fde_initloc = read_encoded_Addr(&nbytes, &adi, data);
          data += nbytes;
          if (di->trace_cfi) 
@@ -3685,7 +3685,7 @@ void ML_(read_callframe_info_dwarf3)
          adi.encoding      = the_CIEs[cie].address_encoding & 0xf;
          adi.ehframe_image = ehframe_image;
          adi.ehframe_avma  = di->ehframe_avma;
-         adi.text_bias     = di->text_bias;
+         adi.text_bias     = di->text_debug_bias;
 
          /* WAS (incorrectly):
             fde_arange = read_encoded_Addr(&nbytes, &adi, data);
@@ -3714,8 +3714,8 @@ void ML_(read_callframe_info_dwarf3)
                         (Addr)ciefde_len,
                         (Addr)(UWord)cie_pointer,
                         (Addr)look_for, 
-                        ((Addr)fde_initloc) - di->text_bias, 
-                        ((Addr)fde_initloc) - di->text_bias + fde_arange);
+                        ((Addr)fde_initloc) - di->text_debug_bias, 
+                        ((Addr)fde_initloc) - di->text_debug_bias + fde_arange);
 
          if (the_CIEs[cie].saw_z_augmentation) {
             UInt length = read_leb128( data, &nbytes, 0);
@@ -3747,7 +3747,7 @@ void ML_(read_callframe_info_dwarf3)
          adi.encoding      = the_CIEs[cie].address_encoding;
          adi.ehframe_image = ehframe_image;
          adi.ehframe_avma  = di->ehframe_avma;
-         adi.text_bias     = di->text_bias;
+         adi.text_bias     = di->text_debug_bias;
 
          if (di->trace_cfi)
             show_CF_instructions( fde_instrs, fde_ilen, &adi,
index b8b4aba18814034984917ed832ada96ffee06159..088e1f3d40958a8e521f538fd1bb4a3c63bfe2cf 100644 (file)
@@ -474,97 +474,8 @@ typedef
    it more logically belongs. */
 
 
-/* "Comment_Regarding_DWARF3_Text_Biasing" (is referred to elsewhere)
-    -----------------------------------------------------------------
-    apply_kludgey_text_bias() is our mechanism for biasing text
-    addresses found in DWARF3 .debug_info, .debug_ranges, .debug_loc
-    sections.  This is a nasty and unprincipled hack.
-
-    Biasing the text svmas, so as to obtain text avmas, should be
-    straightforward, right?  We just add on di->text_bias, as
-    carefully computed by readelf.c.
-
-    That works OK most of the time.  But in the following case it fails:
-    1. The object is made in the usual way (gcc -g, etc)
-    2. The DWARF3 stuff removed from it and parked in a .debuginfo object
-    3. The remaining (base) object is then prelinked.
-
-    Prelinking changes the text svmas throughout an object by some
-    constant amount, including the DWARF3 stuff.  So if the DWARF3
-    stuff remains attached to the original object, then there is no
-    problem.  However, if the DWARF3 stuff is detached, and the
-    remaining object is prelinked and the debuginfo object isn't, then
-    we have a problem: the text bias computed for the main object
-    isn't correct for the debuginfo object.
-
-    So the following kludged is used to bias text svmas.
-
-    1. First, try with the text bias computed for the main object.  If
-       that gives an avma inside the area in which the text segment is
-       known to have been mapped, then all well and good.
-
-    2. If not, try using the avma of the text mapped area as a bias.
-       Again, if that works out, fine.  This is the heart of the
-       kludge.  It implicitly treats the svma-s to be biased as if
-       they had been prelinked to zero.
-
-    3. If even that doesn't work, just return the avma unchanged.
-
-    For each object/object-pair, we count the number of times each
-    case occurs.  We flag an error (which the user gets to see) if (3)
-    ever occurs, or if a mixture of (1) and (2) occurs.  That should
-    at least catch the most obvious snafus.
-
-    Caveats: the main remaining worry is whether this problem somehow
-    also affects the data-biasing done for case DW_OP_addr in
-    ML_(evaluate_Dwarf3_Expr) in d3basics.c.  This is currently
-    unknown.
-
-    Possible sources of info: canonical description seems to be:
-
-       http://people.redhat.com/jakub/prelink.pdf
-
-    See para at line 337 starting "DWARF 2 debugging information ..."
-
-    This thread looks like the gdb people hitting the same issue:
-
-       http://sourceware.org/ml/gdb-patches/2007-01/msg00278.html
-*/
-typedef
-   struct {
-      /* FIXED */
-      Addr     rx_map_avma;
-      SizeT    rx_map_size;
-      PtrdiffT text_bias;
-      /* VARIABLE -- count stats */
-      UWord n_straightforward_biasings;
-      UWord n_kludgey_biasings;
-      UWord n_failed_biasings;
-   }
-   KludgeyTextBiaser;
-
-static Addr apply_kludgey_text_bias ( KludgeyTextBiaser* ktb,
-                                      Addr allegedly_text_svma ) {
-   Addr res;
-   res = allegedly_text_svma + ktb->text_bias;
-   if (res >= ktb->rx_map_avma 
-       && res < ktb->rx_map_avma + ktb->rx_map_size) {
-      ktb->n_straightforward_biasings++;
-      return res;
-   }
-   res = allegedly_text_svma + ktb->rx_map_avma;
-   if (res >= ktb->rx_map_avma 
-       && res < ktb->rx_map_avma + ktb->rx_map_size) {
-      ktb->n_kludgey_biasings++;
-      return res;
-   }
-   ktb->n_failed_biasings++;
-   return allegedly_text_svma; /* this svma is a luzer */
-}
-
-
-/* Apply a text bias to a GX.  Kludgily :-( */
-static void bias_GX ( /*MOD*/GExpr* gx, KludgeyTextBiaser* ktb )
+/* Apply a text bias to a GX. */
+static void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
 {
    UShort nbytes;
    Addr*  pA;
@@ -582,11 +493,11 @@ static void bias_GX ( /*MOD*/GExpr* gx, KludgeyTextBiaser* ktb )
       vg_assert(uc == 0);
       /* t-bias aMin */
       pA = (Addr*)p;
-      *pA = apply_kludgey_text_bias( ktb, *pA );
+      *pA += di->text_debug_bias;
       p += sizeof(Addr);
       /* t-bias aMax */
       pA = (Addr*)p;
-      *pA = apply_kludgey_text_bias( ktb, *pA );
+      *pA += di->text_debug_bias;
       p += sizeof(Addr);
       /* nbytes, and actual expression */
       nbytes = * (UShort*)p; p += sizeof(UShort);
@@ -3206,8 +3117,6 @@ void new_dwarf3_reader_wrk (
    Word  i, j, n;
    Bool td3 = di->trace_symtab;
    XArray* /* of TempVar* */ dioff_lookup_tab;
-   Bool text_biasing_borked;
-   KludgeyTextBiaser ktb;
 #if 0
    /* This doesn't work properly because it assumes all entries are
       packed end to end, with no holes.  But that doesn't always
@@ -3628,19 +3537,14 @@ void new_dwarf3_reader_wrk (
    vg_assert(!di->admin_tyents);
    di->admin_tyents = tyents_to_keep;
 
-   /* Bias all the location expressions.  See
-      "Comment_Regarding_DWARF3_Text_Biasing" above. */
+   /* Bias all the location expressions. */
    TRACE_D3("\n");
    TRACE_D3("------ Biasing the location expressions ------\n" );
-   VG_(memset)( &ktb, 0, sizeof(ktb ));
-   ktb.rx_map_avma = di->rx_map_avma;
-   ktb.rx_map_size = di->rx_map_size;
-   ktb.text_bias   = di->text_bias;
 
    n = VG_(sizeXA)( gexprs );
    for (i = 0; i < n; i++) {
       gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
-      bias_GX( gexpr, &ktb );
+      bias_GX( gexpr, di );
    }
 
    TRACE_D3("\n");
@@ -3830,8 +3734,8 @@ void new_dwarf3_reader_wrk (
 
            /* Apply text biasing, for non-global variables. */
            if (varp->level > 0) {
-              pcMin = apply_kludgey_text_bias( &ktb, pcMin );
-              pcMax = apply_kludgey_text_bias( &ktb, pcMax );
+              pcMin += di->text_debug_bias;
+              pcMax += di->text_debug_bias;
            } 
 
            if (i > 0 && (i%2) == 0) 
@@ -3852,27 +3756,6 @@ void new_dwarf3_reader_wrk (
       /* and move on to the next var */
    }
 
-   /* For the text biasing to work out, we expect that:
-      - there were no failures, and
-      - either all were done straightforwardly, or all kludgily,
-        but not with a mixture
-   */ 
-   text_biasing_borked 
-      = ktb.n_failed_biasings > 0 
-        || (ktb.n_straightforward_biasings > 0 && ktb.n_kludgey_biasings > 0);
-
-   if (td3 || text_biasing_borked) {
-      VG_(printf)("TEXT SVMA BIASING STATISTICS:\n");
-      VG_(printf)("   straightforward biasings: %lu\n",
-                  ktb.n_straightforward_biasings );
-      VG_(printf)("           kludgey biasings: %lu\n",
-                  ktb.n_kludgey_biasings );
-      VG_(printf)("            failed biasings: %lu\n\n",
-                  ktb.n_failed_biasings );
-   }
-   if (text_biasing_borked)
-      barf("couldn't make sense of DWARF3 text-svma biasing; details above");
-
    /* Now free all the TempVars */
    n = VG_(sizeXA)( tempvars );
    for (i = 0; i < n; i++) {
index 158cd318860d98d9fa62e32c81b1179e64cb0c87..ab75d5acd751befcd46b9013feb94b764b8250b4 100644 (file)
@@ -1352,6 +1352,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->text_avma = svma + rx_bias;
             di->text_size = size;
             di->text_bias = rx_bias;
+            di->text_debug_svma = svma;
+            di->text_debug_bias = rx_bias;
             TRACE_SYMTAB("acquiring .text svma = %#lx .. %#lx\n",
                          di->text_svma, 
                          di->text_svma + di->text_size - 1);
@@ -1372,6 +1374,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->data_avma = svma + rw_bias;
             di->data_size = size;
             di->data_bias = rw_bias;
+            di->data_debug_svma = svma;
+            di->data_debug_bias = rw_bias;
             TRACE_SYMTAB("acquiring .data svma = %#lx .. %#lx\n",
                          di->data_svma,
                          di->data_svma + di->data_size - 1);
@@ -1392,6 +1396,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->sdata_avma = svma + rw_bias;
             di->sdata_size = size;
             di->sdata_bias = rw_bias;
+            di->sdata_debug_svma = svma;
+            di->sdata_debug_bias = rw_bias;
             TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n",
                          di->sdata_svma,
                          di->sdata_svma + di->sdata_size - 1);
@@ -1412,6 +1418,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->rodata_avma = svma + rx_bias;
             di->rodata_size = size;
             di->rodata_bias = rx_bias;
+            di->rodata_debug_svma = svma;
+            di->rodata_debug_bias = rw_bias;
             TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
                          di->rodata_svma,
                          di->rodata_svma + di->rodata_size - 1);
@@ -1432,6 +1440,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->bss_avma = svma + rw_bias;
             di->bss_size = size;
             di->bss_bias = rw_bias;
+            di->bss_debug_svma = svma;
+            di->bss_debug_bias = rw_bias;
             TRACE_SYMTAB("acquiring .bss svma = %#lx .. %#lx\n",
                          di->bss_svma,
                          di->bss_svma + di->bss_size - 1);
@@ -1451,6 +1461,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->bss_avma = 0;
             di->bss_size = 0;
             di->bss_bias = 0;
+            di->bss_debug_svma = 0;
+            di->bss_debug_bias = 0;
             if (!VG_(clo_xml)) {
                VG_(message)(Vg_UserMsg, "Warning: the following file's .bss is "
                                        "mapped r-x only - ignoring .bss syms");
@@ -1480,6 +1492,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             di->sbss_avma = svma + rw_bias;
             di->sbss_size = size;
             di->sbss_bias = rw_bias;
+            di->sbss_debug_svma = svma;
+            di->sbss_debug_bias = rw_bias;
             TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n",
                          di->sbss_svma,
                          di->sbss_svma + di->sbss_size - 1);
@@ -1748,6 +1762,14 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
             UWord       shdr_dent_szB    = ehdr_dimg->e_shentsize;
             UChar*      shdr_strtab_dimg = NULL;
 
+            /* SVMAs covered by rx and rw segments and corresponding bias. */
+            Addr     rx_dsvma_base = 0;
+            Addr     rx_dsvma_limit = 0;
+            PtrdiffT rx_dbias = 0;
+            Addr     rw_dsvma_base = 0;
+            Addr     rw_dsvma_limit = 0;
+            PtrdiffT rw_dbias = 0;
+
             Bool need_symtab, need_stabs, need_dwarf2, need_dwarf1;
 
             if (phdr_dnent == 0
@@ -1797,22 +1819,63 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
                   = INDEX_BIS( (void*)(dimage + ehdr_dimg->e_phoff), 
                                           i, phdr_ent_szB );
                if (phdr->p_type == PT_LOAD) {
-                  //offset_dimage = di->text_avma - phdr->p_vaddr;
-                  // FIXME: update di->text_bias at this point?
-                  // or can we assume the SVMAs in the debuginfo
-                  // file (hence, the biases) are the same as
-                  // established from the main file?
-                  break;
+                  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) {
+                     rx_dsvma_base = phdr->p_vaddr;
+                     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;
+                  }
+                  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) {
+                     rw_dsvma_base = phdr->p_vaddr;
+                     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;
+                  }
                }
             }
 
-            /* Same deal as previous FIND, except only do it for those
-               sections for which we didn't find anything useful in
-               the main file. */
-
             /* Find all interesting sections */
             for (i = 0; i < ehdr_dimg->e_shnum; i++) {
 
+               /* Find debug svma and bias information for sections
+                  we found in the main file. */ 
+
+#              define FIND(sec, seg) \
+               do { ElfXX_Shdr* shdr \
+                       = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
+                  if (di->sec##_present \
+                      && 0 == VG_(strcmp)("." #sec, \
+                                          shdr_strtab_dimg + shdr->sh_name)) { \
+                     vg_assert(di->sec##_size == shdr->sh_size); \
+                     vg_assert(di->sec##_avma +  shdr->sh_addr + seg##_dbias); \
+                     di->sec##_debug_svma = shdr->sh_addr; \
+                     di->sec##_debug_bias = seg##_dbias; \
+                     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", \
+                                  di->sec##_debug_bias); \
+                  } \
+               } while (0);
+
+               /* SECTION   SEGMENT */
+               FIND(text,   rx)
+               FIND(data,   rw)
+               FIND(sdata,  rw)
+               FIND(rodata, rw)
+               FIND(bss,    rw)
+               FIND(sbss,   rw)
+
+#              undef FIND
+
+               /* Same deal as previous FIND, except only do it for those
+                  sections for which we didn't find anything useful in
+                  the main file. */
+
 #              define FIND(condition, sec_name, sec_size, sec_img) \
                do { ElfXX_Shdr* shdr \
                        = INDEX_BIS( shdr_dimg, i, shdr_dent_szB ); \
index 4ad1956ecff9e349f048a0de883233adc81a3c94..3c3072b502b1ab8a4021c6eec1d503645aaf6c75 100644 (file)
@@ -336,7 +336,7 @@ void ML_(read_debuginfo_stabs) ( DebugInfo* di,
                line.first = True;
 
                /* line ends at start of next function */
-               addr = di->text_bias + st->n_value;
+               addr = di->text_debug_bias + st->n_value;
 
                func.start = addr;
             }