|
From: Randy M. <rwm...@gm...> - 2006-05-03 15:16:51
|
Hi,
I trying to use valgrind on an embedded ppc system using a custom kernel.
First, because our kernel doesn't have Altivec enabled and the valgrind/VE=
X
altivec detection in ./coregrind/m_machine.c wasn't working,
I commented out the Altivec detection hardcoded: have_vmx =3D False;
If you are interested, I can reproduce this without the patch and file a bu=
g.
So now, valgrind /bin/ls works! Yipee!
I tried valgrind on a binary of interest and found an unhandled instruction
error as shown below. I looked at the svn latest src but it didn't appear
that these issues had been fixed. Please confirm.
dis_int_ldst_rev(PPC32)(opc2)
disInstr(ppc32): unhandled instruction: 0x7D204E2C
primary 31(0x1F), secondary 1580(0x62C)
=3D=3D18449=3D=3D Your program just tried to execute an instruction that Va=
lgrind
=3D=3D18449=3D=3D did not recognise. There are two possible reasons for th=
is.
=3D=3D18449=3D=3D 1. Your program has a bug and erroneously jumped to a non=
-code
=3D=3D18449=3D=3D location. If you are running Memcheck and you just sa=
w a
=3D=3D18449=3D=3D warning about a bad jump, it's probably your program's=
fault.
no.
=3D=3D18449=3D=3D 2. The instruction is legitimate but Valgrind doesn't han=
dle it,
=3D=3D18449=3D=3D i.e. it's Valgrind's fault. If you think this is the =
case or
=3D=3D18449=3D=3D you are not sure, please let us know.
Here I am.
=3D=3D18449=3D=3D Either way, Valgrind will now raise a SIGILL signal which=
will
=3D=3D18449=3D=3D probably kill your program.
=3D=3D18449=3D=3D
=3D=3D18449=3D=3D Process terminating with default action of signal 4
(SIGILL): dumping core
=3D=3D18449=3D=3D Illegal opcode at address 0x10001CD4
=3D=3D18449=3D=3D at 0x10001CD4: testRead16le (ovlBitField.h:646)
=3D=3D18449=3D=3D by 0xFF73058: __cUnit_run_test (cUnit.c:407)
=3D=3D18449=3D=3D by 0xFF739B8: g_node_traverse_pre_order (gnode.c:476)
=3D=3D18449=3D=3D by 0xFF7393C: g_node_traverse_pre_order (gnode.c:472)
=3D=3D18449=3D=3D by 0xFF7393C: g_node_traverse_pre_order (gnode.c:472)
=3D=3D18449=3D=3D by 0xFF729F4: cUnit_run_session (cUnit.c:197)
=3D=3D18449=3D=3D by 0xFF733FC: cUnit_TestRunner_int (cUnitRunnerUnix.c:=
125)
=3D=3D18449=3D=3D by 0x1000F3DC: main (ovlUnitTest.c:34)
If I run objdump on my test program, I see that the instruction is:
10001d24: 7d 20 4e 2c lhbrx r9,r0,r9
and I see that that comes from
OVL_INLINE uint_fast16_t ovlRead16le(const uint8_t *s) OVL_THROW
{
uint_fast16_t result;
#if __BYTE_ORDER =3D=3D __BIG_ENDIAN
__asm volatile(
" lhbrx %0,0,%1 \n" // Get half word and reverse the by=
tes
: "=3Dr" (result) // %0 - Output operand
: "r" (s) // %1 - Input operand
: "memory" // Consider memory clobberred for aliasing
);
...
So, I tried to hack in support for lhbrx:
[VEX]$ ls ./priv/guest-ppc32/toIR.c*
./priv/guest-ppc32/toIR.c ./priv/guest-ppc32/toIR.c.orig
[VEX]$ diff ./priv/guest-ppc32/toIR.c*
2612,2618c2612
< case 0x62C: // lhbrx (Load HW, Byte-Reverse Indexed)
< DIP("lwzx r%d,r%d,r%d\n", rD_addr, rA_addr, rB_addr);
< vex_printf("rwm: fixed lhbrx?....\n");
< // ?? rwm: putIReg( rD_addr, loadBE(Ity_I32, mkexpr(EA_reg)) );
< putIReg( rD_addr, unop(Iop_16Uto32,
< loadBE(Ity_I16, mkexpr(EA_reg))) );
< break;
---
>
7261,7263d7254
< case 0x62C: // lhbrx
< if (dis_int_load( theInstr )) goto decode_success;
< goto decode_failure;
but I don't really understand valgrind's design. Does my put putIReg call l=
ook
right? I'm reading the manual and docs/internals now...
Thanks,
// Randy
|