]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge from the trunk, a bunch of changes to fix ELF segment mapping
authorJulian Seward <jseward@acm.org>
Mon, 26 Jan 2009 13:02:16 +0000 (13:02 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 26 Jan 2009 13:02:16 +0000 (13:02 +0000)
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
coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_d3basics.h
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readdwarf.c
coregrind/m_debuginfo/readdwarf3.c
coregrind/m_debuginfo/readelf.c
coregrind/m_debuginfo/readxcoff.c
coregrind/m_debuginfo/storage.c
coregrind/m_debuginfo/tytypes.c

index 7f932910e342747eb7c28f514b0d584d2e66008b..64f602764459b9b808ab8a01daac6254d387fb28 100644 (file)
@@ -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
index f244f0255de2081adbe601acf975d51df1a8bee9..6239d9035b3ec59669c10e835613d7cb73086e63 100644 (file)
@@ -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, &regs,
-                                     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, &regs, data_bias );
+   res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
 
    regs.fp   = 0;
    regs.ip   = ip;
    regs.sp   = 7 * 1024;
-   res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, data_bias );
+   res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
 
    regs.fp   = 6 * 1024;
    regs.ip   = ip;
    regs.sp   = 0;
-   res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, data_bias );
+   res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
 
    regs.fp   = 7 * 1024;
    regs.ip   = ip;
    regs.sp   = 0;
-   res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, data_bias );
+   res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, 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, &regs, data_bias );
+         res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, 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, &regs, data_bias );
+         res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, 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) {
index 1113bf064d3a098a23d2abb3604275a0c49b220f..1810ca6c2c677c5cc9fba9f47250f0adc82007e1 100644 (file)
@@ -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 */
 
index eb174600855ff438c86e13cb15e555e8b20a4871..327f8c2bd25586e3d56c0f8ec5219b6dab905144 100644 (file)
@@ -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;
index de050c703369b5b019d9f351be04b9c1a2a2c647..a6fe19048411e57dd6869bb00cfb6b796983c305 100644 (file)
@@ -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"
index 48e8dbe68ed61d785b7133a1f4c1625697b63681..44a832c2da48f31c75a0068f5ff06af211a05ede 100644 (file)
    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"
index b5e6be4a1671b9b9ecad6f3c73f36889a2ea9531..5558aae5d3ec22491586ff2041a05b84179e605d 100644 (file)
@@ -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);
 
index e4442131c5f34a32f72be5a90435c68c0247600b..aaf4ccb6f724ecab362d5d4572eb55e447a18669 100644 (file)
@@ -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 */
index d705f0d177a7f8f8567b460f58454b733f3b3ec3..7241778b218e4f36449cabcb0b04f213fbddf71f 100644 (file)
@@ -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"
index ad80691f7c08d7d69ddffc0abe624a9f21235b99..1d388691518be9e71b06e8675aed0bd2debf82c8 100644 (file)
@@ -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"