]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Get DWARF CFI handling going on amd64 systems. This also required getting
authorTom Hughes <tom@compton.nu>
Sun, 1 May 2005 15:14:01 +0000 (15:14 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 1 May 2005 15:14:01 +0000 (15:14 +0000)
handling of augmentation strings right.

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

coregrind/vg_dwarf.c
coregrind/vg_symtab2.c
coregrind/vg_symtab2.h

index 2eb96e73c0fe5924373448144ba2e5125c590aa7..a47eaf9a4ee9deb67a26c8c29c24c4a3857b5166 100644 (file)
@@ -909,6 +909,15 @@ static void initCfiSI ( CfiSI* si )
 
       8 is the return address (EIP) */
 
+#if defined(__x86__)
+#define FP_COL 5
+#define SP_COL 4
+#define RA_COL 8
+#elif defined(__amd64__)
+#define FP_COL 6
+#define SP_COL 7
+#define RA_COL 16
+#endif
 
 /* the number of regs we are prepared to unwind */
 #define N_CFI_REGS 20
@@ -944,6 +953,27 @@ enum dwarf_cfa_secondary_ops
     DW_CFA_hi_user          = 0x3f
   };
 
+#define DW_EH_PE_absptr                0x00
+#define DW_EH_PE_omit          0xff
+
+#define DW_EH_PE_uleb128       0x01
+#define DW_EH_PE_udata2                0x02
+#define DW_EH_PE_udata4                0x03
+#define DW_EH_PE_udata8                0x04
+#define DW_EH_PE_sleb128       0x09
+#define DW_EH_PE_sdata2                0x0A
+#define DW_EH_PE_sdata4                0x0B
+#define DW_EH_PE_sdata8                0x0C
+#define DW_EH_PE_signed                0x08
+
+#define DW_EH_PE_pcrel         0x10
+#define DW_EH_PE_textrel       0x20
+#define DW_EH_PE_datarel       0x30
+#define DW_EH_PE_funcrel       0x40
+#define DW_EH_PE_aligned       0x50
+
+#define DW_EH_PE_indirect      0x80
+
 
 typedef
    struct {
@@ -1018,18 +1048,18 @@ static void ppUnwindContext ( UnwindContext* ctx )
    This is taken to be just after ctx's loc advances; hence the
    summary is up to but not including the current loc.
 */
-static Bool summarise_context_x86 ( /*OUT*/CfiSI* si,
-                                    Addr loc_start,
-                                   UnwindContext* ctx )
+static Bool summarise_context( /*OUT*/CfiSI* si,
+                               Addr loc_start,
+                              UnwindContext* ctx )
 {
    initCfiSI(si);
 
    /* How to generate the CFA */
-   if (ctx->cfa_reg == 4 /* ESP */) {
+   if (ctx->cfa_reg == SP_COL) {
       si->cfa_sprel = True;
       si->cfa_off   = ctx->cfa_offset;
    } else
-   if (ctx->cfa_reg == 5 /* EBP */) {
+   if (ctx->cfa_reg == FP_COL) {
       si->cfa_sprel = False;
       si->cfa_off   = ctx->cfa_offset;
    } else {
@@ -1044,8 +1074,8 @@ static Bool summarise_context_x86 ( /*OUT*/CfiSI* si,
       default:        goto failed; /* otherwise give up */               \
    }
 
-   SUMMARISE_HOW(si->ra_how, si->ra_off, ctx->reg[8 /* Return address */] );
-   SUMMARISE_HOW(si->fp_how, si->fp_off, ctx->reg[5 /* EBP */] );
+   SUMMARISE_HOW(si->ra_how, si->ra_off, ctx->reg[RA_COL] );
+   SUMMARISE_HOW(si->fp_how, si->fp_off, ctx->reg[FP_COL] );
 
 #  undef SUMMARISE_HOW
 
@@ -1055,7 +1085,7 @@ static Bool summarise_context_x86 ( /*OUT*/CfiSI* si,
    si->sp_off = 0;
 
    /* also, gcc says "Undef" for %ebp when it is unchanged.  So .. */
-   if (ctx->reg[5 /* EBP */].tag == RR_Undef)
+   if (ctx->reg[FP_COL].tag == RR_Undef)
       si->fp_how = CFIR_SAME;
 
    /* knock out some obviously stupid cases */
@@ -1073,30 +1103,30 @@ static Bool summarise_context_x86 ( /*OUT*/CfiSI* si,
    return True;
 
   failed:
-   VG_(printf)("summarise_context_x86(loc_start = %p)"
+   VG_(printf)("summarise_context(loc_start = %p)"
                ": cannot summarise:\n   ", loc_start);
    ppUnwindContext(ctx);
    return False;
 }
 
-static void ppUnwindContext_x86_summary ( UnwindContext* ctx )
+static void ppUnwindContext_summary ( UnwindContext* ctx )
 {
    VG_(printf)("0x%llx-1: ", (ULong)ctx->loc);
 
-   if (ctx->cfa_reg == 4 /* ESP */) {
-      VG_(printf)("SP/CFA=%d+%%esp   ", ctx->cfa_offset);
+   if (ctx->cfa_reg == SP_COL) {
+      VG_(printf)("SP/CFA=%d+SP   ", ctx->cfa_offset);
    } else
-   if (ctx->cfa_reg == 5 /* EBP */) {
-      VG_(printf)("SP/CFA=%d+%%ebp   ", ctx->cfa_offset);
+   if (ctx->cfa_reg == FP_COL) {
+      VG_(printf)("SP/CFA=%d+FP   ", ctx->cfa_offset);
    } else {
       VG_(printf)("SP/CFA=unknown  ", ctx->cfa_offset);
    }
 
    VG_(printf)("RA=");
-   ppRegRule( &ctx->reg[8 /* Return address */] );
+   ppRegRule( &ctx->reg[RA_COL] );
 
    VG_(printf)("FP=");
-   ppRegRule( &ctx->reg[5 /* EBP */] );
+   ppRegRule( &ctx->reg[FP_COL] );
    VG_(printf)("\n");
 }
 
@@ -1108,6 +1138,41 @@ static inline Bool host_is_little_endian ( void )
 }
 
 
+static Short read_Short ( UChar* data )
+{
+   vg_assert(host_is_little_endian());
+   Short r = 0;
+   r = data[0] 
+       | ( ((UInt)data[1]) << 8 );
+   return r;
+}
+
+static Int read_Int ( UChar* data )
+{
+   vg_assert(host_is_little_endian());
+   Int r = 0;
+   r = data[0] 
+       | ( ((UInt)data[1]) << 8 ) 
+       | ( ((UInt)data[2]) << 16 ) 
+       | ( ((UInt)data[3]) << 24 );
+   return r;
+}
+
+static Long read_Long ( UChar* data )
+{
+   vg_assert(host_is_little_endian());
+   Long r = 0;
+   r = data[0] 
+       | ( ((ULong)data[1]) << 8 ) 
+       | ( ((ULong)data[2]) << 16 ) 
+       | ( ((ULong)data[3]) << 24 )
+       | ( ((ULong)data[4]) << 32 ) 
+       | ( ((ULong)data[5]) << 40 ) 
+       | ( ((ULong)data[6]) << 48 ) 
+       | ( ((ULong)data[7]) << 56 );
+   return r;
+}
+
 static UShort read_UShort ( UChar* data )
 {
    vg_assert(host_is_little_endian());
@@ -1128,10 +1193,27 @@ static UInt read_UInt ( UChar* data )
    return r;
 }
 
+static ULong read_ULong ( UChar* data )
+{
+   vg_assert(host_is_little_endian());
+   ULong r = 0;
+   r = data[0] 
+       | ( ((ULong)data[1]) << 8 ) 
+       | ( ((ULong)data[2]) << 16 ) 
+       | ( ((ULong)data[3]) << 24 )
+       | ( ((ULong)data[4]) << 32 ) 
+       | ( ((ULong)data[5]) << 40 ) 
+       | ( ((ULong)data[6]) << 48 ) 
+       | ( ((ULong)data[7]) << 56 );
+   return r;
+}
+
 static Addr read_Addr ( UChar* data )
 {
   if (sizeof(Addr) == 4)
     return read_UInt(data);
+  else if (sizeof(Addr) == 8)
+    return read_ULong(data);
   vg_assert(0);
 }
 
@@ -1140,6 +1222,96 @@ static UChar read_UChar ( UChar* data )
    return data[0];
 }
 
+static UChar default_address_encoding ()
+{
+   switch (sizeof(Addr)) {
+      case 4: return DW_EH_PE_udata4;
+      case 8: return DW_EH_PE_udata8;
+      default: vg_assert(0);
+   }
+}
+
+static UInt size_of_encoded_address ( UChar encoding )
+{
+   if (encoding == DW_EH_PE_omit)
+      return 0;
+
+   switch (encoding & 0x07) {
+      case DW_EH_PE_absptr: return sizeof(Addr);
+      case DW_EH_PE_udata2: return sizeof(UShort);
+      case DW_EH_PE_udata4: return sizeof(UInt);
+      case DW_EH_PE_udata8: return sizeof(ULong);
+      default: vg_assert(0);
+   }
+}
+
+static Addr read_encoded_address ( UChar* data, UChar encoding, Int *nbytes,
+                                   UChar* ehframe, Addr ehframe_addr )
+{
+   Addr base;
+   Int offset;
+
+   vg_assert((encoding & DW_EH_PE_indirect) == 0);
+
+   *nbytes = 0;
+
+   switch (encoding & 0x70) {
+      case DW_EH_PE_absptr:
+         base = 0;
+         break;
+      case DW_EH_PE_pcrel:
+         base = ehframe_addr + ( data - ehframe );
+         break;
+      case DW_EH_PE_datarel:
+         vg_assert(0);
+         base = /* data base address */ 0;
+         break;
+      case DW_EH_PE_textrel:
+         vg_assert(0);
+         base = /* text base address */ 0;
+         break;
+      case DW_EH_PE_funcrel:
+         base = 0;
+         break;
+      case DW_EH_PE_aligned:
+         base = 0;
+         offset = data - ehframe;
+         if ((offset % sizeof(Addr)) != 0) {
+            *nbytes = sizeof(Addr) - (offset % sizeof(Addr));
+            data += *nbytes;
+         }
+         break;
+      default:
+         vg_assert(0);
+   }
+
+   if ((encoding & 0x0f) == 0x00)
+      encoding |= default_address_encoding();
+
+   switch (encoding & 0x0f) {
+      case DW_EH_PE_udata2:
+         *nbytes += sizeof(UShort);
+         return base + read_UShort(data);
+      case DW_EH_PE_udata4:
+         *nbytes += sizeof(UInt);
+         return base + read_UInt(data);
+      case DW_EH_PE_udata8:
+         *nbytes += sizeof(ULong);
+         return base + read_ULong(data);
+      case DW_EH_PE_sdata2:
+         *nbytes += sizeof(Short);
+         return base + read_Short(data);
+      case DW_EH_PE_sdata4:
+         *nbytes += sizeof(Int);
+         return base + read_Int(data);
+      case DW_EH_PE_sdata8:
+         *nbytes += sizeof(Long);
+         return base + read_Long(data);
+      default:
+         vg_assert(0);
+   }
+}
+
 
 /* Run a CFI instruction, and also return its length.
    Returns 0 if the instruction could not be executed. 
@@ -1183,10 +1355,20 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
    switch (lo6) {
       case DW_CFA_nop: 
          break;
+      case DW_CFA_set_loc:
+         ctx->loc = read_Addr(&instr[i]) - ctx->initloc; i+= sizeof(Addr);
+         break;
       case DW_CFA_advance_loc1:
-         vg_assert(0);
          delta = (UInt)read_UChar(&instr[i]); i+= sizeof(UChar);
-         VG_(printf)("DW_CFA_advance_loc1(%d)\n", delta); 
+         ctx->loc += delta;
+         break;
+      case DW_CFA_advance_loc2:
+         delta = (UInt)read_UShort(&instr[i]); i+= sizeof(UShort);
+         ctx->loc += delta;
+         break;
+      case DW_CFA_advance_loc4:
+         delta = (UInt)read_UInt(&instr[i]); i+= sizeof(UInt);
+         ctx->loc += delta;
          break;
 
       case DW_CFA_def_cfa:
@@ -1222,8 +1404,8 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
          break;
       }
       default: 
-         vg_assert(0);
-         VG_(printf)("0:%d\n", (Int)lo6); 
+         VG_(printf)("Unhandled CFI instruction 0:%d\n", (Int)lo6); 
+         i = 0;
          break;
    }
 
@@ -1236,11 +1418,17 @@ static Int show_CF_instruction ( UChar* instr )
 {
    UInt  delta;
    Int   off, reg, nleb;
+   Addr  loc;
    Int   i   = 0;
    UChar hi2 = (instr[i] >> 6) & 3;
    UChar lo6 = instr[i] & 0x3F;
    i++;
 
+   if (0) VG_(printf)("raw:%x/%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
+                      hi2, lo6,
+                      instr[i+0], instr[i+1], instr[i+2], instr[i+3],
+                      instr[i+4], instr[i+5], instr[i+6], instr[i+7] );
+   
    if (hi2 == DW_CFA_advance_loc) {
       VG_(printf)("DW_CFA_advance_loc(%d)\n", (Int)lo6);
       return i;
@@ -1266,11 +1454,26 @@ static Int show_CF_instruction ( UChar* instr )
          VG_(printf)("DW_CFA_nop\n"); 
          break;
 
+      case DW_CFA_set_loc:
+         loc = read_Addr(&instr[i]); i+= sizeof(Addr);
+         VG_(printf)("DW_CFA_set_loc(%p)\n", loc); 
+         break;
+
       case DW_CFA_advance_loc1:
          delta = (UInt)read_UChar(&instr[i]); i+= sizeof(UChar);
          VG_(printf)("DW_CFA_advance_loc1(%d)\n", delta); 
          break;
 
+      case DW_CFA_advance_loc2:
+         delta = (UInt)read_UShort(&instr[i]); i+= sizeof(UShort);
+         VG_(printf)("DW_CFA_advance_loc2(%d)\n", delta); 
+         break;
+
+      case DW_CFA_advance_loc4:
+         delta = (UInt)read_UInt(&instr[i]); i+= sizeof(UInt);
+         VG_(printf)("DW_CFA_advance_loc4(%d)\n", delta); 
+         break;
+
       case DW_CFA_def_cfa:
          reg = read_leb128( &instr[i], &nleb, 0 );
          i += nleb;
@@ -1328,7 +1531,7 @@ Bool run_CF_instructions ( SegInfo* si,
    Int j, i = 0;
    Addr loc_prev;
    if (0) ppUnwindContext(ctx);
-   if (0) ppUnwindContext_x86_summary(ctx);
+   if (0) ppUnwindContext_summary(ctx);
    while (True) {
       loc_prev = ctx->loc;
       if (i >= ilen) break;
@@ -1339,7 +1542,7 @@ Bool run_CF_instructions ( SegInfo* si,
       i += j;
       if (0) ppUnwindContext(ctx);
       if (loc_prev != ctx->loc && si) {
-         summarise_context_x86 ( &cfisi, loc_prev, ctx );
+         summarise_context ( &cfisi, loc_prev, ctx );
          VG_(addCfiSI)(si, &cfisi);
       }
    }
@@ -1347,7 +1550,7 @@ Bool run_CF_instructions ( SegInfo* si,
       loc_prev = ctx->loc;
       ctx->loc = fde_arange;
       if (si) {
-         summarise_context_x86 ( &cfisi, loc_prev, ctx );
+         summarise_context ( &cfisi, loc_prev, ctx );
          VG_(addCfiSI)(si, &cfisi);
       }
    }
@@ -1356,7 +1559,7 @@ Bool run_CF_instructions ( SegInfo* si,
 
 
 void VG_(read_callframe_info_dwarf2) 
-        ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz )
+        ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz, Addr ehframe_addr )
 {
    UnwindContext ctx;
    Int nbytes;
@@ -1374,6 +1577,8 @@ void VG_(read_callframe_info_dwarf2)
 
    UChar* cie_instrs = NULL;
    Int cie_ilen = 0;
+   Bool saw_z_augmentation = False;
+   UChar address_encoding = default_address_encoding();
 
    /* Loop over CIEs/FDEs */
 
@@ -1425,9 +1630,9 @@ void VG_(read_callframe_info_dwarf2)
          data += 1 + VG_(strlen)(cie_augmentation);
          if (0) VG_(printf)("cie.augment     = \"%s\"\n", cie_augmentation);
 
-         if (0 != VG_(strcmp)(cie_augmentation, "")) {
-            how = "non-NULL cie.augmentation";
-            goto bad;
+         if (cie_augmentation[0] == 'e' && cie_augmentation[1] == 'h') {
+            data += sizeof(Addr);
+            cie_augmentation += 2;
          }
 
          cie_codeaf = read_leb128( data, &nbytes, 0);
@@ -1441,9 +1646,47 @@ void VG_(read_callframe_info_dwarf2)
          UChar cie_rareg = read_UChar(data); data += sizeof(UChar);
          if (0) VG_(printf)("cie.ra_reg      = %d\n", (Int)cie_rareg);
 
+         saw_z_augmentation = *cie_augmentation == 'z';
+         if (saw_z_augmentation) {
+            UInt length = read_leb128( data, &nbytes, 0);
+            data += nbytes;
+            cie_instrs = data + length;
+            cie_augmentation++;
+         } else {
+            cie_instrs = NULL;
+         }
+
+         while (*cie_augmentation) {
+            switch (*cie_augmentation) {
+               case 'L':
+                  data++;
+                  cie_augmentation++;
+                  break;
+               case 'R':
+                  address_encoding = read_UChar(data); data += sizeof(UChar);
+                  cie_augmentation++;
+                  break;
+               case 'P':
+                  data += size_of_encoded_address(address_encoding);
+                  cie_augmentation++;
+                  break;
+               default:
+                  if (cie_instrs == NULL) {
+                     how = "unhandled cie.augmentation";
+                     goto bad;
+                  }
+                  data = cie_instrs;
+                  goto done_augmentation;
+            }
+         }
+
+        done_augmentation:
+
+         if (0) VG_(printf)("cie.encoding    = 0x%x\n", address_encoding);
+
          cie_instrs = data;
          cie_ilen   = ciefde_start + ciefde_len + sizeof(UInt) - data;
-         if (0) VG_(printf)("cie.instrs      = %p\n", (Int)cie_instrs);
+         if (0) VG_(printf)("cie.instrs      = %p\n", cie_instrs);
          if (0) VG_(printf)("cie.ilen        = %d\n", (Int)cie_ilen);
 
          if (cie_ilen < 0 || cie_ilen > ehframe_sz) {
@@ -1470,15 +1713,24 @@ void VG_(read_callframe_info_dwarf2)
             goto bad;
          }
 
-         Addr fde_initloc = read_Addr(data); data += sizeof(Addr);
+         Addr fde_initloc = read_encoded_address(data, address_encoding,
+                                                 &nbytes, ehframe, ehframe_addr);
+         data += nbytes;
          if (0) VG_(printf)("fde.initloc     = %p\n", (void*)fde_initloc);
 
-         UWord fde_arange = read_Addr(data); data += sizeof(Addr);
+         UWord fde_arange = read_encoded_address(data, address_encoding & 0xf,
+                                                 &nbytes, ehframe, ehframe_addr);
+         data += nbytes;
          if (0) VG_(printf)("fde.arangec     = %p\n", (void*)fde_arange);
 
+         if (saw_z_augmentation) {
+            data += read_leb128( data, &nbytes, 0);
+            data += nbytes;
+         }
+
          UChar* fde_instrs = data;
          Int    fde_ilen   = ciefde_start + ciefde_len + sizeof(UInt) - data;
-         if (0) VG_(printf)("fde.instrs      = %p\n", (Int)fde_instrs);
+         if (0) VG_(printf)("fde.instrs      = %p\n", fde_instrs);
          if (0) VG_(printf)("fde.ilen        = %d\n", (Int)fde_ilen);
 
          if (fde_ilen < 0 || fde_ilen > ehframe_sz) {
index 3270c8091884347c9a09a2b1f2993c6ec0366748..88613e41a8f5010857326b9709345722aab8c11e 100644 (file)
@@ -1505,11 +1505,15 @@ Bool read_lib_symbols ( SegInfo* si )
       UInt       dwarf1l_sz      = 0;
       UInt       ehframe_sz      = 0;
 
+      /* Section virtual addresses */
+      Addr       dummy_addr      = 0;
+      Addr       ehframe_addr    = 0;
+
       Bool       has_debuginfo = False;
 
       /* Find all interesting sections */
       for (i = 0; i < ehdr->e_shnum; i++) {
-#        define FIND(sec_name, sec_data, sec_size, in_exec, type) \
+#        define FIND(sec_name, sec_data, sec_size, sec_addr, in_exec, type) \
          if (0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
             if (0 != sec_data) \
                VG_(core_panic)("repeated section!\n"); \
@@ -1518,6 +1522,7 @@ Bool read_lib_symbols ( SegInfo* si )
             else \
                sec_data = (type)(oimage + shdr[i].sh_offset); \
             sec_size = shdr[i].sh_size; \
+            sec_addr = si->offset + shdr[i].sh_addr; \
             TRACE_SYMTAB( "%18s: %p .. %p\n", \
                           sec_name, sec_data, sec_data + sec_size - 1); \
             if ( shdr[i].sh_offset + sec_size > n_oimage ) { \
@@ -1528,22 +1533,22 @@ Bool read_lib_symbols ( SegInfo* si )
 
          /* Nb: must find where .got and .plt sections will be in the
           * executable image, not in the object image transiently loaded. */
-              FIND(".dynsym",       o_dynsym,     o_dynsym_sz,   0, ElfXX_Sym*)
-         else FIND(".dynstr",       o_dynstr,     o_dynstr_sz,   0, UChar*)
-         else FIND(".symtab",       o_symtab,     o_symtab_sz,   0, ElfXX_Sym*)
-         else FIND(".strtab",       o_strtab,     o_strtab_sz,   0, UChar*)
+              FIND(".dynsym",       o_dynsym,     o_dynsym_sz,   dummy_addr,   0, ElfXX_Sym*)
+         else FIND(".dynstr",       o_dynstr,     o_dynstr_sz,   dummy_addr,   0, UChar*)
+         else FIND(".symtab",       o_symtab,     o_symtab_sz,   dummy_addr,   0, ElfXX_Sym*)
+         else FIND(".strtab",       o_strtab,     o_strtab_sz,   dummy_addr,   0, UChar*)
 
-         else FIND(".gnu_debuglink", debuglink,   debuglink_sz,  0, Char*)
+         else FIND(".gnu_debuglink", debuglink,   debuglink_sz,  dummy_addr,   0, Char*)
 
-         else FIND(".stab",         stab,         stab_sz,       0, UChar*)
-         else FIND(".stabstr",      stabstr,      stabstr_sz,    0, UChar*)
-         else FIND(".debug_line",   debug_line,   debug_line_sz, 0, UChar*)
-         else FIND(".debug",        dwarf1d,      dwarf1d_sz,    0, UChar*)
-         else FIND(".line",         dwarf1l,      dwarf1l_sz,    0, UChar*)
-         else FIND(".eh_frame",     ehframe,      ehframe_sz,    0, UChar*)
+         else FIND(".stab",         stab,         stab_sz,       dummy_addr,   0, UChar*)
+         else FIND(".stabstr",      stabstr,      stabstr_sz,    dummy_addr,   0, UChar*)
+         else FIND(".debug_line",   debug_line,   debug_line_sz, dummy_addr,   0, UChar*)
+         else FIND(".debug",        dwarf1d,      dwarf1d_sz,    dummy_addr,   0, UChar*)
+         else FIND(".line",         dwarf1l,      dwarf1l_sz,    dummy_addr,   0, UChar*)
+         else FIND(".eh_frame",     ehframe,      ehframe_sz,    ehframe_addr, 0, UChar*)
 
-         else FIND(".got",         si->got_start, si->got_size,  1, Addr)
-         else FIND(".plt",         si->plt_start, si->plt_size,  1, Addr)
+         else FIND(".got",         si->got_start, si->got_size,  dummy_addr,   1, Addr)
+         else FIND(".plt",         si->plt_start, si->plt_size,  dummy_addr,   1, Addr)
 
 #        undef FIND
          
@@ -1615,7 +1620,7 @@ Bool read_lib_symbols ( SegInfo* si )
 
       /* Read .eh_frame (call-frame-info) if any */
       if (ehframe && ehframe_sz > 4) {
-         VG_(read_callframe_info_dwarf2) ( si, ehframe, ehframe_sz );
+         VG_(read_callframe_info_dwarf2) ( si, ehframe, ehframe_sz, ehframe_addr );
       }
 
       /* Read the stabs and/or dwarf2 debug information, if any. */
index 81bac30ce92e5c23e4782458820f74ca498ae285..f1f141c0b66f9165f3cbb5b6f76744def01c4007 100644 (file)
@@ -255,7 +255,7 @@ void VG_(read_debuginfo_dwarf1) ( SegInfo* si,
    CFI reader
    -------------------- */
 void VG_(read_callframe_info_dwarf2) 
-    ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz );
+    ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz, Addr ehframe_addr );
 
 
 #endif /* _VG_SYMTYPE_H */