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; }
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; }