|
From: Chris J. <ch...@at...> - 2004-06-23 11:33:27
|
Hello, I am trying to find a way to match function calls up with returns. For example: XXX: CALL somecode somecode: . . . YYY: RET I want to match the return at YYY with the call at XXX. Whatever method I use must be able to cope with 1) the stack pointer warping (e.g. due to longjmp) and 2) not all calls/returns being instrumented. To cope with 1) I decided to give each CALL instance a unique index and pushed this value on the stack. The instrumented RET would pop this value from the stack and in this way the RET could be matched with the CALL. To cope with 2) I decided that when an instrumented CALL occurred it would have to modify the return address on the stack to point to some trampoline code that would also pop the extra index from the stack. I hope I am making sense so far! I don't want the trampoline code instrumented so I decided to manually insert a non-instrumneted copy (compiled from Ucode) in the translation table. Unfortunately this requires the use of some internal functions and is generally messy. Can anyone help me out here and suggest a better way to do what I'm doing? Regargs, Chris -- http://www.atomice.com |
|
From: Nicholas N. <nj...@ca...> - 2004-06-23 13:20:44
|
On Wed, 23 Jun 2004, Chris January wrote: > I am trying to find a way to match function calls up with returns. > > [snip] > > I don't want the trampoline code instrumented so I decided to manually > insert a non-instrumneted copy (compiled from Ucode) in the translation > table. Unfortunately this requires the use of some internal functions > and is generally messy. > > Can anyone help me out here and suggest a better way to do what I'm > doing? A better way for matching call/ret pairs, or a better way for the trampoline bit? If the latter, can you give more detail about your current approach -- the description you've given is too vague to be much use. Can you insert UCode before a RET that calls your trampoline code? N |
|
From: Chris J. <ch...@at...> - 2004-06-23 16:53:27
|
> On Wed, 23 Jun 2004, Chris January wrote:
>
> > I am trying to find a way to match function calls up with returns.
> >
> > [snip]
> >
> > I don't want the trampoline code instrumented so I decided
> to manually
> > insert a non-instrumneted copy (compiled from Ucode) in the
> > translation table. Unfortunately this requires the use of some
> > internal functions and is generally messy.
> >
> > Can anyone help me out here and suggest a better way to do what I'm
> > doing?v
>
> A better way for matching call/ret pairs, or a better way for
> the trampoline bit? If the latter, can you give more detail
> about your current approach -- the description you've given
> is too vague to be much use. Can you insert UCode before a
> RET that calls your trampoline code?
No, I can't insert UCode before a RET because I don't want to instrument
the code that's being called.
What I'd really like to do is:
...
Record function call
CALL ...
Record function return
...
But unfortunately the CALL ends the basic block so this doesn't work.
So what I've tried to do is modify the return address to point to some
trampoline code that does the "Record function return" bit then returns
to the real return address.
The code looks something like this:
Char return_marker[100];
....
if (VG_(search_transtab) ((Addr) return_marker) == (Addr)0) {
...
cb = VG_(alloc_UCodeBlock) ();
cb->orig_eip = (Addr) return_marker;
t1 = newTemp (cb);
uInstr1 (cb, POP, 4, TempReg, t1);
VG_(set_global_var) (cb, (Addr) &jump_data1, t1);
uInstr1 (cb, POP, 4, TempReg, t1);
uInstr1 (cb, JMP, 4, TempReg, t1);
VG_(get_last_instr)(cb)->jmpkind = JmpBoring;
VG_(get_last_instr)(cb)->cond = CondAlways;
code = VG_(emit_code) (cb, &len, jumps);
VG_(add_to_trans_tab) ((Addr) return_marker, 100, (Addr), code, len,
jumps);
VG_(arena_free) (VG_ARG_JITTER, (void *)code);
VG_(free_UCodeBlock) (cb);
}
...
if (u_in->jmpkind == JmpCall) {
...
t1 = newTemp (cb);
t2 = newTemp (cb);
uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t1);
uLiteral (cb, (Addr) &sequence);
uInstr2 (cb, LOAD, 4, TempReg, t1, TempReg, t2);
uInstr1 (cb, PUSH, 4, TempReg, t2);
uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t1);
uLiteral (cb, (Addr) return_marker);
uInstr1(cb, PUSH, 4, TempReg, t1);
}
Unfortunately VG_(emit_code) complains the Ucode isn't sane
(specifically the first POP instruction).
The trampoline idea is a bit of a dirty hack and requires importing a
number of internal functions like VG_(add_to_trans_tab) and the
definition of UCodeBlock.
I'd really like to find a better way of adding instrumentation either
side of the CALL but I don't know of any.
Regards,
Chris
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-28 12:34:59
|
On Wed, 23 Jun 2004, Chris January wrote: >> A better way for matching call/ret pairs, or a better way for >> the trampoline bit? If the latter, can you give more detail >> about your current approach -- the description you've given >> is too vague to be much use. Can you insert UCode before a >> RET that calls your trampoline code? > > No, I can't insert UCode before a RET because I don't want to instrument > the code that's being called. > [snip] > Unfortunately VG_(emit_code) complains the Ucode isn't sane > (specifically the first POP instruction). POPs have to be paired with PUSHes, and can only be used in conjunction with CALLM, I think. I'm still not clear what it is you want to do. Perhaps you can give a more detailed example, showing some assembly code or UCode, and exactly what effect you are trying to achieve? N |