|
From: <sv...@va...> - 2005-05-03 16:05:05
|
Author: sewardj
Date: 2005-05-03 17:05:00 +0100 (Tue, 03 May 2005)
New Revision: 3604
Modified:
trunk/coregrind/vg_dwarf.c
trunk/coregrind/vg_symtab2.c
Log:
* Clean up the DWARF2 CFI reader a bit
* Check that cie.ra_reg that shows up matches the RA_COL we assume
* Improve debug printing a bit
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-03 15:23:00 UTC (rev 3603)
+++ trunk/coregrind/vg_dwarf.c 2005-05-03 16:05:00 UTC (rev 3604)
@@ -829,6 +829,42 @@
/*--- Read call-frame info from an .eh_frame section ---*/
/*------------------------------------------------------------*/
=20
+/* Useful info ..
+
+ In general:
+ gdb-6.3/gdb/dwarf2-frame.c
+
+ gdb-6.3/gdb/i386-tdep.c:
+
+ DWARF2/GCC uses the stack address *before* the function call as a
+ frame's CFA. [jrs: I presume this means %esp before the call as
+ the CFA].=20
+
+ JRS: on amd64, the dwarf register numbering is, as per
+ gdb-6.3/gdb/tdep-amd64.c and also amd64-abi-0.95.pdf:
+
+ 0 1 2 3 4 5 6 7
+ RAX RDX RCX RBX RSI RDI RBP RSP
+
+ 8 ... 15
+ R8 ... R15
+
+ 16 is the return address (RIP)
+
+ This is pretty strange given this not the encoding scheme for
+ registers used in amd64 code.
+
+ On x86 I cannot find any documentation. It _appears_ to be the
+ actual instruction encoding, viz:
+
+ 0 1 2 3 4 5 6 7
+ EAX ECX EDX EBX ESP EBP ESI EDI
+
+ 8 is the return address (EIP) */
+
+
+/* ------------ Deal with summary-info records ------------ */
+
void VG_(ppCfiSI) ( CfiSI* si )
{
# define SHOW_HOW(_how, _off) \
@@ -879,36 +915,8 @@
}
=20
=20
-/* Useful info ..
+/* --------------- Decls --------------- */
=20
- gdb-6.3/gdb/i386-tdep.c:
-
- DWARF2/GCC uses the stack address *before* the function call as a
- frame's CFA. [jrs: I presume this means %esp before the call as
- the CFA].=20
-
- JRS: on amd64, the dwarf register numbering is, as per
- gdb-6.3/gdb/tdep-amd64.c and also amd64-abi-0.95.pdf:
-
- 0 1 2 3 4 5 6 7
- RAX RDX RCX RBX RSI RDI RBP RSP
-
- 8 ... 15
- R8 ... R15
-
- 16 is the return address (RIP)
-
- This is pretty strange given this not the encoding scheme for
- registers used in amd64 code.
-
- On x86 I cannot find any documentation. It _appears_ to be the
- actual instruction encoding, viz:
-
- 0 1 2 3 4 5 6 7
- EAX ECX EDX EBX ESP EBP ESI EDI
-
- 8 is the return address (EIP) */
-
#if defined(VGP_x86_linux)
#define FP_COL 5
#define SP_COL 4
@@ -976,10 +984,16 @@
#define DW_EH_PE_indirect 0x80
=20
=20
+/* RegRule and UnwindContext are used temporarily to do the unwinding.
+ The result is then summarised into a CfiSI, if possible. */
+
typedef
struct {
enum { RR_Undef, RR_Same, RR_CFAoff, RR_Reg, RR_Arch } tag;
=20
+ /* Note, .coff and .reg are never both in use. Therefore could
+ merge them into one. */
+
/* CFA offset if tag=3D=3DRR_CFAoff */
Int coff;
=20
@@ -988,6 +1002,19 @@
}
RegRule;
=20
+static void ppRegRule ( RegRule* reg )
+{
+ switch (reg->tag) {
+ case RR_Undef: VG_(printf)("u "); break;
+ case RR_Same: VG_(printf)("s "); break;
+ case RR_CFAoff: VG_(printf)("c%d ", reg->coff); break;
+ case RR_Reg: VG_(printf)("r%d ", reg->reg); break;
+ case RR_Arch: VG_(printf)("a "); break;
+ default: VG_(core_panic)("ppRegRule");
+ }
+}
+
+
typedef
struct {
/* Read-only fields. */
@@ -1006,6 +1033,16 @@
}
UnwindContext;
=20
+static void ppUnwindContext ( UnwindContext* ctx )
+{
+ Int i;
+ VG_(printf)("0x%llx: ", (ULong)ctx->loc);
+ VG_(printf)("%d(r%d) ", ctx->cfa_offset, ctx->cfa_reg);
+ for (i =3D 0; i < N_CFI_REGS; i++)
+ ppRegRule(&ctx->reg[i]);
+ VG_(printf)("\n");
+}
+
static void initUnwindContext ( /*OUT*/UnwindContext* ctx )
{
Int i;
@@ -1021,30 +1058,9 @@
}
}
=20
-static void ppRegRule ( RegRule* reg )
-{
- switch (reg->tag) {
- case RR_Undef: VG_(printf)("u "); break;
- case RR_Same: VG_(printf)("s "); break;
- case RR_CFAoff: VG_(printf)("c%d ", reg->coff); break;
- case RR_Reg: VG_(printf)("r%d ", reg->reg); break;
- case RR_Arch: VG_(printf)("a "); break;
- default: VG_(core_panic)("ppRegRule");
- }
-}
=20
+/* --------------- Summarisation --------------- */
=20
-static void ppUnwindContext ( UnwindContext* ctx )
-{
- Int i;
- VG_(printf)("0x%llx: ", (ULong)ctx->loc);
- VG_(printf)("%d(r%d) ", ctx->cfa_offset, ctx->cfa_reg);
- for (i =3D 0; i < N_CFI_REGS; i++)
- ppRegRule(&ctx->reg[i]);
- VG_(printf)("\n");
-}
-
-
/* 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. This works
@@ -1110,9 +1126,12 @@
return True;
=20
failed:
- VG_(printf)("summarise_context(loc_start =3D %p)"
- ": cannot summarise(why=3D%d):\n ", loc_start, why);
- ppUnwindContext(ctx);
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg,
+ "summarise_context(loc_start =3D %p)"
+ ": cannot summarise(why=3D%d): ", loc_start, why);
+ ppUnwindContext(ctx);
+ }
return False;
}
=20
@@ -1137,6 +1156,9 @@
VG_(printf)("\n");
}
=20
+
+/* ------------ Pick apart DWARF2 byte streams ------------ */
+
static inline Bool host_is_little_endian ( void )
{
UInt x =3D 0x76543210;
@@ -1144,7 +1166,6 @@
return toBool(*p =3D=3D 0x10);
}
=20
-
static Short read_Short ( UChar* data )
{
vg_assert(host_is_little_endian());
@@ -1217,11 +1238,11 @@
=20
static Addr read_Addr ( UChar* data )
{
- if (sizeof(Addr) =3D=3D 4)
- return read_UInt(data);
- else if (sizeof(Addr) =3D=3D 8)
- return read_ULong(data);
- vg_assert(0);
+# if VG_WORDSIZE =3D=3D 4
+ return read_UInt(data);
+# else
+ return read_ULong(data);
+# endif
}
=20
static UChar read_UChar ( UChar* data )
@@ -1320,6 +1341,8 @@
}
=20
=20
+/* ------------ Run/show CFI instructions ------------ */
+
/* Run a CFI instruction, and also return its length.
Returns 0 if the instruction could not be executed.=20
*/
@@ -1440,7 +1463,8 @@
break;
=20
default:=20
- VG_(printf)("Unhandled CFI instruction 0:%d\n", (Int)lo6);=20
+ VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: unhandled CFI "
+ "instruction 0:%d", (Int)lo6);=20
i =3D 0;
break;
}
@@ -1450,6 +1474,7 @@
=20
=20
/* Show a CFI instruction, and also return its length. */
+
static Int show_CF_instruction ( UChar* instr )
{
UInt delta;
@@ -1611,8 +1636,11 @@
}
=20
=20
+/* ------------ Main entry point for CFI reading ------------ */
+
void VG_(read_callframe_info_dwarf2)=20
- ( /*OUT*/SegInfo* si, UChar* ehframe, Int ehframe_sz, Addr ehfra=
me_addr )
+ ( /*OUT*/SegInfo* si,=20
+ UChar* ehframe, Int ehframe_sz, Addr ehframe_addr )
{
UnwindContext ctx, restore_ctx;
Int nbytes;
@@ -1718,6 +1746,10 @@
UChar cie_rareg =3D read_UChar(data); data +=3D sizeof(UChar);
if (VG_(clo_trace_cfi))=20
VG_(printf)("cie.ra_reg =3D %d\n", (Int)cie_rareg);
+ if (cie_rareg !=3D RA_COL) {
+ how =3D "cie.ra_reg does not match RA_COL";
+ goto bad;
+ }
=20
saw_z_augmentation =3D *cie_augmentation =3D=3D 'z';
if (saw_z_augmentation) {
Modified: trunk/coregrind/vg_symtab2.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_symtab2.c 2005-05-03 15:23:00 UTC (rev 3603)
+++ trunk/coregrind/vg_symtab2.c 2005-05-03 16:05:00 UTC (rev 3604)
@@ -391,9 +391,19 @@
them. */
if ( cfisi->base + cfisi->len - 1 < si->start
|| si->start + si->size - 1 < cfisi->base ) {
- if (VG_(clo_trace_cfi)) {
- VG_(printf)("CfiSI outside segment: ");
- VG_(ppCfiSI)(cfisi);
+ static Int complaints =3D 3;
+ if (VG_(clo_trace_cfi) || complaints > 0) {
+ complaints--;
+ VG_(message)(
+ Vg_DebugMsg,
+ "warning: CfiSI %p .. %p outside segment %p .. %p",
+ cfisi->base,=20
+ cfisi->base + cfisi->len - 1,
+ si->start,
+ si->start + si->size - 1=20
+ );
+ if (VG_(clo_trace_cfi))=20
+ VG_(ppCfiSI)(cfisi);
}
return;
}
@@ -1709,7 +1719,7 @@
}
=20
/* Read .eh_frame (call-frame-info) if any */
- if (ehframe && ehframe_sz > 4) {
+ if (ehframe) {
VG_(read_callframe_info_dwarf2) ( si, ehframe, ehframe_sz, ehfr=
ame_addr );
}
=20
|