#include "stdafx_gui.h" #if 0 #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "DisAsmFrame.h" #include "Emu/FS/vfsLocalFile.h" #include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPCThread.h" #include "Gui/DisAsmFrame.h" #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUDisAsm.h" #include "Emu/Cell/SPUDecoder.h" #include "Emu/Cell/SPUDisAsm.h" DisAsmFrame::DisAsmFrame(PPCThread& cpu) : wxFrame(nullptr, wxID_ANY, "DisAsm") , CPU(cpu) { exit = false; count = 0; wxBoxSizer* s_panel = new wxBoxSizer(wxVERTICAL); wxBoxSizer* s_b_panel = new wxBoxSizer(wxHORIZONTAL); m_disasm_list = new wxListView(this); m_disasm_list->Bind(wxEVT_MOUSEWHEEL, &DisAsmFrame::MouseWheel, this); wxButton* b_fprev = new wxButton(this, wxID_ANY, L"<<"); wxButton* b_prev = new wxButton(this, wxID_ANY, L"<"); wxButton* b_next = new wxButton(this, wxID_ANY, L">"); wxButton* b_fnext = new wxButton(this, wxID_ANY, L">>"); b_fprev->Bind(wxEVT_BUTTON, &DisAsmFrame::fPrev, this); b_prev->Bind(wxEVT_BUTTON, &DisAsmFrame::Prev, this); b_next->Bind(wxEVT_BUTTON, &DisAsmFrame::Next, this); b_fnext->Bind(wxEVT_BUTTON, &DisAsmFrame::fNext, this); wxButton* b_dump = new wxButton(this, wxID_ANY, L"Dump code"); b_dump->Bind(wxEVT_BUTTON, &DisAsmFrame::Dump, this); wxButton* b_setpc = new wxButton(this, wxID_ANY, L"Set PC"); b_setpc->Bind(wxEVT_BUTTON, &DisAsmFrame::SetPc, this); s_b_panel->Add(b_fprev); s_b_panel->Add(b_prev); s_b_panel->AddSpacer(5); s_b_panel->Add(b_next); s_b_panel->Add(b_fnext); s_b_panel->AddSpacer(8); s_b_panel->Add(b_dump); s_panel->Add(s_b_panel); s_panel->Add(b_setpc); s_panel->Add(m_disasm_list); m_disasm_list->InsertColumn(0, "PC"); m_disasm_list->InsertColumn(1, "ASM"); m_disasm_list->SetColumnWidth(0, 50); for(uint i=0; iInsertItem(i, -1); SetSizerAndFit(s_panel); SetSize(50, 660); Bind(wxEVT_SIZE, &DisAsmFrame::OnResize, this); } void DisAsmFrame::OnResize(wxSizeEvent& event) { const wxSize size(GetClientSize()); m_disasm_list->SetSize( size.GetWidth(), size.GetHeight() - 25 ); m_disasm_list->SetColumnWidth( 1, size.GetWidth() - (m_disasm_list->GetColumnWidth(0) + 8) ); event.Skip(); } void DisAsmFrame::AddLine(const wxString line) { static bool finished = false; if(finished && Emu.IsRunning()) { count = 0; finished = false; } else if(count >= LINES_OPCODES || !Emu.IsRunning()) { if(Emu.IsRunning()) Emu.Pause(); finished = true; CPU.PC -= 4; return; } m_disasm_list->SetItem(count, 0, wxString::Format("%x", CPU.PC)); m_disasm_list->SetItem(count, 1, line); ++count; } void DisAsmFrame::Resume() { Emu.Resume(); } #include #include "Loader/ELF.h" #include "Loader/ELF32.h" #include "Loader/ELF64.h" std::vector* shdr_arr_64 = NULL; std::vector* shdr_arr_32 = NULL; ELF64Loader* l_elf64 = NULL; ELF32Loader* l_elf32 = NULL; bool ElfType64 = false; class DumperThread : public ThreadBase { volatile uint id; PPCDisAsm* disasm; PPCDecoder* decoder; volatile bool* done; volatile u8 cores; MTProgressDialog* prog_dial; wxArrayString** arr; public: DumperThread() : ThreadBase("DumperThread") { } void Set(uint _id, u8 _cores, bool* _done, MTProgressDialog& _prog_dial, wxArrayString** _arr) { id = _id; cores = _cores; done = _done; prog_dial = &_prog_dial; arr = _arr; *done = false; if(Emu.GetCPU().GetThreads()[0]->GetType() != CPU_THREAD_PPU) { SPUDisAsm& dis_asm = *new SPUDisAsm(CPUDisAsm_DumpMode); decoder = new SPUDecoder(dis_asm); disasm = &dis_asm; } else { PPUDisAsm* dis_asm = new PPUDisAsm(CPUDisAsm_DumpMode); decoder = new PPUDecoder(dis_asm); disasm = dis_asm; } } virtual void Task() { LOG_NOTICE(HLE, "Start dump in thread %d!", (int)id); const u32 max_value = prog_dial->GetMaxValue(id); const u32 shdr_count = ElfType64 ? shdr_arr_64->size() : shdr_arr_32->size(); for(u32 sh=0, vsize=0; shUpdate(id, vsize, wxString::Format("%d thread: %d of %d", (int)id + 1, vsize, max_value)); disasm->dump_pc = sh_addr + off; decoder->Decode(vm::read32(disasm->dump_pc)); arr[id][sh].Add(fmt::FromUTF8(disasm->last_opcode)); off += (cores - id) * 4; off += id * 4; } } LOG_NOTICE(HLE, "Finish dump in thread %d!", (int)id); *done = true; } void OnExit() { LOG_NOTICE(HLE, "CleanUp dump thread (%d)!", (int)id); safe_delete(decoder); } }; struct WaitDumperThread : public ThreadBase { volatile bool* done; volatile u8 cores; wxString patch; MTProgressDialog& prog_dial; wxArrayString** arr; WaitDumperThread(bool* _done, u8 _cores, wxString _patch, MTProgressDialog& _prog_dial, wxArrayString** _arr) : ThreadBase("WaitDumperThread") , done(_done) , cores(_cores) , patch(_patch) , prog_dial(_prog_dial) , arr(_arr) { } ~WaitDumperThread() { delete (bool*)done; done = NULL; } virtual void Task() { for(uint i=0; isize() : shdr_arr_32->size(); for(uint sh=0, counter=0; sh= cores) { c = 0; v++; } prog_dial2.Update(0, counter, wxString::Format("Saving data to file: %d of %d", counter, length)); if(v >= arr[c][sh].GetCount()) continue; fd.Write("\t"); fd.Write(arr[c][sh][v]); } fd.Write(wxString::Format("End of section header %d\n\n", sh)); } LOG_NOTICE(HLE, "CleanUp dump saving!"); for(uint c=0; c name_arr; switch(ehdr.GetClass()) { case CLASS_ELF64: ElfType64 = true; l_elf64 = new ELF64Loader(f_elf); if(!l_elf64->LoadInfo()) { delete l_elf64; return; } name_arr = l_elf64->shdr_name_arr; shdr_arr_64 = &l_elf64->shdr_arr; if(l_elf64->shdr_arr.size() <= 0) return; break; case CLASS_ELF32: ElfType64 = false; l_elf32 = new ELF32Loader(f_elf); if(!l_elf32->LoadInfo()) { delete l_elf32; return; } name_arr = l_elf32->shdr_name_arr; shdr_arr_32 = &l_elf32->shdr_arr; if(l_elf32->shdr_arr.size() <= 0) return; break; default: LOG_ERROR(HLE, "Corrupted ELF!"); return; } PPCDisAsm* disasm; PPCDecoder* decoder; switch(Emu.GetCPU().GetThreads()[0]->GetType()) { case CPU_THREAD_PPU: { PPUDisAsm* dis_asm = new PPUDisAsm(CPUDisAsm_DumpMode); decoder = new PPUDecoder(dis_asm); disasm = dis_asm; } break; case CPU_THREAD_SPU: case CPU_THREAD_RAW_SPU: { SPUDisAsm& dis_asm = *new SPUDisAsm(CPUDisAsm_DumpMode); decoder = new SPUDecoder(dis_asm); disasm = &dis_asm; } break; } const u32 shdr_count = ElfType64 ? shdr_arr_64->size() : shdr_arr_32->size(); u64 max_count = 0; for(u32 sh=0; shdump_pc = addr; decoder->Decode(vm::read32(disasm->dump_pc)); fd.Write("\t"); fd.Write(fmt::FromUTF8(disasm->last_opcode)); } } fd.Write(wxString::Format("End of section header %s[%d]\n\n", name.c_str(), sh)); } prog_dial.Close(); Emu.Stop(); /* SYSTEM_INFO si; GetSystemInfo(&si); const uint cores_count = (si.dwNumberOfProcessors < 1 || si.dwNumberOfProcessors > 8 ? 2 : si.dwNumberOfProcessors); wxArrayLong max; max.Clear(); u64 max_count = 0; if(ElfType64) { for(uint sh=0; shshdr_arr.GetCount(); ++sh) { max_count += l_elf64->shdr_arr[sh].sh_size / 4; } } else { for(uint sh=0; shshdr_arr.GetCount(); ++sh) { max_count += l_elf32->shdr_arr[sh].sh_size / 4; } } for(uint c=0; cshdr_arr.GetCount() : l_elf32->shdr_arr.GetCount()]; dump[i].Set(i, cores_count, &threads_done[i], prog_dial, arr); dump[i].Start(); } WaitDumperThread& wait_dump = *new WaitDumperThread(threads_done, cores_count, ctrl.GetPath(), prog_dial, arr); wait_dump.Start(); */ } void DisAsmFrame::Prev (wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - 4*(LINES_OPCODES+1)); Resume(); } } void DisAsmFrame::Next (wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - 4*(LINES_OPCODES-1)); Resume(); } } void DisAsmFrame::fPrev(wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { CPU.SetPc( CPU.PC - (4*LINES_OPCODES)*2); Resume(); } } void DisAsmFrame::fNext(wxCommandEvent& WXUNUSED(event)) { if(Emu.IsPaused()) { Resume(); } } void DisAsmFrame::SetPc(wxCommandEvent& WXUNUSED(event)) { if(!Emu.IsPaused()) return; wxDialog diag(this, wxID_ANY, "Set PC", wxDefaultPosition); wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL)); wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); wxTextCtrl* p_pc(new wxTextCtrl(&diag, wxID_ANY)); s_panel->Add(p_pc); s_panel->AddSpacer(8); s_panel->Add(s_b_panel); s_b_panel->Add(new wxButton(&diag, wxID_OK), wxLEFT, 0, 5); s_b_panel->AddSpacer(5); s_b_panel->Add(new wxButton(&diag, wxID_CANCEL), wxRIGHT, 0, 5); diag.SetSizerAndFit( s_panel ); p_pc->SetLabel(wxString::Format("%x", CPU.PC)); if(diag.ShowModal() == wxID_OK) { sscanf(fmt::ToUTF8(p_pc->GetLabel()).c_str(), "%x", &CPU.PC); Resume(); } } void DisAsmFrame::MouseWheel(wxMouseEvent& event) { if(!Emu.IsPaused()) { event.Skip(); return; } const int value = (event.m_wheelRotation / event.m_wheelDelta); if(event.ControlDown()) { CPU.SetPc( CPU.PC - (((4*LINES_OPCODES)*2)*value) ); } else { CPU.SetPc( CPU.PC - 4*(LINES_OPCODES + (value /** event.m_linesPerAction*/)) ); } Emu.Resume(); event.Skip(); } #endif