More fixes for unaligned accesses in the debuginfo code. BZ#282527.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12102
This commit is contained in:
Tom Hughes 2011-10-05 08:48:07 +00:00
parent 0eef127a30
commit d991dfe727
5 changed files with 133 additions and 52 deletions

View File

@ -558,7 +558,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
/* 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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
#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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
"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 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
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 @@ GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX,
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
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 @@ GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
&& 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 @@ void ML_(pp_GX) ( GExpr* gx ) {
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++);

View File

@ -2041,7 +2041,7 @@ UWord evalCfiExpr ( XArray* exprs, Int ix,
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 @@ static Addr compute_cfa ( D3UnwindRegs* uregs,
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 @@ Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
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 @@ Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
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;
}

View File

@ -136,6 +136,27 @@ UShort ML_(read_UShort) ( UChar* data ) {
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 @@ UInt ML_(read_UInt) ( UChar* data ) {
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 @@ ULong ML_(read_ULong) ( UChar* data ) {
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,6 +254,16 @@ Addr ML_(read_Addr) ( UChar* data ) {
}
}
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 ---*/

View File

@ -48,11 +48,18 @@ Short ML_(read_Short)( UChar* data );
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;

View File

@ -243,7 +243,7 @@ static UShort get_UShort ( Cursor* c ) {
/*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 @@ static UInt get_UInt ( Cursor* c ) {
/*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 @@ static ULong get_ULong ( Cursor* c ) {
/*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 @@ typedef
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 @@ static void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
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 @@ static GExpr* make_singleton_GX ( UChar* block, UWord nbytes )
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]