From: Tom Hughes Date: Wed, 5 Oct 2011 08:48:07 +0000 (+0000) Subject: More fixes for unaligned accesses in the debuginfo code. BZ#282527. X-Git-Tag: svn/VALGRIND_3_7_0~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d991dfe72740f6c34c9ac33ed703fdedaa4a667f;p=thirdparty%2Fvalgrind.git More fixes for unaligned accesses in the debuginfo code. BZ#282527. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12102 --- diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index e41eb8bf3d..1a31f60cc3 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -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++); diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 97373e88a9..445f621025 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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; } diff --git a/coregrind/m_debuginfo/misc.c b/coregrind/m_debuginfo/misc.c index be60ffc38a..b5bf39d72a 100644 --- a/coregrind/m_debuginfo/misc.c +++ b/coregrind/m_debuginfo/misc.c @@ -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 ---*/ diff --git a/coregrind/m_debuginfo/priv_misc.h b/coregrind/m_debuginfo/priv_misc.h index 51a30c96eb..a16ef3ed70 100644 --- a/coregrind/m_debuginfo/priv_misc.h +++ b/coregrind/m_debuginfo/priv_misc.h @@ -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; diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 3fe43db0f6..e37f251ed5 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -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]