diff --git a/mkstubs.pl b/mkstubs.pl index 32ea50f..db84ce1 100644 --- a/mkstubs.pl +++ b/mkstubs.pl @@ -112,6 +112,10 @@ END print CODE <<"END"; section .data + +global _stubs_enable_profile +_stubs_enable_profile: db 0 + END foreach my $func(@stubs) @@ -167,6 +171,11 @@ foreach my $func(@stubs) $func->{name}_go: + ; Bypass the profiling code and jump straight into the taget + ; function when not profiling. + cmp byte [_stubs_enable_profile], 0 + je $func->{name}_skip + push ebp mov ebp, esp @@ -203,7 +212,6 @@ END } print CODE <<"END"; - ; Call target function call [$func->{name}_addr] @@ -236,6 +244,9 @@ END pop ebp ; Restore caller's ebp ret $func->{params} + + $func->{name}_skip: + jmp [$func->{name}_addr] END } else{ diff --git a/src/common.h b/src/common.h index d67188f..69e88bd 100644 --- a/src/common.h +++ b/src/common.h @@ -44,6 +44,7 @@ extern enum ipx_log_level min_log_level; extern struct FuncStats stub_fstats[]; extern const unsigned int NUM_STUBS; extern const char *STUBS_DLL_NAME; +extern unsigned char stubs_enable_profile; const char *w32_error(DWORD errnum); diff --git a/src/config.c b/src/config.c index 296cfe0..15e6e21 100644 --- a/src/config.c +++ b/src/config.c @@ -33,6 +33,7 @@ main_config_t get_main_config(void) config.encap_type = ENCAP_TYPE_IPXWRAPPER; config.frame_type = FRAME_TYPE_ETH_II; config.log_level = LOG_INFO; + config.profile = false; config.dosbox_server_addr = NULL; config.dosbox_server_port = 213; @@ -59,6 +60,7 @@ main_config_t get_main_config(void) config.encap_type = reg_get_dword(reg, "use_pcap", config.encap_type); config.frame_type = reg_get_dword(reg, "frame_type", config.frame_type); config.log_level = reg_get_dword(reg, "log_level", config.log_level); + config.profile = reg_get_dword(reg, "profile", config.profile); config.dosbox_server_addr = reg_get_string(reg, "dosbox_server_addr", ""); config.dosbox_server_port = reg_get_dword(reg, "dosbox_server_port", config.dosbox_server_port); @@ -91,6 +93,7 @@ bool set_main_config(const main_config_t *config) && reg_set_dword(reg, "use_pcap", config->encap_type) && reg_set_dword(reg, "frame_type", config->frame_type) && reg_set_dword(reg, "log_level", config->log_level) + && reg_set_dword(reg, "profile", config->profile) && reg_set_string(reg, "dosbox_server_addr", config->dosbox_server_addr) && reg_set_dword(reg, "dosbox_server_port", config->dosbox_server_port); diff --git a/src/config.h b/src/config.h index 2b67d67..b815f31 100644 --- a/src/config.h +++ b/src/config.h @@ -52,6 +52,7 @@ typedef struct main_config { uint16_t dosbox_server_port; enum ipx_log_level log_level; + bool profile; } main_config_t; struct v1_global_config { diff --git a/src/ipxconfig.cpp b/src/ipxconfig.cpp index db593a4..e70da19 100644 --- a/src/ipxconfig.cpp +++ b/src/ipxconfig.cpp @@ -1,5 +1,5 @@ /* IPXWrapper - Configuration tool - * Copyright (C) 2011-2022 Daniel Collins + * Copyright (C) 2011-2023 Daniel Collins * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -41,6 +41,7 @@ enum { ID_OPT_W95 = 22, ID_OPT_LOG_DEBUG = 25, ID_OPT_LOG_TRACE = 26, + ID_OPT_PROFILE = 27, ID_OK = 31, ID_CANCEL = 32, @@ -142,6 +143,7 @@ static struct { HWND opt_w95; HWND opt_log_debug; HWND opt_log_trace; + HWND opt_profile; HWND ok_btn; HWND can_btn; @@ -588,6 +590,8 @@ static bool save_config() } } + main_config.profile = get_checkbox(wh.opt_profile); + if(main_config.encap_type == ENCAP_TYPE_IPXWRAPPER || main_config.encap_type == ENCAP_TYPE_PCAP) { for(auto i = nics.begin(); i != nics.end(); i++) @@ -796,6 +800,7 @@ static void main_window_init() * | □ Enable Windows 95 SO_BROADCAST bug | * | □ Log debugging messages | * | □ Log WinSock API calls | + * | □ Log profiling counters | * +---------------------------------------------------------+ */ @@ -805,10 +810,12 @@ static void main_window_init() wh.opt_w95 = create_checkbox(wh.box_options, "Enable Windows 95 SO_BROADCAST bug", ID_OPT_W95); wh.opt_log_debug = create_checkbox(wh.box_options, "Log debugging messages", ID_OPT_LOG_DEBUG); wh.opt_log_trace = create_checkbox(wh.box_options, "Log WinSock API calls", ID_OPT_LOG_TRACE); + wh.opt_profile = create_checkbox(wh.box_options, "Log profiling counters", ID_OPT_PROFILE); set_checkbox(wh.opt_w95, main_config.w95_bug); set_checkbox(wh.opt_log_debug, main_config.log_level <= LOG_DEBUG); set_checkbox(wh.opt_log_trace, main_config.log_level <= LOG_CALL); + set_checkbox(wh.opt_profile, main_config.profile); } wh.ok_btn = create_child(wh.main, "BUTTON", "OK", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_OK); @@ -982,6 +989,9 @@ static void main_window_init() MoveWindow(wh.opt_log_trace, BOX_SIDE_PAD, box_options_y, BOX_INNER_WIDTH, text_h, TRUE); box_options_y += text_h + 2; + MoveWindow(wh.opt_profile, BOX_SIDE_PAD, box_options_y, BOX_INNER_WIDTH, text_h, TRUE); + box_options_y += text_h + 2; + int box_options_h = box_options_y + BOX_BOTTOM_PAD; MoveWindow(wh.box_options, BOX_SIDE_MARGIN, 0, BOX_WIDTH, box_options_h, TRUE); diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index 0892d0b..1cebd5f 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -133,29 +133,34 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) router_init(); - prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); - if(prof_thread_exit != NULL) + if(main_config.profile) { - prof_thread_handle = CreateThread( - NULL, /* lpThreadAttributes */ - 0, /* dwStackSize */ - &prof_thread_main, /* lpStartAddress */ - NULL, /* lpParameter */ - 0, /* dwCreationFlags */ - NULL); /* lpThreadId */ + stubs_enable_profile = true; - if(prof_thread_handle == NULL) + prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); + if(prof_thread_exit != NULL) { + prof_thread_handle = CreateThread( + NULL, /* lpThreadAttributes */ + 0, /* dwStackSize */ + &prof_thread_main, /* lpStartAddress */ + NULL, /* lpParameter */ + 0, /* dwCreationFlags */ + NULL); /* lpThreadId */ + + if(prof_thread_handle == NULL) + { + log_printf(LOG_ERROR, + "Unable to create prof_thread_main thread: %s", + w32_error(GetLastError())); + } + } + else{ log_printf(LOG_ERROR, - "Unable to create prof_thread_main thread: %s", + "Unable to create prof_thread_exit event object: %s", w32_error(GetLastError())); } } - else{ - log_printf(LOG_ERROR, - "Unable to create prof_thread_exit event object: %s", - w32_error(GetLastError())); - } } else if(fdwReason == DLL_PROCESS_DETACH) { @@ -197,8 +202,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) unload_dlls(); - fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); - fprof_report("ipxwrapper.dll", ipxwrapper_fstats, ipxwrapper_fstats_size); + if(main_config.profile) + { + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + fprof_report("ipxwrapper.dll", ipxwrapper_fstats, ipxwrapper_fstats_size); + } log_close(); diff --git a/src/stubdll.c b/src/stubdll.c index a6f9f0d..05914e6 100644 --- a/src/stubdll.c +++ b/src/stubdll.c @@ -1,5 +1,5 @@ /* IPXWrapper - Stub DLL functions - * Copyright (C) 2008-2019 Daniel Collins + * Copyright (C) 2008-2023 Daniel Collins * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by @@ -35,31 +35,38 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { log_open("ipxwrapper.log"); - min_log_level = get_main_config().log_level; + main_config_t config = get_main_config(); - prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); - if(prof_thread_exit != NULL) + min_log_level = config.log_level; + + if(config.profile) { - prof_thread_handle = CreateThread( - NULL, /* lpThreadAttributes */ - 0, /* dwStackSize */ - &prof_thread_main, /* lpStartAddress */ - NULL, /* lpParameter */ - 0, /* dwCreationFlags */ - NULL); /* lpThreadId */ + stubs_enable_profile = true; - if(prof_thread_handle == NULL) + prof_thread_exit = CreateEvent(NULL, FALSE, FALSE, NULL); + if(prof_thread_exit != NULL) { + prof_thread_handle = CreateThread( + NULL, /* lpThreadAttributes */ + 0, /* dwStackSize */ + &prof_thread_main, /* lpStartAddress */ + NULL, /* lpParameter */ + 0, /* dwCreationFlags */ + NULL); /* lpThreadId */ + + if(prof_thread_handle == NULL) + { + log_printf(LOG_ERROR, + "Unable to create prof_thread_main thread: %s", + w32_error(GetLastError())); + } + } + else{ log_printf(LOG_ERROR, - "Unable to create prof_thread_main thread: %s", + "Unable to create prof_thread_exit event object: %s", w32_error(GetLastError())); } } - else{ - log_printf(LOG_ERROR, - "Unable to create prof_thread_exit event object: %s", - w32_error(GetLastError())); - } } else if(fdwReason == DLL_PROCESS_DETACH) { @@ -91,7 +98,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { unload_dlls(); - fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + if(stubs_enable_profile) + { + fprof_report(STUBS_DLL_NAME, stub_fstats, NUM_STUBS); + } log_close();