|
From: Tom H. <th...@cy...> - 2004-03-09 12:20:42
|
In message <164...@ca...>
Paul Mackerras <pa...@sa...> wrote:
> By the way, how do you cope with self-modifying code in valgrind on
> x86? Procedure linkage through a PLT presumably involves ld.so
> modifying the PLT entry, doesn't it?
No it doesn't actually. This is what the PLT entry for printf looks
like the first time it is called:
(gdb) disas 0x0804828c
Dump of assembler code for function printf:
0x0804828c <printf+0>: jmp *0x804954c
0x08048292 <printf+6>: push $0x8
0x08048297 <printf+11>: jmp 0x804826c <_init+24>
End of assembler dump.
(gdb) p/x *(unsigned long *)0x804954c
$2 = 0x8048292
and then the second time:
(gdb) disas 0x0804828c
Dump of assembler code for function printf:
0x0804828c <printf+0>: jmp *0x804954c
0x08048292 <printf+6>: push $0x8
0x08048297 <printf+11>: jmp 0x804826c <_init+24>
End of assembler dump.
(gdb) p/x *(unsigned long *)0x804954c
$3 = 0x4204f4a0
As you can see, the first instruction is an indirect jump which
initially points to the next instruction which pushes the entry
number and calls the dynamic resolver.
The second time round, the indirection table has been updated so
that initial indirect jump now calls directly to the function.
So there is no code change occurring, just an update to the
indirection table which is data.
The main self-modifying code problem we have on x86 is the trampolines
which gcc puts on the stack when nested functions are used, and we
don't have a good solution for that at the moment as on x86 the caches
are always coherent I believe so there is no instruction to hint to us
that the translation needs to be discarded.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|