Example #1
0
int main(int ac, const char** av)
{
  const struct test_desc tests[] =
  {
    /* TEST_DESC(hi), */
    /* TEST_DESC(hix), */
    TEST_DESC(matmul),
    /* TEST_DESC(arr), */
    TEST_DESC_INVALID
  };

  static const size_t n = 10000;

  size_t i;
  size_t j;
  uint64_t ticks[2];
  double us[2];

  if (py_init())
  {
    printf("py_init() error\n");
    return -1;
  }

  for (i = 0; tests[i].name != NULL; ++i)
  {
    const struct test_desc* const t = &tests[i];
    py_handle_t py;

    printf("---");
    printf("--- %s test\n", t->name);

    if (py_open(&py))
    {
      printf("py_open error\n");
      continue ;
    }

    if (py_compile(&py, t->py_str))
    {
      printf("py_compile error\n");
      goto on_close;
    }

    /* add variables */
    if (t->post_compile(&py))
    {
      printf("py_post_compile error\n");
      goto on_close;
    }

    /* execute python version */
    ticks[0] = rdtsc();
    for (j = 0; j != n; ++j)
    {
      /* if (j && ((j % 100) == 0)) py_collect(&py); */

      t->pre_exec(&py);

      if (py_execute(&py))
      {
	printf("py_execute error (%zu)\n", j);
	goto on_close;
      }
    }
    ticks[1] = rdtsc();
    us[0] = (double)ticks_to_us(sub_ticks(ticks[0], ticks[1])) / 1000000.0;

    py_print_out_vars(&py);

    /* execute c version */
    ticks[0] = rdtsc();
    for (j = 0; j != n; ++j)
    {
      t->pre_exec(&py);
      t->c(&py);
    }
    ticks[1] = rdtsc();
    us[1] = (double)ticks_to_us(sub_ticks(ticks[0], ticks[1])) / 1000000.0;

    py_print_out_vars(&py);

    printf("py = %lfus, c = %lfus\n", us[0], us[1]);

  on_close:
    py_close(&py);
  }

  py_fini();

  return 0;
}
Example #2
0
File: pin.cpp Project: JaonLin/pyn
int main(int argc, char *argv[])
{
    PIN_Init(argc, argv);
    PIN_InitSymbols();

    py_init();

    pyrun_simple_string("_pin_function_addr = {}");

    char buf[256];
    for (uint32_t idx = 0; idx < ARRAYSIZE(g_functions); idx++) {
        sprintf(buf, "_pin_function_addr['%s'] = "FMTPTR,
            (const char *) g_functions[idx][0],
            (uintptr_t) g_functions[idx][1]);
        pyrun_simple_string(buf);
    }

#if x86
    pyrun_simple_string("x86, x64 = True, False");
#else
    pyrun_simple_string("x86, x64 = False, True");
#endif

#define G(value) \
    sprintf(buf, "%s = %d", #value, value); pyrun_simple_string(buf);

#include "pyn-globals.h"

    // we want to execute pyn.py in the current namespace
    pyrun_simple_string("exec open('pyn.py', 'rb').read()");

    // turns out that IARG_END is a macro which puts IARG_FILE_NAME and
    // IARG_LINE_NO, with their values accordingly, in the argument list as
    // well.. as we take care of this inside our *_InsertCall statements, we
    // can ignore the "real" meaning of IARG_END, and just assign it IARG_LAST
    // TODO actually add some special handling for IARG_END / whatever
    pyrun_simple_string("IARG_END = IARG_LAST");

    // manually parse argv, because KNOB - do you even parse?!
    for (int i = 0, tool_arg_start = -1; i < argc; i++) {
        // end of parameters to our pintool
        if(!strcmp(argv[i], "--")) break;

        // -t specifies our pintool, after that come args to our tool
        if(!strcmp(argv[i], "-t")) {
            tool_arg_start = i + 2;
            continue;
        }

        // check if we're already in the arguments to our tool
        if(tool_arg_start < 0 || i < tool_arg_start) continue;

        // python code injection!!1
        snprintf(buf, sizeof(buf), "exec open('%s', 'rb').read()", argv[i]);
        pyrun_simple_string(buf);
    }

    void *py_globals = NULL, *py_value;
    sprintf(buf, "import ctypes; ctypes.memmove("FMTPTR", "
            "ctypes.byref(ctypes.c_int(id(globals()))), %d)",
            (uintptr_t) &py_globals, sizeof(uintptr_t));
    pyrun_simple_string(buf);

    // generic callback registration function
#define CALLBACK_REG(name, api) \
    g_##name##_callback = pydict_get_item_string(py_globals, #name); \
    if(g_##name##_callback != NULL) { \
        api(&name##_callback, NULL); \
    }

    // callback registration function for callbacks
    // with only one integer as parameter, and which return void
#define CALLBACK_REG1(name, api, cast) \
    py_value = pydict_get_item_string(py_globals, #name); \
    if(py_value != NULL) { \
        api((cast##CALLBACK) &single_int_callback, py_value); \
    }

#define CALLBACK_REG1EX(name, wrapper, api, cast) { \
    static void *_##name##_args[3] = { \
        pyn_callback_helper, \
        pydict_get_item_string(py_globals, #name), \
        pydict_get_item_string(py_globals, #wrapper), \
    }; \
    if(_##name##_args[1] != NULL) { \
        api((cast##CALLBACK) &two_obj_one_int_callback, _##name##_args); \
    }}

    if(py_globals != NULL) {
        void *pyn_callback_helper = pydict_get_item_string(
            py_globals, "_callback_helper");

        CALLBACK_REG1(fini, PIN_AddFiniFunction, FINI_);
        CALLBACK_REG(child, PIN_AddFollowChildProcessFunction);
        CALLBACK_REG1(img_load, IMG_AddInstrumentFunction, IMAGE);
        CALLBACK_REG1EX(img_load2, Image, IMG_AddInstrumentFunction, IMAGE);
        CALLBACK_REG1(img_unload, IMG_AddUnloadFunction, IMAGE);
        CALLBACK_REG1EX(img_unload2, Image, IMG_AddUnloadFunction, IMAGE);
        CALLBACK_REG1(routine, RTN_AddInstrumentFunction, RTN_INSTRUMENT_);
        CALLBACK_REG1EX(routine2, Routine,
            RTN_AddInstrumentFunction, RTN_INSTRUMENT_);
        CALLBACK_REG1(trace, TRACE_AddInstrumentFunction, TRACE_INSTRUMENT_);
        CALLBACK_REG1EX(trace2, Trace,
            TRACE_AddInstrumentFunction, TRACE_INSTRUMENT_);
        CALLBACK_REG1(instr, INS_AddInstrumentFunction, INS_INSTRUMENT_);
        CALLBACK_REG1EX(instr2, Instruction,
            INS_AddInstrumentFunction, INS_INSTRUMENT_);
        CALLBACK_REG(syscall_entry, PIN_AddSyscallEntryFunction);
        CALLBACK_REG(syscall_exit, PIN_AddSyscallExitFunction);
    }

    PIN_StartProgram();
    py_fini();
    return 0;
}