|
From: <sv...@va...> - 2011-10-05 08:52:53
|
Author: tom
Date: 2011-10-05 09:48:07 +0100 (Wed, 05 Oct 2011)
New Revision: 12102
Log:
More fixes for unaligned accesses in the debuginfo code. BZ#282527.
Modified:
trunk/coregrind/m_debuginfo/d3basics.c
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_debuginfo/misc.c
trunk/coregrind/m_debuginfo/priv_misc.h
trunk/coregrind/m_debuginfo/readdwarf3.c
Modified: trunk/coregrind/m_debuginfo/d3basics.c
===================================================================
--- trunk/coregrind/m_debuginfo/d3basics.c 2011-10-05 07:39:07 UTC (rev 12101)
+++ trunk/coregrind/m_debuginfo/d3basics.c 2011-10-05 08:48:07 UTC (rev 12102)
@@ -558,7 +558,7 @@
/* Presumably what is given in the Dwarf3 is a SVMA (how
could it be otherwise?) So we add the appropriate bias
on before pushing the result. */
- a1 = *(Addr*)expr;
+ a1 = ML_(read_Addr)(expr);
if (bias_address(&a1, di)) {
PUSH( a1 );
expr += sizeof(Addr);
@@ -660,7 +660,7 @@
POP(uw1);
if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
VKI_PROT_READ )) {
- uw1 = *(UWord*)uw1;
+ uw1 = ML_(read_UWord)((void *)uw1);
PUSH(uw1);
} else {
FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
@@ -673,10 +673,10 @@
if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
VKI_PROT_READ )) {
switch (uw2) {
- case 1: uw1 = *(UChar*)uw1; break;
- case 2: uw1 = *(UShort*)uw1; break;
- case 4: uw1 = *(UInt*)uw1; break;
- case 8: uw1 = *(ULong*)uw1; break;
+ case 1: uw1 = ML_(read_UChar)((void*)uw1); break;
+ case 2: uw1 = ML_(read_UShort)((void*)uw1); break;
+ case 4: uw1 = ML_(read_UInt)((void*)uw1); break;
+ case 8: uw1 = ML_(read_ULong)((void*)uw1); break;
default:
FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
"DW_OP_deref_size size");
@@ -695,17 +695,17 @@
PUSH(uw1);
break;
case DW_OP_const2u:
- uw1 = *(UShort *)expr;
+ uw1 = ML_(read_UShort)(expr);
expr += 2;
PUSH(uw1);
break;
case DW_OP_const4u:
- uw1 = *(UInt *)expr;
+ uw1 = ML_(read_UInt)(expr);
expr += 4;
PUSH(uw1);
break;
case DW_OP_const8u:
- uw1 = *(ULong *)expr;
+ uw1 = ML_(read_ULong)(expr);
expr += 8;
PUSH(uw1);
break;
@@ -719,17 +719,17 @@
PUSH(uw1);
break;
case DW_OP_const2s:
- uw1 = *(Short *)expr;
+ uw1 = ML_(read_Short)(expr);
expr += 2;
PUSH(uw1);
break;
case DW_OP_const4s:
- uw1 = *(Int *)expr;
+ uw1 = ML_(read_Int)(expr);
expr += 4;
PUSH(uw1);
break;
case DW_OP_const8s:
- uw1 = *(Long *)expr;
+ uw1 = ML_(read_Long)(expr);
expr += 8;
PUSH(uw1);
break;
@@ -826,7 +826,7 @@
#undef UNARY
#undef BINARY
case DW_OP_skip:
- sw1 = *(Short *)expr;
+ sw1 = ML_(read_Short)(expr);
expr += 2;
if (expr + sw1 < limit - exprszB)
FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
@@ -835,7 +835,7 @@
expr += sw1;
break;
case DW_OP_bra:
- sw1 = *(Short *)expr;
+ sw1 = ML_(read_Short)(expr);
expr += 2;
if (expr + sw1 < limit - exprszB)
FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
@@ -853,7 +853,7 @@
"DW_OP_call_frame_cfa but no reg info");
#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
/* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
- uw1 = *(Addr *)(regs->sp);
+ uw1 = ML_(read_Addr)(regs->sp);
#else
uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
#endif
@@ -869,19 +869,19 @@
uw1 = 0;
switch (sw1) {
case 1:
- uw1 = *(UChar *)expr;
+ uw1 = ML_(read_UChar)(expr);
expr += 1;
break;
case 2:
- uw1 = *(UShort *)expr;
+ uw1 = ML_(read_UShort)(expr);
expr += 2;
break;
case 4:
- uw1 = *(UInt *)expr;
+ uw1 = ML_(read_UInt)(expr);
expr += 4;
break;
case 8:
- uw1 = *(ULong *)expr;
+ uw1 = ML_(read_ULong)(expr);
expr += 8;
break;
default:
@@ -950,9 +950,9 @@
return res;
}
vg_assert(uc == 0);
- aMin = * (Addr*)p; p += sizeof(Addr);
- aMax = * (Addr*)p; p += sizeof(Addr);
- nbytes = * (UShort*)p; p += sizeof(UShort);
+ aMin = ML_(read_Addr)(p); p += sizeof(Addr);
+ aMax = ML_(read_Addr)(p); p += sizeof(Addr);
+ nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
nGuards++;
if (0) VG_(printf)(" guard %d: %#lx %#lx\n",
(Int)nGuards, aMin,aMax);
@@ -1027,9 +1027,9 @@
if (uc == 1) /*isEnd*/
break;
vg_assert(uc == 0);
- aMin = * (Addr*)p; p += sizeof(Addr);
- aMax = * (Addr*)p; p += sizeof(Addr);
- nbytes = * (UShort*)p; p += sizeof(UShort);
+ aMin = ML_(read_Addr)(p); p += sizeof(Addr);
+ aMax = ML_(read_Addr)(p); p += sizeof(Addr);
+ nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
nGuards++;
if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
nGuards, aMin,aMax);
@@ -1041,7 +1041,7 @@
obviously a constant. */
if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
/* DW_OP_addr a */
- Addr a = *(Addr*)(p+1);
+ Addr a = ML_(read_Addr)((p+1));
if (bias_address(&a, di)) {
thisResult.b = True;
thisResult.ul = (ULong)a;
@@ -1061,7 +1061,7 @@
&& 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];
+ Addr a = ML_(read_Addr)(&p[1]);
if (bias_address(&a, di)) {
thisResult.b = True;
thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
@@ -1189,9 +1189,9 @@
if (uc == 1)
break; /*isEnd*/
vg_assert(uc == 0);
- aMin = * (Addr*)p; p += sizeof(Addr);
- aMax = * (Addr*)p; p += sizeof(Addr);
- nbytes = * (UShort*)p; p += sizeof(UShort);
+ aMin = ML_(read_Addr)(p); p += sizeof(Addr);
+ aMax = ML_(read_Addr)(p); p += sizeof(Addr);
+ nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
VG_(printf)("[%#lx,%#lx]=", aMin, aMax);
while (nbytes > 0) {
VG_(printf)("%02x", (UInt)*p++);
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- trunk/coregrind/m_debuginfo/debuginfo.c 2011-10-05 07:39:07 UTC (rev 12101)
+++ trunk/coregrind/m_debuginfo/debuginfo.c 2011-10-05 08:48:07 UTC (rev 12102)
@@ -2041,7 +2041,7 @@
return 0;
}
/* let's hope it doesn't trap! */
- return * ((UWord*)a);
+ return ML_(read_UWord)((void *)a);
default:
goto unhandled;
}
@@ -2242,7 +2242,7 @@
Addr a = uregs->sp + cfsi->cfa_off;
if (a < min_accessible || a > max_accessible-sizeof(Addr))
break;
- cfa = *(Addr*)a;
+ cfa = ML_(read_Addr)((void *)a);
break;
}
case CFIR_SAME:
@@ -2385,7 +2385,7 @@
if (a < min_accessible \
|| a > max_accessible-sizeof(Addr)) \
return False; \
- _prev = *(Addr*)a; \
+ _prev = ML_(read_Addr)((void *)a); \
break; \
} \
case CFIR_CFAREL: \
@@ -2547,10 +2547,10 @@
spHere = *spP;
- *ipP = *(Addr *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals));
- *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
- + fpo->cdwParams);
- *fpP = *(Addr *)(spHere + 4*2);
+ *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
+ *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
+ + fpo->cdwParams);
+ *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
return True;
}
Modified: trunk/coregrind/m_debuginfo/misc.c
===================================================================
--- trunk/coregrind/m_debuginfo/misc.c 2011-10-05 07:39:07 UTC (rev 12101)
+++ trunk/coregrind/m_debuginfo/misc.c 2011-10-05 08:48:07 UTC (rev 12102)
@@ -136,6 +136,27 @@
return r;
}
+UChar *ML_(write_UShort) ( UChar* ptr, UShort val ) {
+ if (host_is_little_endian()) {
+ ptr[0] = val & 0xff;
+ ptr[1] = ( val >> 8 ) & 0xff;
+ } else {
+ ptr[0] = ( val >> 8 ) & 0xff;
+ ptr[1] = val & 0xff;
+ }
+ return ptr + sizeof(UShort);
+}
+
+UWord ML_(read_UWord) ( UChar* data ) {
+ if (sizeof(UWord) == sizeof(UInt)) {
+ return ML_(read_UInt)(data);
+ } else if (sizeof(UWord) == sizeof(ULong)) {
+ return ML_(read_ULong)(data);
+ } else {
+ vg_assert(0);
+ }
+}
+
UInt ML_(read_UInt) ( UChar* data ) {
UInt r = 0;
if (host_is_little_endian()) {
@@ -152,6 +173,21 @@
return r;
}
+UChar* ML_(write_UInt) ( UChar* ptr, UInt val ) {
+ if (host_is_little_endian()) {
+ ptr[0] = val & 0xff;
+ ptr[1] = ( val >> 8 ) & 0xff;
+ ptr[2] = ( val >> 16 ) & 0xff;
+ ptr[3] = ( val >> 24 ) & 0xff;
+ } else {
+ ptr[0] = ( val >> 24 ) & 0xff;
+ ptr[1] = ( val >> 16 ) & 0xff;
+ ptr[2] = ( val >> 8 ) & 0xff;
+ ptr[3] = val & 0xff;
+ }
+ return ptr + sizeof(UInt);
+}
+
ULong ML_(read_ULong) ( UChar* data ) {
ULong r = 0;
if (host_is_little_endian()) {
@@ -176,10 +212,38 @@
return r;
}
+UChar* ML_(write_ULong) ( UChar* ptr, ULong val ) {
+ if (host_is_little_endian()) {
+ ptr[0] = val & 0xff;
+ ptr[1] = ( val >> 8 ) & 0xff;
+ ptr[2] = ( val >> 16 ) & 0xff;
+ ptr[3] = ( val >> 24 ) & 0xff;
+ ptr[4] = ( val >> 32 ) & 0xff;
+ ptr[5] = ( val >> 40 ) & 0xff;
+ ptr[6] = ( val >> 48 ) & 0xff;
+ ptr[7] = ( val >> 56 ) & 0xff;
+ } else {
+ ptr[0] = ( val >> 56 ) & 0xff;
+ ptr[1] = ( val >> 48 ) & 0xff;
+ ptr[2] = ( val >> 40 ) & 0xff;
+ ptr[3] = ( val >> 32 ) & 0xff;
+ ptr[4] = ( val >> 24 ) & 0xff;
+ ptr[5] = ( val >> 16 ) & 0xff;
+ ptr[6] = ( val >> 8 ) & 0xff;
+ ptr[7] = val & 0xff;
+ }
+ return ptr + sizeof(ULong);
+}
+
UChar ML_(read_UChar) ( UChar* data ) {
return data[0];
}
+UChar* ML_(write_UChar) ( UChar* ptr, UChar val ) {
+ ptr[0] = val;
+ return ptr + sizeof(UChar);
+}
+
Addr ML_(read_Addr) ( UChar* data ) {
if (sizeof(Addr) == sizeof(UInt)) {
return ML_(read_UInt)(data);
@@ -190,7 +254,17 @@
}
}
+UChar* ML_(write_Addr) ( UChar* ptr, Addr val ) {
+ if (sizeof(Addr) == sizeof(UInt)) {
+ return ML_(write_UInt)(ptr, val);
+ } else if (sizeof(Addr) == sizeof(ULong)) {
+ return ML_(write_ULong)(ptr, val);
+ } else {
+ vg_assert(0);
+ }
+}
+
/*--------------------------------------------------------------------*/
/*--- end misc.c ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_debuginfo/priv_misc.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_misc.h 2011-10-05 07:39:07 UTC (rev 12101)
+++ trunk/coregrind/m_debuginfo/priv_misc.h 2011-10-05 08:48:07 UTC (rev 12102)
@@ -48,11 +48,18 @@
Int ML_(read_Int)( UChar* data );
Long ML_(read_Long)( UChar* data );
UShort ML_(read_UShort)( UChar* data );
+UWord ML_(read_UWord)( UChar* data );
UInt ML_(read_UInt)( UChar* data );
ULong ML_(read_ULong)( UChar* data );
UChar ML_(read_UChar)( UChar* data );
Addr ML_(read_Addr)( UChar* data );
+UChar* ML_(write_UShort)( UChar* ptr, UShort val );
+UChar* ML_(write_UInt)( UChar* ptr, UInt val );
+UChar* ML_(write_ULong)( UChar* ptr, ULong val );
+UChar* ML_(write_UChar)( UChar* ptr, UChar val );
+UChar* ML_(write_Addr)( UChar* ptr, Addr val );
+
/* A handy type, a la Haskell's Maybe type. Yes, I know, C sucks.
Been there. Done that. Seen the movie. Got the T-shirt. Etc. */
typedef struct { ULong ul; Bool b; } MaybeULong;
Modified: trunk/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- trunk/coregrind/m_debuginfo/readdwarf3.c 2011-10-05 07:39:07 UTC (rev 12101)
+++ trunk/coregrind/m_debuginfo/readdwarf3.c 2011-10-05 08:48:07 UTC (rev 12102)
@@ -243,7 +243,7 @@
/*NOTREACHED*/
vg_assert(0);
}
- r = * (UShort*) &c->region_start_img[ c->region_next ];
+ r = ML_(read_UShort)(&c->region_start_img[ c->region_next ]);
c->region_next += sizeof(UShort);
return r;
}
@@ -255,7 +255,7 @@
/*NOTREACHED*/
vg_assert(0);
}
- r = * (UInt*) &c->region_start_img[ c->region_next ];
+ r = ML_(read_UInt)(&c->region_start_img[ c->region_next ]);
c->region_next += sizeof(UInt);
return r;
}
@@ -267,7 +267,7 @@
/*NOTREACHED*/
vg_assert(0);
}
- r = * (ULong*) &c->region_start_img[ c->region_next ];
+ r = ML_(read_ULong)(&c->region_start_img[ c->region_next ]);
c->region_next += sizeof(ULong);
return r;
}
@@ -472,8 +472,8 @@
static void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
{
UShort nbytes;
- Addr* pA;
UChar* p = &gx->payload[0];
+ UChar* pA;
UChar uc;
uc = *p++; /*biasMe*/
if (uc == 0)
@@ -486,15 +486,15 @@
break; /*isEnd*/
vg_assert(uc == 0);
/* t-bias aMin */
- pA = (Addr*)p;
- *pA += di->text_debug_bias;
+ pA = (UChar*)p;
+ ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
p += sizeof(Addr);
/* t-bias aMax */
- pA = (Addr*)p;
- *pA += di->text_debug_bias;
+ pA = (UChar*)p;
+ ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
p += sizeof(Addr);
/* nbytes, and actual expression */
- nbytes = * (UShort*)p; p += sizeof(UShort);
+ nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
p += nbytes;
}
}
@@ -520,13 +520,13 @@
p = pstart = &gx->payload[0];
- * ((UChar*)p) = 0; /*biasMe*/ p += sizeof(UChar);
- * ((UChar*)p) = 0; /*!isEnd*/ p += sizeof(UChar);
- * ((Addr*)p) = 0; /*aMin*/ p += sizeof(Addr);
- * ((Addr*)p) = ~((Addr)0); /*aMax */ p += sizeof(Addr);
- * ((UShort*)p) = (UShort)nbytes; /*nbytes*/ p += sizeof(UShort);
+ p = ML_(write_UChar)(p, 0); /*biasMe*/
+ p = ML_(write_UChar)(p, 0); /*!isEnd*/
+ p = ML_(write_Addr)(p, 0); /*aMin*/
+ p = ML_(write_Addr)(p, ~0); /*aMax*/
+ p = ML_(write_UShort)(p, nbytes); /*nbytes*/
VG_(memcpy)(p, block, nbytes); p += nbytes;
- * ((UChar*)p) = 1; /*isEnd*/ p += sizeof(UChar);
+ p = ML_(write_UChar)(p, 1); /*isEnd*/
vg_assert( (SizeT)(p - pstart) == bytesReqd);
vg_assert( &gx->payload[bytesReqd]
|