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
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to