From 56f2d523dd8d487f49252621b6dbf78e4ad2a99e Mon Sep 17 00:00:00 2001 From: Sepalani Date: Sun, 21 May 2017 01:00:36 +0100 Subject: [PATCH] PPCSymbolDB: Split SaveMap function Rewrite the code map file generation --- Source/Core/Core/PowerPC/PPCSymbolDB.cpp | 133 +++++++----------- Source/Core/Core/PowerPC/PPCSymbolDB.h | 9 +- .../Debugger/CodeWindowFunctions.cpp | 13 +- 3 files changed, 68 insertions(+), 87 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp index 32f09ae6d6..5eecab2448 100644 --- a/Source/Core/Core/PowerPC/PPCSymbolDB.cpp +++ b/Source/Core/Core/PowerPC/PPCSymbolDB.cpp @@ -394,90 +394,65 @@ bool PPCSymbolDB::LoadMap(const std::string& filename, bool bad) return true; } -// =================================================== -/* Save the map file and save a code file */ -// ---------------- -bool PPCSymbolDB::SaveMap(const std::string& filename, bool WithCodes) const +// Save symbol map similar to CodeWarrior's map file +bool PPCSymbolDB::SaveSymbolMap(const std::string& filename) const { - // Format the name for the codes version - std::string mapFile = filename; - if (WithCodes) - mapFile = mapFile.substr(0, mapFile.find_last_of(".")) + "_code.map"; - - // Check size - const int wxYES_NO = 0x00000002 | 0x00000008; - if (functions.size() == 0) - { - if (!AskYesNo( - StringFromFormat( - "No symbol names are generated. Do you want to replace '%s' with a blank file?", - mapFile.c_str()) - .c_str(), - "Confirm", wxYES_NO)) - return false; - } - - // Make a file - File::IOFile f(mapFile, "w"); + File::IOFile f(filename, "w"); if (!f) return false; - // -------------------------------------------------------------------- - // Walk through every code row - // ------------------------- - fprintf(f.GetHandle(), ".text\n"); // Write ".text" at the top - XFuncMap::const_iterator itr = functions.begin(); - u32 LastAddress = 0x80004000; - std::string LastSymbolName; - while (itr != functions.end()) + // Write ".text" at the top + fprintf(f.GetHandle(), ".text\n"); + + // Write symbol address, size, virtual address, alignment, name + for (const auto& function : functions) { - // Save a map file - const Symbol& rSymbol = itr->second; - if (!WithCodes) - { - fprintf(f.GetHandle(), "%08x %08x %08x %i %s\n", rSymbol.address, rSymbol.size, - rSymbol.address, 0, rSymbol.name.c_str()); - ++itr; - } - - // Save a code file - else - { - // Get the current and next address - LastAddress = rSymbol.address; - LastSymbolName = rSymbol.name; - ++itr; - - /* To make nice straight lines we fill out the name with spaces, we also cut off - all names longer than 25 letters */ - std::string TempSym; - for (u32 i = 0; i < 25; i++) - { - if (i < LastSymbolName.size()) - TempSym += LastSymbolName[i]; - else - TempSym += " "; - } - - // We currently skip the last block because we don't know how long it goes - int space; - if (itr != functions.end()) - space = itr->second.address - LastAddress; - else - space = 0; - - for (int i = 0; i < space; i += 4) - { - int Address = LastAddress + i; - - std::string disasm = debugger->Disassemble(Address); - fprintf(f.GetHandle(), "%08x %i %20s %s\n", Address, 0, TempSym.c_str(), disasm.c_str()); - } - // Write a blank line after each block - fprintf(f.GetHandle(), "\n"); - } + const Symbol& symbol = function.second; + fprintf(f.GetHandle(), "%08x %08x %08x %i %s\n", symbol.address, symbol.size, symbol.address, 0, + symbol.name.c_str()); + } + return true; +} + +// Save code map (won't work if Core is running) +// +// Notes: +// - Dolphin doesn't load back code maps +// - It's a custom code map format +bool PPCSymbolDB::SaveCodeMap(const std::string& filename) const +{ + constexpr int SYMBOL_NAME_LIMIT = 30; + File::IOFile f(filename, "w"); + if (!f) + return false; + + // Write ".text" at the top + fprintf(f.GetHandle(), ".text\n"); + + u32 next_address = 0; + for (const auto& function : functions) + { + const Symbol& symbol = function.second; + + // Skip functions which are inside bigger functions + if (symbol.address + symbol.size <= next_address) + { + // At least write the symbol name and address + fprintf(f.GetHandle(), "// %08x beginning of %s\n", symbol.address, symbol.name.c_str()); + continue; + } + + // Write the symbol full name + fprintf(f.GetHandle(), "\n%s:\n", symbol.name.c_str()); + next_address = symbol.address + symbol.size; + + // Write the code + for (u32 address = symbol.address; address < next_address; address += 4) + { + const std::string disasm = debugger->Disassemble(address); + fprintf(f.GetHandle(), "%08x %-*.*s %s\n", address, SYMBOL_NAME_LIMIT, SYMBOL_NAME_LIMIT, + symbol.name.c_str(), disasm.c_str()); + } } - return true; } -// =========== diff --git a/Source/Core/Core/PowerPC/PPCSymbolDB.h b/Source/Core/Core/PowerPC/PPCSymbolDB.h index 240f6ce83c..65cc5b751e 100644 --- a/Source/Core/Core/PowerPC/PPCSymbolDB.h +++ b/Source/Core/Core/PowerPC/PPCSymbolDB.h @@ -16,9 +16,6 @@ // This has functionality overlapping Debugger_Symbolmap. Should merge that stuff in here later. class PPCSymbolDB : public SymbolDB { -private: - DebugInterface* debugger; - public: typedef void (*functionGetterCallback)(Symbol* f); @@ -36,11 +33,15 @@ public: void FillInCallers(); bool LoadMap(const std::string& filename, bool bad = false); - bool SaveMap(const std::string& filename, bool WithCodes = false) const; + bool SaveSymbolMap(const std::string& filename) const; + bool SaveCodeMap(const std::string& filename) const; void PrintCalls(u32 funcAddr) const; void PrintCallers(u32 funcAddr) const; void LogFunctionCall(u32 addr); + +private: + DebugInterface* debugger; }; extern PPCSymbolDB g_symbolDB; diff --git a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp index aaecd03d02..ffca4d0273 100644 --- a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp @@ -287,7 +287,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) } break; case IDM_SAVEMAPFILE: - g_symbolDB.SaveMap(writable_map_file); + g_symbolDB.SaveSymbolMap(writable_map_file); break; case IDM_SAVE_MAP_FILE_AS: { @@ -297,12 +297,17 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this); if (!path.IsEmpty()) - g_symbolDB.SaveMap(WxStrToStr(path)); + g_symbolDB.SaveSymbolMap(WxStrToStr(path)); } break; case IDM_SAVE_MAP_FILE_WITH_CODES: - g_symbolDB.SaveMap(writable_map_file, true); - break; + { + // Format the name for the codes version + const std::string path = + writable_map_file.substr(0, writable_map_file.find_last_of(".")) + "_code.map"; + g_symbolDB.SaveCodeMap(path); + } + break; case IDM_RENAME_SYMBOLS: {