|
From: <sv...@va...> - 2005-05-01 23:50:12
|
Author: sewardj
Date: 2005-05-02 00:50:08 +0100 (Mon, 02 May 2005)
New Revision: 3586
Modified:
trunk/coregrind/vg_dwarf.c
Log:
Fix various other CFI-frame-unwind bits and pieces.
Modified: trunk/coregrind/vg_dwarf.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_dwarf.c 2005-05-01 20:24:06 UTC (rev 3585)
+++ trunk/coregrind/vg_dwarf.c 2005-05-01 23:50:08 UTC (rev 3586)
@@ -1047,12 +1047,14 @@
=20
/* Summarise ctx into si, if possible. Returns True if successful.
This is taken to be just after ctx's loc advances; hence the
- summary is up to but not including the current loc.
+ summary is up to but not including the current loc. This works
+ on both x86 and amd64.
*/
static Bool summarise_context( /*OUT*/CfiSI* si,
Addr loc_start,
UnwindContext* ctx )
{
+ Int why =3D 0;
initCfiSI(si);
=20
/* How to generate the CFA */
@@ -1064,6 +1066,7 @@
si->cfa_sprel =3D False;
si->cfa_off =3D ctx->cfa_offset;
} else {
+ why =3D 1;
goto failed;
}
=20
@@ -1072,7 +1075,7 @@
case RR_Undef: _how =3D CFIR_UNKNOWN; _off =3D 0; break; =
\
case RR_Same: _how =3D CFIR_SAME; _off =3D 0; break; =
\
case RR_CFAoff: _how =3D CFIR_MEMCFAREL; _off =3D _ctxreg.coff; br=
eak; \
- default: goto failed; /* otherwise give up */ =
\
+ default: { why =3D 2; goto failed; } /* otherwise give up *=
/ \
}
=20
SUMMARISE_HOW(si->ra_how, si->ra_off, ctx->reg[RA_COL] );
@@ -1080,23 +1083,26 @@
=20
# undef SUMMARISE_HOW
=20
- /* on x86, it seems the old %esp value before the call is always
- the same as the CFA. Therefore ... */
+ /* on x86/amd64, it seems the old %{e,r}sp value before the call is
+ always the same as the CFA. Therefore ... */
si->sp_how =3D CFIR_CFAREL;
si->sp_off =3D 0;
=20
- /* also, gcc says "Undef" for %ebp when it is unchanged. So .. */
+ /* also, gcc says "Undef" for %{e,r}bp when it is unchanged. So
+ .. */
if (ctx->reg[FP_COL].tag =3D=3D RR_Undef)
si->fp_how =3D CFIR_SAME;
=20
/* knock out some obviously stupid cases */
- if (si->ra_how =3D=3D CFIR_SAME) goto failed;
+ if (si->ra_how =3D=3D CFIR_SAME)=20
+ { why =3D 3; goto failed; }
=20
/* bogus looking range? Note, we require that the difference is
representable in 32 bits. */
- if (loc_start >=3D ctx->loc) goto failed;
+ if (loc_start >=3D ctx->loc)=20
+ { why =3D 4; goto failed; }
if (ctx->loc - loc_start > 10000000 /* let's say */)
- goto failed;
+ { why =3D 5; goto failed; }
=20
si->base =3D loc_start + ctx->initloc;
si->len =3D (UInt)(ctx->loc - loc_start);
@@ -1105,7 +1111,7 @@
=20
failed:
VG_(printf)("summarise_context(loc_start =3D %p)"
- ": cannot summarise:\n ", loc_start);
+ ": cannot summarise(why=3D%d):\n ", loc_start, why);
ppUnwindContext(ctx);
return False;
}
@@ -1223,7 +1229,7 @@
return data[0];
}
=20
-static UChar default_address_encoding ()
+static UChar default_Addr_encoding ()
{
switch (sizeof(Addr)) {
case 4: return DW_EH_PE_udata4;
@@ -1232,7 +1238,7 @@
}
}
=20
-static UInt size_of_encoded_address ( UChar encoding )
+static UInt size_of_encoded_Addr ( UChar encoding )
{
if (encoding =3D=3D DW_EH_PE_omit)
return 0;
@@ -1246,8 +1252,8 @@
}
}
=20
-static Addr read_encoded_address ( UChar* data, UChar encoding, Int *nby=
tes,
- UChar* ehframe, Addr ehframe_addr )
+static Addr read_encoded_Addr ( UChar* data, UChar encoding, Int *nbytes=
,
+ UChar* ehframe, Addr ehframe_addr )
{
Addr base;
Int offset;
@@ -1287,7 +1293,7 @@
}
=20
if ((encoding & 0x07) =3D=3D 0x00)
- encoding |=3D default_address_encoding();
+ encoding |=3D default_Addr_encoding();
=20
switch (encoding & 0x0f) {
case DW_EH_PE_udata2:
@@ -1318,7 +1324,8 @@
Returns 0 if the instruction could not be executed.=20
*/
static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,=20
- UChar* instr )
+ UChar* instr,
+ UnwindContext* restore_ctx )
{
Int off, reg, nleb;
UInt delta;
@@ -1346,8 +1353,12 @@
}
=20
if (hi2 =3D=3D DW_CFA_restore) {
- vg_assert(0);
- VG_(printf)("DW_CFA_restore(%d)\n", (Int)lo6);
+ reg =3D (Int)lo6;
+ if (reg < 0 || reg >=3D N_CFI_REGS)=20
+ return 0; /* fail */
+ if (restore_ctx =3D=3D NULL)
+ return 0; /* fail */
+ ctx->reg[reg] =3D restore_ctx->reg[reg];
return i;
}
=20
@@ -1536,7 +1547,8 @@
static=20
Bool run_CF_instructions ( SegInfo* si,
UnwindContext* ctx, UChar* instrs, Int ilen,
- UWord fde_arange )
+ UWord fde_arange,
+ UnwindContext* restore_ctx )
{
CfiSI cfisi;
=20
@@ -1548,7 +1560,7 @@
loc_prev =3D ctx->loc;
if (i >=3D ilen) break;
if (0) (void)show_CF_instruction( &instrs[i] );
- j =3D run_CF_instruction( ctx, &instrs[i] );
+ j =3D run_CF_instruction( ctx, &instrs[i], restore_ctx );
if (j =3D=3D 0)
return False; /* execution failed */
i +=3D j;
@@ -1573,7 +1585,7 @@
void VG_(read_callframe_info_dwarf2)=20
( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz, Addr ehfra=
me_addr )
{
- UnwindContext ctx;
+ UnwindContext ctx, restore_ctx;
Int nbytes;
HChar* how =3D NULL;
Int cie_codeaf =3D 0;
@@ -1586,7 +1598,7 @@
UChar* cie_instrs =3D NULL;
Int cie_ilen =3D 0;
Bool saw_z_augmentation =3D False;
- UChar address_encoding =3D default_address_encoding();
+ UChar address_encoding =3D default_Addr_encoding();
=20
if (VG_(clo_trace_cfi)) {
VG_(printf)("\n-----------------------------------------------\n")=
;
@@ -1698,7 +1710,8 @@
cie_augmentation++;
break;
case 'P':
- data +=3D size_of_encoded_address(address_encoding);
+ data +=3D size_of_encoded_Addr( read_UChar(data) );
+ data++;
cie_augmentation++;
break;
default:
@@ -1749,15 +1762,15 @@
}
=20
Addr fde_initloc=20
- =3D read_encoded_address(data, address_encoding,
- &nbytes, ehframe, ehframe_addr);
+ =3D read_encoded_Addr(data, address_encoding,
+ &nbytes, ehframe, ehframe_addr);
data +=3D nbytes;
if (VG_(clo_trace_cfi))=20
VG_(printf)("fde.initloc =3D %p\n", (void*)fde_initloc);
=20
UWord fde_arange=20
- =3D read_encoded_address(data, address_encoding & 0xf,
- &nbytes, ehframe, ehframe_addr);
+ =3D read_encoded_Addr(data, address_encoding & 0xf,
+ &nbytes, ehframe, ehframe_addr);
data +=3D nbytes;
if (VG_(clo_trace_cfi))=20
VG_(printf)("fde.arangec =3D %p\n", (void*)fde_arange);
@@ -1769,8 +1782,10 @@
=20
UChar* fde_instrs =3D data;
Int fde_ilen =3D ciefde_start + ciefde_len + sizeof(UInt) =
- data;
- if (VG_(clo_trace_cfi)) VG_(printf)("fde.instrs =3D %p\n",=
fde_instrs);
- if (VG_(clo_trace_cfi)) VG_(printf)("fde.ilen =3D %d\n",=
(Int)fde_ilen);
+ if (VG_(clo_trace_cfi)) {
+ VG_(printf)("fde.instrs =3D %p\n", fde_instrs);
+ VG_(printf)("fde.ilen =3D %d\n", (Int)fde_ilen);
+ }
=20
if (fde_ilen < 0 || fde_ilen > ehframe_sz) {
how =3D "implausible # fde insns";
@@ -1786,9 +1801,17 @@
ctx.code_a_f =3D cie_codeaf;
ctx.data_a_f =3D cie_dataaf;
ctx.initloc =3D fde_initloc;
- ok =3D run_CF_instructions(NULL, &ctx, cie_instrs, cie_ilen, 0);
- if (ok)
- ok =3D run_CF_instructions(si, &ctx, fde_instrs, fde_ilen, fde_aran=
ge);
+
+ initUnwindContext(&restore_ctx);
+
+ ok =3D run_CF_instructions(
+ NULL, &ctx, cie_instrs, cie_ilen, 0, NULL);
+ if (ok) {
+ restore_ctx =3D ctx;
+ ok =3D run_CF_instructions(
+ si, &ctx, fde_instrs, fde_ilen, fde_arange,=20
+ &restore_ctx);
+ }
}
}
=20
|