|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Porting valgrind.h to win32?win32 apps run pretty well in wine in valgrind. Great!
But at the moment, valgrind.h doesn't support win32, so win32 apps can't do client requests, which means that you can't instrument the win32 app's heap. So I read up on gcc inline assembler syntax, and looked at valgrind.h... but rather than rot my brain, I decided to use objdump to display the bytes of a simple linux app that calls VALGRIND_PRINT. __SPECIAL_INSTRUCTION_PREAMBLE appears to expand to 48 c1 c7 03 rol $0x3,%rdi 48 c1 c7 0d rol $0xd,%rdi 48 c1 c7 3d rol $0x3d,%rdi 48 c1 c7 33 rol $0x33,%rdi while the key bit of VALGRIND_DO_CLIENT_REQUEST which immediately follows the preamble expands to 48 87 db xchg %rbx,%rbx I'm a bit mystified by all the 0x48 prefixes. I thought 0x48 was dec ax ... what's going on there? In spite of not understanding this, I had a shot at porting VALGRIND_PRINTF. Here's a little test program that should display "Hello, valgrind" and then a warning about exit's argument being undefined when run either as a native linux app, e.g. gcc valprint.c valgrind ./a.out or as a win32 app under wine: cl valprint.c (transfer to linux system) wine winemine & (to avoid valgrinding service startup) valgrind --trace-children=yes wine valprint.exe Works fine on linux, and on Wine the exit(undefined) warning shows up fine, but my implementation of VALGRIND_PRINTF seems to be a no-op :-( Here's the test program. Anyone adventurous feel like having a look? #include <malloc.h> #ifdef _WIN32 #include <stdlib.h> #include <stdarg.h> #define __SPECIAL_INSTRUCTION_PREAMBLE __asm { \ __asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x03 \ __asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x0d \ __asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x3d \ __asm _emit 0x48 __asm _emit 0xc1 __asm _emit 0xc7 __asm _emit 0x33 \ } enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, VG_USERREQ__PRINTF = 0x1401, } Vg_ClientRequest; static int VALGRIND_PRINTF(const char *format, ...) { va_list vargs; volatile unsigned int _zzq_args[6]; unsigned int _qzz_res; va_start(vargs, format); _zzq_args[0] = (unsigned int) VG_USERREQ__PRINTF, _zzq_args[1] = (unsigned int) format; _zzq_args[2] = (unsigned int) vargs; _zzq_args[3] = (unsigned int) 0; _zzq_args[4] = (unsigned int) 0; _zzq_args[5] = (unsigned int) 0; __asm mov eax, _zzq_args __asm mov edx, 0 __SPECIAL_INSTRUCTION_PREAMBLE __asm xchg ebx,ebx __asm mov _qzz_res, edx va_end(vargs); return (int)_qzz_res; } #else #include <valgrind/valgrind.h> #endif int main() { char *memory = malloc(10); VALGRIND_PRINTF("Hello, valgrind!\n"); return memory[0]; } ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Valgrind-users mailing list Valgrind-users@... https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
|
Re: Porting valgrind.h to win32?I extended my demo program to support mingw32,
and got VALGRIND_PRINTF to work from a win32 app that way. Now we just need to figure out what went wrong in my trial port of valgrind.h to visual C. Filed enhancement request for this at https://bugs.kde.org/show_bug.cgi?id=210935 ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Valgrind-users mailing list Valgrind-users@... https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
|
Re: Porting valgrind.h to win32?On 18/10/09 02:37, Dan Kegel wrote:
> while the key bit of VALGRIND_DO_CLIENT_REQUEST > which immediately follows the preamble expands to > 48 87 db xchg %rbx,%rbx > > I'm a bit mystified by all the 0x48 prefixes. I thought > 0x48 was dec ax ... what's going on there? It might be "dec ax" in 32 bit code but this is 64 bit code so it's a REX prefix, used to access the extra registers. Tom -- Tom Hughes (tom@...) http://www.compton.nu/ ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Valgrind-users mailing list Valgrind-users@... https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
|
Re: Porting valgrind.h to win32?Thanks to Tom and John, I now use 32 bit opcodes, and it
works a lot better :-) My little demo still doesn't quite work when compiled with visual c++ -- valgrind explodes with a SIGSEGV, so either I have a bug, or varargs is different enough to cause trouble. I have to run, but if anyone's curious, here's what I've got so far. - Dan /* Demo of calling VALGRIND_PRINTF * See https://bugs.kde.org/show_bug.cgi?id=210935 * * Works under Linux if compiled natively or if compiled with * mingw32 and run under Wine. * Doesn't quite work yet if compiled under Visual C++. * Dan Kegel 18 Oct 2009 */ #include <malloc.h> #if defined(linux) #include <valgrind/valgrind.h> #elif defined(_WIN32) /* Subset of valgrind.h, ported to win32 for compilers mingw and visual c */ #include <stdlib.h> #include <stdarg.h> enum { VG_USERREQ__PRINTF = 0x1401, } Vg_ClientRequest; #if defined(__GNUC__) /* no changes needed in the gcc case; * valgrind.h just needs conditionals changed a bit * to recongnize that it works under gcc regardless of operating system */ #define __SPECIAL_INSTRUCTION_PREAMBLE \ "roll $3, %%edi ; roll $13, %%edi\n\t" \ "roll $29, %%edi ; roll $19, %%edi\n\t" #define VALGRIND_DO_CLIENT_REQUEST( \ _zzq_rlval, _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ { volatile unsigned int _zzq_args[6]; \ volatile unsigned int _zzq_result; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %EDX = client_request ( %EAX ) */ \ "xchgl %%ebx,%%ebx" \ : "=d" (_zzq_result) \ : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ _zzq_rlval = _zzq_result; \ } static int VALGRIND_PRINTF(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); static int VALGRIND_PRINTF(const char *format, ...) { unsigned long _qzz_res; va_list vargs; va_start(vargs, format); VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF, (unsigned long)format, (unsigned long)vargs, 0, 0, 0); va_end(vargs); return (int)_qzz_res; } #else /* definitions from valgrind.h, ported to visual c */ /* This is for 32 bits; for 64 bits, shift counts are different */ #define __SPECIAL_INSTRUCTION_PREAMBLE __asm { \ __asm rol edi, 0x03 \ __asm rol edi, 0x0d \ __asm rol edi, 0x1d \ __asm rol edi, 0x13 \ } static int VALGRIND_PRINTF(const char *format, ...) { va_list vargs; volatile unsigned int _zzq_args[6]; unsigned int _qzz_res; va_start(vargs, format); _zzq_args[0] = (unsigned int) VG_USERREQ__PRINTF, _zzq_args[1] = (unsigned int) format; _zzq_args[2] = (unsigned int) vargs; _zzq_args[3] = (unsigned int) 0; _zzq_args[4] = (unsigned int) 0; _zzq_args[5] = (unsigned int) 0; __asm mov eax, _zzq_args __asm mov edx, 0 __SPECIAL_INSTRUCTION_PREAMBLE __asm xchg ebx,ebx __asm mov _qzz_res, edx va_end(vargs); return (int)_qzz_res; } #endif /* defined(__GCC__) */ #endif /* defined(_WIN32) */ int main() { char *memory = malloc(10); VALGRIND_PRINTF("Hello, valgrind!\n"); return memory[0]; } ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Valgrind-users mailing list Valgrind-users@... https://lists.sourceforge.net/lists/listinfo/valgrind-users |
| Free embeddable forum powered by Nabble | Forum Help |