PPCSymbolDB: Add alignment detection heuristic
Update parse_entry_of in accordance to the sscanf change
This commit is contained in:
parent
024fac84ed
commit
30693773a3
|
@ -18,6 +18,7 @@
|
||||||
#include "Common/IOFile.h"
|
#include "Common/IOFile.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
#include "Common/Unreachable.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Debugger/DebugInterface.h"
|
#include "Core/Debugger/DebugInterface.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
|
@ -310,7 +311,7 @@ bool PPCSymbolDB::LoadMap(const Core::CPUThreadGuard& guard, const std::string&
|
||||||
continue;
|
continue;
|
||||||
column_count = 2;
|
column_count = 2;
|
||||||
|
|
||||||
// Three columns format:
|
// Three columns format (with optional alignment):
|
||||||
// Starting Virtual
|
// Starting Virtual
|
||||||
// address Size address
|
// address Size address
|
||||||
// -----------------------
|
// -----------------------
|
||||||
|
@ -319,7 +320,7 @@ bool PPCSymbolDB::LoadMap(const Core::CPUThreadGuard& guard, const std::string&
|
||||||
else
|
else
|
||||||
iss.str("");
|
iss.str("");
|
||||||
|
|
||||||
// Four columns format:
|
// Four columns format (with optional alignment):
|
||||||
// Starting Virtual File
|
// Starting Virtual File
|
||||||
// address Size address offset
|
// address Size address offset
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -327,75 +328,72 @@ bool PPCSymbolDB::LoadMap(const Core::CPUThreadGuard& guard, const std::string&
|
||||||
column_count = 4;
|
column_count = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 address, vaddress, size, offset, alignment;
|
u32 address;
|
||||||
char name[512];
|
u32 vaddress;
|
||||||
|
u32 size = 0;
|
||||||
|
u32 offset = 0;
|
||||||
|
u32 alignment = 0;
|
||||||
|
char name[512]{};
|
||||||
static constexpr char ENTRY_OF_STRING[] = " (entry of ";
|
static constexpr char ENTRY_OF_STRING[] = " (entry of ";
|
||||||
static constexpr std::string_view ENTRY_OF_VIEW(ENTRY_OF_STRING);
|
static constexpr std::string_view ENTRY_OF_VIEW(ENTRY_OF_STRING);
|
||||||
auto parse_entry_of = [](const char* line, char* name) {
|
auto parse_entry_of = [](char* name) {
|
||||||
const char* s = strstr(line, ENTRY_OF_STRING);
|
if (char* s1 = strstr(name, ENTRY_OF_STRING); s1 != nullptr)
|
||||||
if (s)
|
|
||||||
{
|
{
|
||||||
char container[512];
|
char container[512];
|
||||||
sscanf(s + ENTRY_OF_VIEW.size(), "%511s", container);
|
char* ptr = s1 + ENTRY_OF_VIEW.size();
|
||||||
char* s2 = strchr(container, ')');
|
sscanf(ptr, "%511s", container);
|
||||||
// Skip sections, those start with a dot, e.g. (entry of .text)
|
// Skip sections, those start with a dot, e.g. (entry of .text)
|
||||||
if (s2 && container[0] != '.')
|
if (char* s2 = strchr(container, ')'); s2 != nullptr && *container != '.')
|
||||||
{
|
{
|
||||||
s2[0] = '\0';
|
ptr += strlen(container);
|
||||||
|
// Preserve data after the entry part, usually it contains object names
|
||||||
|
strcpy(s1, ptr);
|
||||||
|
*s2 = '\0';
|
||||||
strcat(container, "::");
|
strcat(container, "::");
|
||||||
strcat(container, name);
|
strcat(container, name);
|
||||||
strcpy(name, container);
|
strcpy(name, container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (column_count == 4)
|
auto was_alignment = [](const char* name) {
|
||||||
|
return *name == ' ' || (*name >= '0' && *name <= '9');
|
||||||
|
};
|
||||||
|
auto parse_alignment = [](char* name, u32* alignment) {
|
||||||
|
const std::string buffer(StripWhitespace(name));
|
||||||
|
return sscanf(buffer.c_str(), "%i %511[^\r\n]", alignment, name);
|
||||||
|
};
|
||||||
|
switch (column_count)
|
||||||
{
|
{
|
||||||
|
case 4:
|
||||||
// sometimes there is no alignment value, and sometimes it is because it is an entry of
|
// sometimes there is no alignment value, and sometimes it is because it is an entry of
|
||||||
// something else
|
// something else
|
||||||
if (length > 37 && line[37] == ' ')
|
sscanf(line, "%08x %08x %08x %08x %511[^\r\n]", &address, &size, &vaddress, &offset, name);
|
||||||
{
|
if (was_alignment(name))
|
||||||
alignment = 0;
|
parse_alignment(name, &alignment);
|
||||||
sscanf(line, "%08x %08x %08x %08x %511s", &address, &size, &vaddress, &offset, name);
|
// The `else` statement was omitted to handle symbol already saved in Dolphin symbol map
|
||||||
parse_entry_of(line, name);
|
// since it doesn't omit the alignment on save for such case.
|
||||||
}
|
parse_entry_of(name);
|
||||||
else
|
break;
|
||||||
{
|
case 3:
|
||||||
sscanf(line, "%08x %08x %08x %08x %i %511s", &address, &size, &vaddress, &offset,
|
|
||||||
&alignment, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (column_count == 3)
|
|
||||||
{
|
|
||||||
// some entries in the table have a function name followed by " (entry of " followed by a
|
// some entries in the table have a function name followed by " (entry of " followed by a
|
||||||
// container name, followed by ")"
|
// container name, followed by ")"
|
||||||
// instead of a space followed by a number followed by a space followed by a name
|
// instead of a space followed by a number followed by a space followed by a name
|
||||||
if (length > 27 && line[27] != ' ' && strstr(line, ENTRY_OF_STRING))
|
sscanf(line, "%08x %08x %08x %511[^\r\n]", &address, &size, &vaddress, name);
|
||||||
{
|
if (was_alignment(name))
|
||||||
alignment = 0;
|
parse_alignment(name, &alignment);
|
||||||
sscanf(line, "%08x %08x %08x %511s", &address, &size, &vaddress, name);
|
// The `else` statement was omitted to handle symbol already saved in Dolphin symbol map
|
||||||
parse_entry_of(line, name);
|
// since it doesn't omit the alignment on save for such case.
|
||||||
}
|
parse_entry_of(name);
|
||||||
else
|
break;
|
||||||
{
|
case 2:
|
||||||
sscanf(line, "%08x %08x %08x %i %511s", &address, &size, &vaddress, &alignment, name);
|
sscanf(line, "%08x %511[^\r\n]", &address, name);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (column_count == 2)
|
|
||||||
{
|
|
||||||
sscanf(line, "%08x %511s", &address, name);
|
|
||||||
vaddress = address;
|
vaddress = address;
|
||||||
size = 0;
|
break;
|
||||||
}
|
default:
|
||||||
else
|
// Should never happen
|
||||||
{
|
Common::Unreachable();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const char* namepos = strstr(line, name);
|
|
||||||
if (namepos != nullptr) // would be odd if not :P
|
|
||||||
strcpy(name, namepos);
|
|
||||||
name[strlen(name) - 1] = 0;
|
|
||||||
if (name[strlen(name) - 1] == '\r')
|
|
||||||
name[strlen(name) - 1] = 0;
|
|
||||||
|
|
||||||
// Split the current name string into separate parts, and get the object name
|
// Split the current name string into separate parts, and get the object name
|
||||||
// if it exists.
|
// if it exists.
|
||||||
|
|
Loading…
Reference in New Issue