Blob Blame Raw
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/d3basics.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/d3basics.c	2009-01-27 16:32:54.000000000 +0100
@@ -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* 
    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) ( UCh
                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) ( UCh
 /* 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, GE
          /* 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, GE
          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*/ );
          }
       }
@@ -688,8 +736,11 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GE
    * any of the subexpressions do not produce a manifest constant
    * 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 )
+   JRS 23Jan09: the special-casing in this function is a nasty kludge.
+   Really it ought to be pulled out and turned into a general
+   constant- expression evaluator.
+*/
+GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
 {
    GXResult   res;
    Addr       aMin, aMax;
@@ -699,7 +750,7 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
    MaybeULong *mul, *mul2;
 
    HChar*  badness = NULL;
-   UChar*  p       = &gx->payload[0];
+   UChar*  p       = &gx->payload[0]; /* must remain unsigned */
    XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
                                  ML_(dinfo_free),
                                  sizeof(MaybeULong) );
@@ -730,12 +781,41 @@ GXResult ML_(evaluate_trivial_GX)( GExpr
       /* 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;
+         /* DW_OP_addr a */
+         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 (1)";
+         }
       }
-      else if (nbytes == 2 + sizeof(Addr) 
-               && *p == DW_OP_addr
-               && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
+      else 
+      if (nbytes == 1 + sizeof(Addr) + 1 + 1
+          /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
+             (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
+             This is really a nasty kludge - only matches if the
+             trailing ULEB denotes a number in the range 0 .. 127
+             inclusive. */
+          && p[0] == DW_OP_addr
+          && p[1 + sizeof(Addr)] == DW_OP_plus_uconst 
+          && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
+         Addr a = *(Addr*)&p[1];
+         if (bias_address(&a, di)) {
+            thisResult.b = True;
+            thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
+         } else {
+            if (!badness)
+               badness = "trivial GExpr denotes constant address "
+                         "in unknown section (2)";
+         }
+      }
+      else
+      if (nbytes == 2 + sizeof(Addr) 
+          && *p == DW_OP_addr
+          && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
          if (!badness)
             badness = "trivial GExpr is DW_OP_addr plus trailing junk";
       }
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/debuginfo.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/debuginfo.c	2009-01-27 16:32:54.000000000 +0100
@@ -1036,7 +1036,17 @@ static void search_all_symtabs ( Addr pt
                    (di->bss_present
                     && di->bss_size > 0
                     && di->bss_avma <= ptr 
-                    && ptr < di->bss_avma + di->bss_size);
+                    && ptr < di->bss_avma + di->bss_size)
+                   ||
+                   (di->sbss_present
+                    && di->sbss_size > 0
+                    && di->sbss_avma <= ptr 
+                    && ptr < di->sbss_avma + di->sbss_size)
+                   ||
+                   (di->rodata_present
+                    && di->rodata_size > 0
+                    && di->rodata_avma <= ptr 
+                    && ptr < di->rodata_avma + di->rodata_size);
       }
 
       if (!inRange) continue;
@@ -1064,6 +1074,7 @@ static void search_all_loctabs ( Addr pt
    DebugInfo* di;
    for (di = debugInfo_list; di != NULL; di = di->next) {
       if (di->text_present
+          && di->text_size > 0
           && di->text_avma <= ptr 
           && ptr < di->text_avma + di->text_size) {
          lno = ML_(search_one_loctab) ( di, ptr );
@@ -1250,6 +1261,7 @@ Bool VG_(get_objname) ( Addr a, Char* bu
       expect this to produce a result. */
    for (di = debugInfo_list; di != NULL; di = di->next) {
       if (di->text_present
+          && di->text_size > 0
           && di->text_avma <= a 
           && a < di->text_avma + di->text_size) {
          VG_(strncpy_safely)(buf, di->filename, nbuf);
@@ -1288,6 +1300,7 @@ DebugInfo* VG_(find_seginfo) ( Addr a )
    DebugInfo* di;
    for (di = debugInfo_list; di != NULL; di = di->next) {
       if (di->text_present
+          && di->text_size > 0
           && di->text_avma <= a 
           && a < di->text_avma + di->text_size) {
          return di;
@@ -1928,7 +1941,7 @@ static Bool data_address_is_in_var ( /*O
                                      DiVariable*   var,
                                      RegSummary*   regs,
                                      Addr          data_addr,
-                                     Addr          data_bias )
+                                     const DebugInfo* di )
 {
    MaybeULong mul;
    SizeT      var_szB;
@@ -1965,7 +1978,7 @@ static Bool data_address_is_in_var ( /*O
       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 +2256,7 @@ Bool consider_vars_in_frame ( /*OUT*/Cha
                         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 +2355,7 @@ Bool VG_(get_data_description)( /*OUT*/C
             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 +2480,7 @@ Bool VG_(get_data_description)( /*OUT*/C
 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 +2525,22 @@ void analyse_deps ( /*MOD*/XArray* /* of
    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 +2562,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
       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 +2581,7 @@ void analyse_deps ( /*MOD*/XArray* /* of
       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 +2711,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 +2794,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) {
@@ -2939,6 +2952,7 @@ const HChar* VG_(pp_SectKind)( VgSectKin
       case Vg_SectGOT:     return "GOT";
       case Vg_SectPLT:     return "PLT";
       case Vg_SectOPD:     return "OPD";
+      case Vg_SectGOTPLT:  return "GOTPLT";
       default:             vg_assert(0);
    }
 }
@@ -2989,6 +3003,12 @@ VgSectKind VG_(seginfo_sect_kind)( /*OUT
          res = Vg_SectBSS;
          break;
       }
+      if (di->sbss_present
+          && di->sbss_size > 0
+          && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
+         res = Vg_SectBSS;
+         break;
+      }
       if (di->plt_present
           && di->plt_size > 0
           && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/priv_d3basics.h	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/priv_d3basics.h	2009-01-27 16:32:54.000000000 +0100
@@ -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, GE
    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) ( UCh
    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 */
 
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/priv_storage.h	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/priv_storage.h	2009-01-27 16:32:54.000000000 +0100
@@ -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;
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readdwarf3.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readdwarf3.c	2009-01-27 16:32:54.000000000 +0100
@@ -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"
@@ -386,7 +387,12 @@ typedef
       Bool   is_dw64;
       /* Which DWARF version ?  (2 or 3) */
       UShort version;
-      /* Length of this Compilation Unit, excluding its Header */
+      /* Length of this Compilation Unit, as stated in the
+         .unit_length :: InitialLength field of the CU Header.
+         However, this size (as specified by the D3 spec) does not
+         include the size of the .unit_length field itself, which is
+         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
+         can be obtained through the expression ".is_dw64 ? 12 : 4". */
       ULong  unit_length;
       /* Offset of start of this unit in .debug_info */
       UWord  cu_start_offset;
@@ -412,6 +418,9 @@ typedef
       /* Where is .debug_line? */
       UChar* debug_line_img;
       UWord  debug_line_sz;
+      /* Where is .debug_info? */
+      UChar* debug_info_img;
+      UWord  debug_info_sz;
       /* --- Needed so we can add stuff to the string table. --- */
       struct _DebugInfo* di;
       /* --- a cache for set_abbv_Cursor --- */
@@ -895,7 +904,8 @@ void parse_CU_Header ( /*OUT*/CUConst* c
 
    /* address size.  If this isn't equal to the host word size, just
       give up.  This makes it safe to assume elsewhere that
-      DW_FORM_addr can be treated as a host word. */
+      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
+      word. */
    address_size = get_UChar( c );
    if (address_size != sizeof(void*))
       cc->barf( "parse_CU_Header: invalid address_size" );
@@ -1077,12 +1087,43 @@ void get_Form_contents ( /*OUT*/ULong* c
          *ctsSzB = sizeof(UWord);
          TRACE_D3("0x%lx", (UWord)*cts);
          break;
+
+      case DW_FORM_ref_addr:
+         /* We make the same word-size assumption as DW_FORM_addr. */
+         /* What does this really mean?  From D3 Sec 7.5.4,
+            description of "reference", it would appear to reference
+            some other DIE, by specifying the offset from the
+            beginning of a .debug_info section.  The D3 spec mentions
+            that this might be in some other shared object and
+            executable.  But I don't see how the name of the other
+            object/exe is specified.
+
+            At least for the DW_FORM_ref_addrs created by icc11, the
+            references seem to be within the same object/executable.
+            So for the moment we merely range-check, to see that they
+            actually do specify a plausible offset within this
+            object's .debug_info, and return the value unchanged.
+         */
+         *cts = (ULong)(UWord)get_UWord(c);
+         *ctsSzB = sizeof(UWord);
+         TRACE_D3("0x%lx", (UWord)*cts);
+         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)*cts);
+         if (/* the following 2 are surely impossible, but ... */
+             cc->debug_info_img == NULL || cc->debug_info_sz == 0
+             || *cts >= (ULong)cc->debug_info_sz) {
+            /* Hmm.  Offset is nonsensical for this object's .debug_info
+               section.  Be safe and reject it. */
+            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
+                     "outside .debug_info");
+         }
+         break;
+
       case DW_FORM_strp: {
          /* this is an offset into .debug_str */
          UChar* str;
          UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
          if (cc->debug_str_img == NULL || uw >= cc->debug_str_sz)
-            cc->barf("read_and_show_Form: DW_FORM_strp "
+            cc->barf("get_Form_contents: DW_FORM_strp "
                      "points outside .debug_str");
          /* FIXME: check the entire string lies inside debug_str,
             not just the first byte of it. */
@@ -1143,8 +1184,9 @@ void get_Form_contents ( /*OUT*/ULong* c
          break;
       }
       default:
-         VG_(printf)("get_Form_contents: unhandled %d (%s)\n",
-                     form, ML_(pp_DW_FORM)(form));
+         VG_(printf)(
+            "get_Form_contents: unhandled %d (%s) at <%lx>\n",
+            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
          c->barf("get_Form_contents: unhandled DW_FORM");
    }
 }
@@ -2178,14 +2220,13 @@ static void parse_type_DIE ( /*MOD*/XArr
       typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
       typeE.Te.TyPorR.isPtr = dtag == DW_TAG_pointer_type
                               || dtag == DW_TAG_ptr_to_member_type;
-      /* Pointer types don't *have* to specify their size, in which
-         case we assume it's a machine word.  But if they do specify
-         it, it must be a machine word :-) This probably assumes that
-         the word size of the Dwarf3 we're reading is the same size as
-         that on the machine.  gcc appears to give a size whereas icc9
-         doesn't. */
-      if (typeE.Te.TyPorR.isPtr)
-         typeE.Te.TyPorR.szB = sizeof(Word);
+      /* These three type kinds don't *have* to specify their size, in
+         which case we assume it's a machine word.  But if they do
+         specify it, it must be a machine word :-)  This probably
+         assumes that the word size of the Dwarf3 we're reading is the
+         same size as that on the machine.  gcc appears to give a size
+         whereas icc9 doesn't. */
+      typeE.Te.TyPorR.szB = sizeof(UWord);
       while (True) {
          DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
          DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
@@ -2200,7 +2241,7 @@ static void parse_type_DIE ( /*MOD*/XArr
          }
       }
       /* Do we have something that looks sane? */
-      if (typeE.Te.TyPorR.szB != sizeof(Word))
+      if (typeE.Te.TyPorR.szB != sizeof(UWord))
          goto bad_DIE;
       else
          goto acquire_Type;
@@ -2230,9 +2271,14 @@ static void parse_type_DIE ( /*MOD*/XArr
             typeE.Te.TyEnum.szB = cts;
          }
       }
+
+      if (!typeE.Te.TyEnum.name)
+         typeE.Te.TyEnum.name 
+            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
+                                 "<anon_enum_type>" );
+
       /* Do we have something that looks sane? */
-      if (typeE.Te.TyEnum.szB == 0 /* we must know the size */
-         /* But the name can be present, or not */)
+      if (typeE.Te.TyEnum.szB == 0 /* we must know the size */)
          goto bad_DIE;
       /* On't stack! */
       typestack_push( cc, parser, td3, &typeE, level );
@@ -3367,12 +3413,30 @@ void new_dwarf3_reader_wrk ( 
    while (True) {
       UWord   cu_start_offset, cu_offset_now;
       CUConst cc;
+      /* It may be that the stated size of this CU is larger than the
+         amount of stuff actually in it.  icc9 seems to generate CUs
+         thusly.  We use these variables to figure out if this is
+         indeed the case, and if so how many bytes we need to skip to
+         get to the start of the next CU.  Not skipping those bytes
+         causes us to misidentify the start of the next CU, and it all
+         goes badly wrong after that (not surprisingly). */
+      UWord cu_size_including_IniLen, cu_amount_used;
 
       /* It seems icc9 finishes the DIE info before debug_info_sz
          bytes have been used up.  So be flexible, and declare the
          sequence complete if there is not enough remaining bytes to
          hold even the smallest conceivable CU header.  (11 bytes I
          reckon). */
+      /* JRS 23Jan09: I suspect this is no longer necessary now that
+         the code below contains a 'while (cu_amount_used <
+         cu_size_including_IniLen ...'  style loop, which skips over
+         any leftover bytes at the end of a CU in the case where the
+         CU's stated size is larger than its actual size (as
+         determined by reading all its DIEs).  However, for prudence,
+         I'll leave the following test in place.  I can't see that a
+         CU header can be smaller than 11 bytes, so I don't think
+         there's any harm possible through the test -- it just adds
+         robustness. */
       Word avail = get_remaining_length_Cursor( &info );
       if (avail < 11) {
          if (avail > 0)
@@ -3408,6 +3472,8 @@ void new_dwarf3_reader_wrk ( 
       cc.debug_loc_sz     = debug_loc_sz;
       cc.debug_line_img   = debug_line_img;
       cc.debug_line_sz    = debug_line_sz;
+      cc.debug_info_img   = debug_info_img;
+      cc.debug_info_sz    = debug_info_sz;
       cc.cu_start_offset  = cu_start_offset;
       cc.di = di;
       /* The CU's svma can be deduced by looking at the AT_low_pc
@@ -3446,10 +3512,36 @@ void new_dwarf3_reader_wrk ( 
                 &info, td3, &cc, 0 );
 
       cu_offset_now = get_position_of_Cursor( &info );
+
+      if (0) VG_(printf)("Travelled: %lu  size %llu\n",
+                         cu_offset_now - cc.cu_start_offset,
+                         cc.unit_length + (cc.is_dw64 ? 12 : 4));
+
+      /* How big the CU claims it is .. */
+      cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
+      /* .. vs how big we have found it to be */
+      cu_amount_used = cu_offset_now - cc.cu_start_offset;
+
       if (1) TRACE_D3("offset now %ld, d-i-size %ld\n",
                       cu_offset_now, debug_info_sz);
       if (cu_offset_now > debug_info_sz)
          barf("toplevel DIEs beyond end of CU");
+
+      /* If the CU is bigger than it claims to be, we've got a serious
+         problem. */
+      if (cu_amount_used > cu_size_including_IniLen)
+         barf("CU's actual size appears to be larger than it claims it is");
+
+      /* If the CU is smaller than it claims to be, we need to skip some
+         bytes.  Loop updates cu_offset_new and cu_amount_used. */
+      while (cu_amount_used < cu_size_including_IniLen
+             && get_remaining_length_Cursor( &info ) > 0) {
+         if (0) VG_(printf)("SKIP\n");
+         (void)get_UChar( &info );
+         cu_offset_now = get_position_of_Cursor( &info );
+         cu_amount_used = cu_offset_now - cc.cu_start_offset;
+      }
+
       if (cu_offset_now == debug_info_sz)
          break;
 
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readdwarf.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readdwarf.c	2009-01-27 16:32:54.000000000 +0100
@@ -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"
@@ -2554,6 +2555,16 @@ static Int dwarfexpr_to_dag ( UnwindCont
                VG_(printf)("DW_OP_breg%d: %ld", reg, sw);
             break;
 
+         case DW_OP_reg0 ... DW_OP_reg31:
+            /* push: reg */
+            reg = (Int)opcode - (Int)DW_OP_reg0;
+            vg_assert(reg >= 0 && reg <= 31);
+            ix = ML_(CfiExpr_DwReg)( dst, reg );
+            PUSH(ix);
+            if (ddump_frames)
+               VG_(printf)("DW_OP_reg%d", reg);
+            break;
+
          case DW_OP_plus_uconst:
             uw = read_leb128U( &expr );
             PUSH( ML_(CfiExpr_Const)( dst, uw ) );
@@ -2573,6 +2584,15 @@ static Int dwarfexpr_to_dag ( UnwindCont
                VG_(printf)("DW_OP_const4s: %ld", sw);
             break;
 
+         case DW_OP_const1s:
+            /* push: 8-bit signed immediate */
+            sw = read_le_s_encoded_literal( expr, 1 );
+            expr += 1;
+            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_const1s: %ld", sw);
+            break;
+
          case DW_OP_minus:
             op = Cop_Sub; opname = "minus"; goto binop;
          case DW_OP_plus:
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readelf.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readelf.c	2009-01-27 16:32:54.000000000 +0100
@@ -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, Wor
    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 _
    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 _
                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 _
       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 _
    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 _
       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 _
               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 _
       /* 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 _
       /* 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 _
          }
       }
 
+      /* 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 _
             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 _
             }
          } 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 _
 
       /* 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 _
       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 _
       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 _
       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 _
       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 _
       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 _
       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 _
 
    }
 
-   /* 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);
 
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/readxcoff.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/readxcoff.c	2009-01-27 16:32:54.000000000 +0100
@@ -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 */
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/storage.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/storage.c	2009-01-27 16:32:54.000000000 +0100
@@ -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"
--- valgrind-3.4.0.vanilla/coregrind/m_debuginfo/tytypes.c	2009-01-02 19:40:41.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_debuginfo/tytypes.c	2009-01-27 16:32:54.000000000 +0100
@@ -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"
--- valgrind-3.4.0.vanilla/coregrind/m_machine.c	2009-01-02 19:40:44.000000000 +0100
+++ valgrind-3.4.1.SVN-9098-1883/coregrind/m_machine.c	2009-01-27 16:32:56.000000000 +0100
@@ -35,7 +35,8 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_machine.h"
 #include "pub_core_cpuid.h"
-#include "pub_core_libcsignal.h"   // for ppc32 messing with SIGILL
+#include "pub_core_libcsignal.h"   // for ppc32 messing with SIGILL
+#include "pub_core_debuglog.h"
 
 
 #define INSTR_PTR(regs)    ((regs).vex.VG_INSTR_PTR)