|
From: Jakub B. <ber...@gm...> - 2016-09-08 13:06:11
|
Hello, I'm experimenting with writing a valgrind tool and I'd like to access function parameters, specifically the size given to malloc. It is passed to the malloc callback, but I need to know the address of the variable that was passed as the parameter (if it wasn't a constant). Is there a simple way to do this without searching through the stack frame? Thank you, Kuba Beranek |
|
From: Ivo R. <iv...@iv...> - 2016-09-09 17:35:49
|
2016-09-08 15:05 GMT+02:00 Jakub Beránek <ber...@gm...>: > I'm experimenting with writing a valgrind tool and I'd like to access > function parameters, specifically the size given to malloc. > I assume you are implementing VG_(needs_malloc_replacement)() and have a vgpreload_* module? > It is passed to the malloc callback, but I need to know the address of the > variable that was passed as the parameter (if it wasn't a constant). > Have a look at how existing tools implement VG_(needs_malloc_replacement)() and in particular, how do they implement pmalloc() callback. For example ms_malloc() in massif. Passing of the function parameters from the client (instrumented program) to the tool is performed as follows: - vgpreload_* library is loaded with the client program - vgpreload_* library defines malloc() replacements as per vg_replace_malloc.c [for example via ALLOC_or_NULL] - replacement function uses a client request: special sequence of instructions [for example VALGRIND_NON_SIMD_CALL1] - when Valgrind translates and instruments the client program and all the libraries, it recognizes the client request and acts accordingly - when the instrumented program is run, it calls into the tool's provided callback [for example ms_malloc()] Therefore there is no need to have any knowledge about function argument passing convention, which differs among architectures. This is all hidden behind client request definition (valgrind.h) and VEX frontend, specific to a particular architecture. The tool is architecture agnostic. Hope that helps, I. Btw, what is the main purpose of your tool? |
|
From: Ivo R. <iv...@iv...> - 2016-09-10 00:51:21
|
2016-09-09 20:28 GMT+02:00 Jakub Beránek <ber...@gm...>: > I'm playing with symbolic execution inside Valgrind and therefore when the > program calls malloc(x); > > I need to know the address of x to get its symbolic constraints (I don't > really care about the actual value of x). > > I realize that getting this to work will probably differ significantly > amongst different platforms, I'm not even sure if it's universally possible > (for example on AMD64 I can track the last assignment into > parameter-passing registers, but on x86 it's much harder to track what's on > the stack before a function call). > I also realize that this is not a typical usage for a Valgrind tool :-) > Oh my, that's completely different story, then. I am thinking how would you do that in the client/guest program itself, if there is no Valgrind involved. This would rely significantly on function argument passing convention used on every particular platform. > Maybe with DWARF I could link the function call to the parameter passing. > Maybe another possibility would be to mess with the IR code, in the tool's instrument() callback. But I don't see an efficient way at this moment. I. |
|
From: Philippe W. <phi...@sk...> - 2016-09-10 09:48:38
|
> 2016-09-09 20:28 GMT+02:00 Jakub Beránek <ber...@gm...>:
> I'm playing with symbolic execution inside Valgrind and
> therefore when the program calls malloc(x);
>
>
> I need to know the address of x to get its symbolic
> constraints (I don't really care about the actual value of x).
I am not sure to fully understand what you are trying to do.
There is not necessarily any address for the argument.
So, what is the tool supposed to do when you have a call such as:
malloc (10)
or
malloc (any_var + any_other_var)
?
In the first case, there is no var address
In the second case, also no address (or rather you might imagine you
have 2 addresses to track ?)
That being said, what you are trying to do might somewhat looks
like origin tracking in memcheck, which tries to determine the origin
of undef values (e.g. an allocation stack trace, or a stack frame).
You might maybe get some ideas from this.
Philippe
|