BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { if (dwReason == DLL_PROCESS_ATTACH) { } else if (dwReason == DLL_PROCESS_DETACH) { gdb_deinit(); } return TRUE; // ok }
static u8 gdb_read_byte() { ssize_t res; u8 c = '+'; res = recv(sock, &c, 1, MSG_WAITALL); if (res != 1) { ERROR_LOG(GDB_STUB, "recv failed : %ld", res); gdb_deinit(); } return c; }
//-------------------------------------------------------------------------- // Terminate PPC debugger plugin static void term_plugin(void) { gdb_deinit(); for (int k = 0; k < custom_format_count; ++k) { if (!unregister_custom_data_format(0, (int)custom_formats[k].ud)) msg("---: %d - Could not unregister custom format: %s - %lld bytes - %d wide\n", (uint32)k, custom_formats[k].name, (uint64)custom_formats[k].value_size, (uint32)custom_formats[k].text_width); else msg("---: %d - Unregistered custom format: %s - %lld bytes - %d wide\n", (uint32)k, custom_formats[k].name, (uint64)custom_formats[k].value_size, (uint32)custom_formats[k].text_width); custom_formats[k].ud = (void*)-1; } }
static void gdb_reply(const char* reply) { u8 chk; u32 left; u8* ptr; int n; if (!gdb_active()) return; memset(cmd_bfr, 0, sizeof cmd_bfr); cmd_len = strlen(reply); if (cmd_len + 4 > sizeof cmd_bfr) ERROR_LOG(GDB_STUB, "cmd_bfr overflow in gdb_reply"); memcpy(cmd_bfr + 1, reply, cmd_len); cmd_len++; chk = gdb_calc_chksum(); cmd_len--; cmd_bfr[0] = GDB_STUB_START; cmd_bfr[cmd_len + 1] = GDB_STUB_END; cmd_bfr[cmd_len + 2] = nibble2hex(chk >> 4); cmd_bfr[cmd_len + 3] = nibble2hex(chk); DEBUG_LOG(GDB_STUB, "gdb: reply (len: %d): %s", cmd_len, cmd_bfr); ptr = cmd_bfr; left = cmd_len + 4; while (left > 0) { n = send(sock, ptr, left, 0); if (n < 0) { ERROR_LOG(GDB_STUB, "gdb: send failed"); return gdb_deinit(); } left -= n; ptr += n; } }
void fail(const char *a, ...) { char msg[1024]; va_list va; va_start(va, a); vsnprintf(msg, sizeof msg, a, va); perror(msg); #ifdef FAIL_DUMP_REGS dump_regs(); #endif #ifdef FAIL_DUMP_LS dump_ls(); #endif gdb_deinit(); exit(1); }
void gdb_handle_exception() { while (gdb_active()) { if (!gdb_data_available()) continue; gdb_read_command(); if (cmd_len == 0) continue; switch (cmd_bfr[0]) { case 'q': gdb_handle_query(); break; case 'H': gdb_handle_set_thread(); break; case '?': gdb_handle_signal(); break; case 'k': gdb_deinit(); INFO_LOG(GDB_STUB, "killed by gdb"); return; case 'g': gdb_read_registers(); break; case 'G': gdb_write_registers(); break; case 'p': gdb_read_register(); break; case 'P': gdb_write_register(); break; case 'm': gdb_read_mem(); break; case 'M': gdb_write_mem(); PowerPC::ppcState.iCache.Reset(); Host_UpdateDisasmDialog(); break; case 's': gdb_step(); return; case 'C': case 'c': gdb_continue(); return; case 'z': gdb_remove_bp(); break; case 'Z': _gdb_add_bp(); break; default: gdb_reply(""); break; } } }
// Initialize and create emulation thread // Call browser: Init():s_emu_thread(). // See the BootManager.cpp file description for a complete call schedule. void EmuThread() { const SCoreStartupParameter& core_parameter = SConfig::GetInstance().m_LocalCoreStartupParameter; Common::SetCurrentThreadName("Emuthread - Starting"); if (SConfig::GetInstance().m_OCEnable) DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000); DisplayMessage(cpu_info.brand_string, 8000); DisplayMessage(cpu_info.Summarize(), 8000); DisplayMessage(core_parameter.m_strFilename, 3000); Movie::Init(); HW::Init(); if (!g_video_backend->Initialize(s_window_handle)) { PanicAlert("Failed to initialize video backend!"); Host_Message(WM_USER_STOP); return; } OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); if (cpu_info.HTT) SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = cpu_info.num_cores > 4; else SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPThread = cpu_info.num_cores > 2; if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread)) { HW::Shutdown(); g_video_backend->Shutdown(); PanicAlert("Failed to initialize DSP emulator!"); Host_Message(WM_USER_STOP); return; } Keyboard::Initialize(s_window_handle); Pad::Initialize(s_window_handle); // Load and Init Wiimotes - only if we are booting in Wii mode if (core_parameter.bWii) { Wiimote::Initialize(s_window_handle, !s_state_filename.empty()); // Activate Wiimotes which don't have source set to "None" for (unsigned int i = 0; i != MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true); } AudioCommon::InitSoundStream(); // The hardware is initialized. s_hardware_initialized = true; // Boot to pause or not Core::SetState(core_parameter.bBootToPause ? Core::CORE_PAUSE : Core::CORE_RUN); // Load GCM/DOL/ELF whatever ... we boot with the interpreter core PowerPC::SetMode(PowerPC::MODE_INTERPRETER); CBoot::BootUp(); // Setup our core, but can't use dynarec if we are compare server if (core_parameter.iCPUCore != SCoreStartupParameter::CORE_INTERPRETER && (!core_parameter.bRunCompareServer || core_parameter.bRunCompareClient)) { PowerPC::SetMode(PowerPC::MODE_JIT); } else { PowerPC::SetMode(PowerPC::MODE_INTERPRETER); } // Update the window again because all stuff is initialized Host_UpdateDisasmDialog(); Host_UpdateMainFrame(); // Determine the CPU thread function void (*cpuThreadFunc)(void); if (core_parameter.m_BootType == SCoreStartupParameter::BOOT_DFF) cpuThreadFunc = FifoPlayerThread; else cpuThreadFunc = CpuThread; // ENTER THE VIDEO THREAD LOOP if (core_parameter.bCPUThread) { // This thread, after creating the EmuWindow, spawns a CPU // thread, and then takes over and becomes the video thread Common::SetCurrentThreadName("Video thread"); g_video_backend->Video_Prepare(); // Spawn the CPU thread s_cpu_thread = std::thread(cpuThreadFunc); // become the GPU thread g_video_backend->Video_EnterLoop(); // We have now exited the Video Loop INFO_LOG(CONSOLE, "%s", StopMessage(false, "Video Loop Ended").c_str()); } else // SingleCore mode { // The spawned CPU Thread also does the graphics. // The EmuThread is thus an idle thread, which sleeps while // waiting for the program to terminate. Without this extra // thread, the video backend window hangs in single core mode // because no one is pumping messages. Common::SetCurrentThreadName("Emuthread - Idle"); // Spawn the CPU+GPU thread s_cpu_thread = std::thread(cpuThreadFunc); while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) { g_video_backend->PeekMessages(); Common::SleepCurrentThread(20); } } INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping Emu thread ...").c_str()); // Wait for s_cpu_thread to exit INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping CPU-GPU thread ...").c_str()); #ifdef USE_GDBSTUB INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping GDB ...").c_str()); gdb_deinit(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str()); #endif s_cpu_thread.join(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str()); if (core_parameter.bCPUThread) g_video_backend->Video_Cleanup(); VolumeHandler::EjectVolume(); FileMon::Close(); // Stop audio thread - Actually this does nothing when using HLE // emulation, but stops the DSP Interpreter when using LLE emulation. DSP::GetDSPEmulator()->DSP_StopSoundStream(); // We must set up this flag before executing HW::Shutdown() s_hardware_initialized = false; INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); HW::Shutdown(); INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); Wiimote::Shutdown(); Keyboard::Shutdown(); Pad::Shutdown(); g_video_backend->Shutdown(); AudioCommon::ShutdownSoundStream(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "Main Emu thread stopped").c_str()); // Clear on screen messages that haven't expired g_video_backend->Video_ClearMessages(); // Reload sysconf file in order to see changes committed during emulation if (core_parameter.bWii) SConfig::GetInstance().m_SYSCONF->Reload(); INFO_LOG(CONSOLE, "Stop [Video Thread]\t\t---- Shutdown complete ----"); Movie::Shutdown(); PatchEngine::Shutdown(); s_is_stopping = false; if (s_on_stopped_callback) s_on_stopped_callback(); }
int main(int argc, char *argv[]) { u32 done; memset(&_ctx, 0x00, sizeof _ctx); ctx = &_ctx; parse_args(argc, argv); #if 0 u64 local_ptr; local_ptr = 0xdead0000dead0000ULL; ctx->reg[3][0] = (u32)(local_ptr >> 32); ctx->reg[3][1] = (u32)local_ptr; ctx->reg[4][0] = 0xdead0000; ctx->reg[4][1] = 0xdead0000; #endif ctx->ls = (u8*)malloc(LS_SIZE); if (ctx->ls == NULL) fail("Unable to allocate local storage."); memset(ctx->ls, 0, LS_SIZE); #if 0 wbe64(ctx->ls + 0x3f000, 0x100000000ULL); wbe32(ctx->ls + 0x3f008, 0x10000); wbe32(ctx->ls + 0x3e000, 0xff); #endif if (gdb_port < 0) { ctx->paused = 0; } else { gdb_init(gdb_port); ctx->paused = 1; gdb_signal(SIGABRT); } elf_load(elf_path); setup_context(); done = 0; while(done == 0) { if (ctx->paused == 0 || ctx->paused == 2) done = emulate(); // data watchpoints if (done == 2) { ctx->paused = 0; gdb_signal(SIGTRAP); done = 0; } if (done != 0) { printf("emulated() returned, sending SIGSEGV to gdb stub\n"); ctx->paused = 1; done = gdb_signal(SIGSEGV); } if (done != 0) { #ifdef STOP_DUMP_REGS dump_regs(); #endif #ifdef STOP_DUMP_LS dump_ls(); #endif } //if (ctx->paused == 1) gdb_handle_events(); } printf("emulate() returned. we're done!\n"); dump_ls(); free(ctx->ls); gdb_deinit(); return 0; }
// Initalize and create emulation thread // Call browser: Init():g_EmuThread(). // See the BootManager.cpp file description for a complete call schedule. void EmuThread() { const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; Common::SetCurrentThreadName("Emuthread - Starting"); DisplayMessage(cpu_info.brand_string, 8000); DisplayMessage(cpu_info.Summarize(), 8000); DisplayMessage(_CoreParameter.m_strFilename, 3000); if (cpu_info.IsUnsafe() && (NetPlay::IsNetPlayRunning() || Movie::IsRecordingInput() || Movie::IsPlayingInput())) { PanicAlertT("Warning: Netplay/movies will desync because your CPU does not support DAZ and Dolphin does not emulate it anymore."); } Movie::Init(); HW::Init(); if (!g_video_backend->Initialize(g_pWindowHandle)) { PanicAlert("Failed to initialize video backend!"); Host_Message(WM_USER_STOP); return; } OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, _CoreParameter.bWii, _CoreParameter.bDSPThread)) { HW::Shutdown(); g_video_backend->Shutdown(); PanicAlert("Failed to initialize DSP emulator!"); Host_Message(WM_USER_STOP); return; } Pad::Initialize(g_pWindowHandle); // Load and Init Wiimotes - only if we are booting in wii mode if (g_CoreStartupParameter.bWii) { Wiimote::Initialize(g_pWindowHandle, !g_stateFileName.empty()); // Activate wiimotes which don't have source set to "None" for (unsigned int i = 0; i != MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true); } AudioCommon::InitSoundStream(g_pWindowHandle); // The hardware is initialized. g_bHwInit = true; // Boot to pause or not Core::SetState(_CoreParameter.bBootToPause ? Core::CORE_PAUSE : Core::CORE_RUN); // Load GCM/DOL/ELF whatever ... we boot with the interpreter core PowerPC::SetMode(PowerPC::MODE_INTERPRETER); CBoot::BootUp(); // Setup our core, but can't use dynarec if we are compare server if (_CoreParameter.iCPUCore && (!_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)) PowerPC::SetMode(PowerPC::MODE_JIT); else PowerPC::SetMode(PowerPC::MODE_INTERPRETER); // Update the window again because all stuff is initialized Host_UpdateDisasmDialog(); Host_UpdateMainFrame(); // Determine the cpu thread function void (*cpuThreadFunc)(void); if (_CoreParameter.m_BootType == SCoreStartupParameter::BOOT_DFF) cpuThreadFunc = FifoPlayerThread; else cpuThreadFunc = CpuThread; // ENTER THE VIDEO THREAD LOOP if (_CoreParameter.bCPUThread) { // This thread, after creating the EmuWindow, spawns a CPU // thread, and then takes over and becomes the video thread Common::SetCurrentThreadName("Video thread"); g_video_backend->Video_Prepare(); // Spawn the CPU thread g_cpu_thread = std::thread(cpuThreadFunc); // become the GPU thread g_video_backend->Video_EnterLoop(); // We have now exited the Video Loop INFO_LOG(CONSOLE, "%s", StopMessage(false, "Video Loop Ended").c_str()); } else // SingleCore mode { // The spawned CPU Thread also does the graphics. // The EmuThread is thus an idle thread, which sleeps while // waiting for the program to terminate. Without this extra // thread, the video backend window hangs in single core mode // because noone is pumping messages. Common::SetCurrentThreadName("Emuthread - Idle"); // Spawn the CPU+GPU thread g_cpu_thread = std::thread(cpuThreadFunc); while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) { g_video_backend->PeekMessages(); Common::SleepCurrentThread(20); } } // Wait for g_cpu_thread to exit INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping CPU-GPU thread ...").c_str()); #ifdef USE_GDBSTUB INFO_LOG(CONSOLE, "%s", StopMessage(true, "Stopping GDB ...").c_str()); gdb_deinit(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "GDB stopped.").c_str()); #endif g_cpu_thread.join(); INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str()); if (_CoreParameter.bCPUThread) g_video_backend->Video_Cleanup(); VolumeHandler::EjectVolume(); FileMon::Close(); // Stop audio thread - Actually this does nothing when using HLE // emulation, but stops the DSP Interpreter when using LLE emulation. DSP::GetDSPEmulator()->DSP_StopSoundStream(); // We must set up this flag before executing HW::Shutdown() g_bHwInit = false; INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); HW::Shutdown(); INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); Pad::Shutdown(); Wiimote::Shutdown(); g_video_backend->Shutdown(); AudioCommon::ShutdownSoundStream(); }