Add "Load bad map file" option for map files on disc that don't quite match.

Currently it is very simple and naive, but filters out most of the bad matches.
This commit is contained in:
CarlKenner 2014-12-15 10:13:45 +10:30
parent f54d9e33c2
commit e246aaf419
6 changed files with 125 additions and 2 deletions

View File

@ -269,6 +269,101 @@ bool PPCSymbolDB::LoadMap(const std::string& filename)
return true;
}
// Carefully load map files that might not be from exactly the right version
bool PPCSymbolDB::LoadBadMap(const std::string& filename)
{
File::IOFile f(filename, "r");
if (!f)
return false;
bool started = false;
int good_count = 0, bad_count = 0;
char line[512];
while (fgets(line, 512, f.GetHandle()))
{
if (strlen(line) < 4)
continue;
char temp[256];
sscanf(line, "%255s", temp);
if (strcmp(temp, "UNUSED") == 0) continue;
if (strcmp(temp, ".text") == 0) { started = true; continue; };
if (strcmp(temp, ".init") == 0) { started = true; continue; };
if (strcmp(temp, "Starting") == 0) continue;
if (strcmp(temp, "extab") == 0) continue;
if (strcmp(temp, ".ctors") == 0) break; //uh?
if (strcmp(temp, ".dtors") == 0) break;
if (strcmp(temp, ".rodata") == 0) continue;
if (strcmp(temp, ".data") == 0) continue;
if (strcmp(temp, ".sbss") == 0) continue;
if (strcmp(temp, ".sdata") == 0) continue;
if (strcmp(temp, ".sdata2") == 0) continue;
if (strcmp(temp, "address") == 0) continue;
if (strcmp(temp, "-----------------------") == 0) continue;
if (strcmp(temp, ".sbss2") == 0) break;
if (temp[1] == ']') continue;
if (!started) continue;
u32 address, vaddress, size, unknown;
char name[512];
// some entries in the table have a function name followed by " (entry of " followed by a container name, followed by ")"
// instead of a space followed by a number followed by a space followed by a name
if (strlen(line) > 27 && line[27] != ' ' && strstr(line, "(entry of "))
{
sscanf(line, "%08x %08x %08x %511s", &address, &size, &vaddress, name);
}
else
{
sscanf(line, "%08x %08x %08x %i %511s", &address, &size, &vaddress, &unknown, name);
}
const char *namepos = strstr(line, name);
if (namepos != nullptr) //would be odd if not :P
strcpy(name, namepos);
name[strlen(name) - 1] = 0;
// we want the function names only .... TODO: or do we really? aren't we wasting information here?
for (size_t i = 0; i < strlen(name); i++)
{
if (name[i] == ' ') name[i] = 0x00;
if (name[i] == '(') name[i] = 0x00;
}
// Check if this is a valid entry.
if (strcmp(name, ".text") != 0 && strcmp(name, ".init") != 0 && strlen(name) > 0)
{
vaddress |= 0x80000000;
// check for BLR before function
u32 opcode = Memory::Read_Instruction(vaddress - 4);
if (opcode == 0x4e800020)
{
// check for BLR at end of function
opcode = Memory::Read_Instruction(vaddress + size - 4);
if (opcode == 0x4e800020)
{
AddKnownSymbol(vaddress, size, name); // ST_FUNCTION
++good_count;
}
else
{
++bad_count;
}
}
else
{
++bad_count;
}
}
}
Index();
PanicAlertT("Loaded %d good functions, ignored %d bad functions", good_count, bad_count);
return true;
}
// ===================================================
/* Save the map file and save a code file */

View File

@ -35,6 +35,7 @@ public:
void FillInCallers();
bool LoadMap(const std::string& filename);
bool LoadBadMap(const std::string& filename);
bool SaveMap(const std::string& filename, bool WithCodes = false) const;
void PrintCalls(u32 funcAddr) const;

View File

@ -754,6 +754,7 @@ void CCodeWindow::UpdateButtonStates()
GetMenuBar()->Enable(IDM_SAVEMAPFILE, Initialized);
GetMenuBar()->Enable(IDM_LOADMAPFILEAS, Initialized);
GetMenuBar()->Enable(IDM_SAVEMAPFILEAS, Initialized);
GetMenuBar()->Enable(IDM_LOADBADMAPFILE, Initialized);
GetMenuBar()->Enable(IDM_SAVEMAPFILEWITHCODES, Initialized);
GetMenuBar()->Enable(IDM_CREATESIGNATUREFILE, Initialized);
GetMenuBar()->Enable(IDM_APPENDSIGNATUREFILE, Initialized);

View File

@ -155,8 +155,11 @@ void CCodeWindow::CreateMenuSymbols(wxMenuBar *pMenuBar)
_("Try to load this game's function names automatically - but doesn't check .map files stored on the disc image yet."));
pSymbolsMenu->Append(IDM_SAVEMAPFILE, _("&Save symbol map"),
_("Save the function names for each address to a .map file in your user settings map folder, named after the title id."));
pSymbolsMenu->AppendSeparator();
pSymbolsMenu->Append(IDM_LOADMAPFILEAS, _("Choose symbol map file to load..."),
_("Load any .map file containing the function names and addresses for this game."));
pSymbolsMenu->Append(IDM_LOADBADMAPFILE, _("Load &bad map file..."),
_("Try to load a .map file that might be from a slightly different version."));
pSymbolsMenu->Append(IDM_SAVEMAPFILEAS, _("Save symbol map &as..."),
_("Save the function names and addresses for this game as a .map file. If you want to open it in IDA pro, use the .idc script."));
pSymbolsMenu->AppendSeparator();
@ -301,6 +304,23 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
NotifyMapLoaded();
}
break;
case IDM_LOADBADMAPFILE:
{
const wxString path = wxFileSelector(
_("Load bad map file"), File::GetUserPath(D_MAPS_IDX),
title_id_str + ".map", ".map",
"Dolphin Map File (*.map)|*.map|All files (*.*)|*.*",
wxFD_OPEN | wxFD_FILE_MUST_EXIST, this);
if (!path.IsEmpty())
{
g_symbolDB.LoadBadMap(WxStrToStr(path));
Parent->StatusBarMessage("Loaded symbols from '%s'", path.c_str());
}
HLE::PatchFunctions();
NotifyMapLoaded();
}
break;
case IDM_SAVEMAPFILE:
g_symbolDB.SaveMap(writable_map_file);
break;

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!--For some stupid reason this has to be in the .user file...-->
@ -6,4 +6,10 @@
<LocalDebuggerWorkingDirectory>$(BinaryOutputDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-d</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@ -214,7 +214,7 @@ enum
// Symbols
IDM_CLEARSYMBOLS,
IDM_SCANFUNCTIONS,
IDM_LOADMAPFILE, IDM_LOADMAPFILEAS,
IDM_LOADMAPFILE, IDM_LOADMAPFILEAS, IDM_LOADBADMAPFILE,
IDM_SAVEMAPFILE, IDM_SAVEMAPFILEWITHCODES, IDM_SAVEMAPFILEAS,
IDM_CREATESIGNATUREFILE,
IDM_APPENDSIGNATUREFILE,