Adding support for detecting the save/rest fpr and vmx blocks.
This commit is contained in:
parent
e6195c4086
commit
38efd3837d
|
@ -108,6 +108,10 @@ public:
|
|||
enum Flags {
|
||||
kFlagSaveGprLr = 1 << 1,
|
||||
kFlagRestGprLr = 1 << 2,
|
||||
kFlagSaveFpr = 1 << 3,
|
||||
kFlagRestFpr = 1 << 4,
|
||||
kFlagSaveVmx = 1 << 5,
|
||||
kFlagRestVmx = 1 << 6,
|
||||
};
|
||||
|
||||
FunctionSymbol();
|
||||
|
|
|
@ -64,8 +64,8 @@ XexSymbolDatabase::~XexSymbolDatabase() {
|
|||
int XexSymbolDatabase::Analyze() {
|
||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex_);
|
||||
|
||||
// Find __savegprlr_* and __restgprlr_*.
|
||||
FindGplr();
|
||||
// Find __savegprlr_* and __restgprlr_* and the others.
|
||||
FindSaveRest();
|
||||
|
||||
// Add each import thunk.
|
||||
for (size_t n = 0; n < header->import_library_count; n++) {
|
||||
|
@ -84,14 +84,14 @@ int XexSymbolDatabase::Analyze() {
|
|||
return SymbolDatabase::Analyze();
|
||||
}
|
||||
|
||||
int XexSymbolDatabase::FindGplr() {
|
||||
int XexSymbolDatabase::FindSaveRest() {
|
||||
// Special stack save/restore functions.
|
||||
// __savegprlr_14 to __savegprlr_31
|
||||
// __restgprlr_14 to __restgprlr_31
|
||||
// http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/crt/md/ppc/xxx.s.htm
|
||||
// It'd be nice to stash these away and mark them as such to allow for
|
||||
// special codegen.
|
||||
static const uint32_t code_values[] = {
|
||||
// __savegprlr_14 to __savegprlr_31
|
||||
// __restgprlr_14 to __restgprlr_31
|
||||
static const uint32_t gprlr_code_values[] = {
|
||||
0x68FFC1F9, // __savegprlr_14
|
||||
0x70FFE1F9, // __savegprlr_15
|
||||
0x78FF01FA, // __savegprlr_16
|
||||
|
@ -134,8 +134,395 @@ int XexSymbolDatabase::FindGplr() {
|
|||
0xA603887D,
|
||||
0x2000804E,
|
||||
};
|
||||
// __savefpr_14 to __savefpr_31
|
||||
// __restfpr_14 to __restfpr_31
|
||||
static const uint32_t fpr_code_values[] = {
|
||||
0x70FFCCD9, // __savefpr_14
|
||||
0x78FFECD9, // __savefpr_15
|
||||
0x80FF0CDA, // __savefpr_16
|
||||
0x88FF2CDA, // __savefpr_17
|
||||
0x90FF4CDA, // __savefpr_18
|
||||
0x98FF6CDA, // __savefpr_19
|
||||
0xA0FF8CDA, // __savefpr_20
|
||||
0xA8FFACDA, // __savefpr_21
|
||||
0xB0FFCCDA, // __savefpr_22
|
||||
0xB8FFECDA, // __savefpr_23
|
||||
0xC0FF0CDB, // __savefpr_24
|
||||
0xC8FF2CDB, // __savefpr_25
|
||||
0xD0FF4CDB, // __savefpr_26
|
||||
0xD8FF6CDB, // __savefpr_27
|
||||
0xE0FF8CDB, // __savefpr_28
|
||||
0xE8FFACDB, // __savefpr_29
|
||||
0xF0FFCCDB, // __savefpr_30
|
||||
0xF8FFECDB, // __savefpr_31
|
||||
0x2000804E,
|
||||
0x70FFCCC9, // __restfpr_14
|
||||
0x78FFECC9, // __restfpr_15
|
||||
0x80FF0CCA, // __restfpr_16
|
||||
0x88FF2CCA, // __restfpr_17
|
||||
0x90FF4CCA, // __restfpr_18
|
||||
0x98FF6CCA, // __restfpr_19
|
||||
0xA0FF8CCA, // __restfpr_20
|
||||
0xA8FFACCA, // __restfpr_21
|
||||
0xB0FFCCCA, // __restfpr_22
|
||||
0xB8FFECCA, // __restfpr_23
|
||||
0xC0FF0CCB, // __restfpr_24
|
||||
0xC8FF2CCB, // __restfpr_25
|
||||
0xD0FF4CCB, // __restfpr_26
|
||||
0xD8FF6CCB, // __restfpr_27
|
||||
0xE0FF8CCB, // __restfpr_28
|
||||
0xE8FFACCB, // __restfpr_29
|
||||
0xF0FFCCCB, // __restfpr_30
|
||||
0xF8FFECCB, // __restfpr_31
|
||||
0x2000804E,
|
||||
};
|
||||
// __savevmx_14 to __savevmx_31
|
||||
// __savevmx_64 to __savevmx_127
|
||||
// __restvmx_14 to __restvmx_31
|
||||
// __restvmx_64 to __restvmx_127
|
||||
static const uint32_t vmx_code_values[] = {
|
||||
0xE0FE6039, // __savevmx_14
|
||||
0xCE61CB7D,
|
||||
0xF0FE6039,
|
||||
0xCE61EB7D,
|
||||
0x00FF6039,
|
||||
0xCE610B7E,
|
||||
0x10FF6039,
|
||||
0xCE612B7E,
|
||||
0x20FF6039,
|
||||
0xCE614B7E,
|
||||
0x30FF6039,
|
||||
0xCE616B7E,
|
||||
0x40FF6039,
|
||||
0xCE618B7E,
|
||||
0x50FF6039,
|
||||
0xCE61AB7E,
|
||||
0x60FF6039,
|
||||
0xCE61CB7E,
|
||||
0x70FF6039,
|
||||
0xCE61EB7E,
|
||||
0x80FF6039,
|
||||
0xCE610B7F,
|
||||
0x90FF6039,
|
||||
0xCE612B7F,
|
||||
0xA0FF6039,
|
||||
0xCE614B7F,
|
||||
0xB0FF6039,
|
||||
0xCE616B7F,
|
||||
0xC0FF6039,
|
||||
0xCE618B7F,
|
||||
0xD0FF6039,
|
||||
0xCE61AB7F,
|
||||
0xE0FF6039,
|
||||
0xCE61CB7F,
|
||||
0xF0FF6039, // __savevmx_31
|
||||
0xCE61EB7F,
|
||||
0x2000804E,
|
||||
|
||||
0x00FC6039, // __savevmx_64
|
||||
0xCB610B10,
|
||||
0x10FC6039,
|
||||
0xCB612B10,
|
||||
0x20FC6039,
|
||||
0xCB614B10,
|
||||
0x30FC6039,
|
||||
0xCB616B10,
|
||||
0x40FC6039,
|
||||
0xCB618B10,
|
||||
0x50FC6039,
|
||||
0xCB61AB10,
|
||||
0x60FC6039,
|
||||
0xCB61CB10,
|
||||
0x70FC6039,
|
||||
0xCB61EB10,
|
||||
0x80FC6039,
|
||||
0xCB610B11,
|
||||
0x90FC6039,
|
||||
0xCB612B11,
|
||||
0xA0FC6039,
|
||||
0xCB614B11,
|
||||
0xB0FC6039,
|
||||
0xCB616B11,
|
||||
0xC0FC6039,
|
||||
0xCB618B11,
|
||||
0xD0FC6039,
|
||||
0xCB61AB11,
|
||||
0xE0FC6039,
|
||||
0xCB61CB11,
|
||||
0xF0FC6039,
|
||||
0xCB61EB11,
|
||||
0x00FD6039,
|
||||
0xCB610B12,
|
||||
0x10FD6039,
|
||||
0xCB612B12,
|
||||
0x20FD6039,
|
||||
0xCB614B12,
|
||||
0x30FD6039,
|
||||
0xCB616B12,
|
||||
0x40FD6039,
|
||||
0xCB618B12,
|
||||
0x50FD6039,
|
||||
0xCB61AB12,
|
||||
0x60FD6039,
|
||||
0xCB61CB12,
|
||||
0x70FD6039,
|
||||
0xCB61EB12,
|
||||
0x80FD6039,
|
||||
0xCB610B13,
|
||||
0x90FD6039,
|
||||
0xCB612B13,
|
||||
0xA0FD6039,
|
||||
0xCB614B13,
|
||||
0xB0FD6039,
|
||||
0xCB616B13,
|
||||
0xC0FD6039,
|
||||
0xCB618B13,
|
||||
0xD0FD6039,
|
||||
0xCB61AB13,
|
||||
0xE0FD6039,
|
||||
0xCB61CB13,
|
||||
0xF0FD6039,
|
||||
0xCB61EB13,
|
||||
0x00FE6039,
|
||||
0xCF610B10,
|
||||
0x10FE6039,
|
||||
0xCF612B10,
|
||||
0x20FE6039,
|
||||
0xCF614B10,
|
||||
0x30FE6039,
|
||||
0xCF616B10,
|
||||
0x40FE6039,
|
||||
0xCF618B10,
|
||||
0x50FE6039,
|
||||
0xCF61AB10,
|
||||
0x60FE6039,
|
||||
0xCF61CB10,
|
||||
0x70FE6039,
|
||||
0xCF61EB10,
|
||||
0x80FE6039,
|
||||
0xCF610B11,
|
||||
0x90FE6039,
|
||||
0xCF612B11,
|
||||
0xA0FE6039,
|
||||
0xCF614B11,
|
||||
0xB0FE6039,
|
||||
0xCF616B11,
|
||||
0xC0FE6039,
|
||||
0xCF618B11,
|
||||
0xD0FE6039,
|
||||
0xCF61AB11,
|
||||
0xE0FE6039,
|
||||
0xCF61CB11,
|
||||
0xF0FE6039,
|
||||
0xCF61EB11,
|
||||
0x00FF6039,
|
||||
0xCF610B12,
|
||||
0x10FF6039,
|
||||
0xCF612B12,
|
||||
0x20FF6039,
|
||||
0xCF614B12,
|
||||
0x30FF6039,
|
||||
0xCF616B12,
|
||||
0x40FF6039,
|
||||
0xCF618B12,
|
||||
0x50FF6039,
|
||||
0xCF61AB12,
|
||||
0x60FF6039,
|
||||
0xCF61CB12,
|
||||
0x70FF6039,
|
||||
0xCF61EB12,
|
||||
0x80FF6039,
|
||||
0xCF610B13,
|
||||
0x90FF6039,
|
||||
0xCF612B13,
|
||||
0xA0FF6039,
|
||||
0xCF614B13,
|
||||
0xB0FF6039,
|
||||
0xCF616B13,
|
||||
0xC0FF6039,
|
||||
0xCF618B13,
|
||||
0xD0FF6039,
|
||||
0xCF61AB13,
|
||||
0xE0FF6039,
|
||||
0xCF61CB13,
|
||||
0xF0FF6039, // __savevmx_127
|
||||
0xCF61EB13,
|
||||
0x2000804E,
|
||||
|
||||
0xE0FE6039, // __restvmx_14
|
||||
0xCE60CB7D,
|
||||
0xF0FE6039,
|
||||
0xCE60EB7D,
|
||||
0x00FF6039,
|
||||
0xCE600B7E,
|
||||
0x10FF6039,
|
||||
0xCE602B7E,
|
||||
0x20FF6039,
|
||||
0xCE604B7E,
|
||||
0x30FF6039,
|
||||
0xCE606B7E,
|
||||
0x40FF6039,
|
||||
0xCE608B7E,
|
||||
0x50FF6039,
|
||||
0xCE60AB7E,
|
||||
0x60FF6039,
|
||||
0xCE60CB7E,
|
||||
0x70FF6039,
|
||||
0xCE60EB7E,
|
||||
0x80FF6039,
|
||||
0xCE600B7F,
|
||||
0x90FF6039,
|
||||
0xCE602B7F,
|
||||
0xA0FF6039,
|
||||
0xCE604B7F,
|
||||
0xB0FF6039,
|
||||
0xCE606B7F,
|
||||
0xC0FF6039,
|
||||
0xCE608B7F,
|
||||
0xD0FF6039,
|
||||
0xCE60AB7F,
|
||||
0xE0FF6039,
|
||||
0xCE60CB7F,
|
||||
0xF0FF6039, // __restvmx_31
|
||||
0xCE60EB7F,
|
||||
0x2000804E,
|
||||
|
||||
0x00FC6039, // __restvmx_64
|
||||
0xCB600B10,
|
||||
0x10FC6039,
|
||||
0xCB602B10,
|
||||
0x20FC6039,
|
||||
0xCB604B10,
|
||||
0x30FC6039,
|
||||
0xCB606B10,
|
||||
0x40FC6039,
|
||||
0xCB608B10,
|
||||
0x50FC6039,
|
||||
0xCB60AB10,
|
||||
0x60FC6039,
|
||||
0xCB60CB10,
|
||||
0x70FC6039,
|
||||
0xCB60EB10,
|
||||
0x80FC6039,
|
||||
0xCB600B11,
|
||||
0x90FC6039,
|
||||
0xCB602B11,
|
||||
0xA0FC6039,
|
||||
0xCB604B11,
|
||||
0xB0FC6039,
|
||||
0xCB606B11,
|
||||
0xC0FC6039,
|
||||
0xCB608B11,
|
||||
0xD0FC6039,
|
||||
0xCB60AB11,
|
||||
0xE0FC6039,
|
||||
0xCB60CB11,
|
||||
0xF0FC6039,
|
||||
0xCB60EB11,
|
||||
0x00FD6039,
|
||||
0xCB600B12,
|
||||
0x10FD6039,
|
||||
0xCB602B12,
|
||||
0x20FD6039,
|
||||
0xCB604B12,
|
||||
0x30FD6039,
|
||||
0xCB606B12,
|
||||
0x40FD6039,
|
||||
0xCB608B12,
|
||||
0x50FD6039,
|
||||
0xCB60AB12,
|
||||
0x60FD6039,
|
||||
0xCB60CB12,
|
||||
0x70FD6039,
|
||||
0xCB60EB12,
|
||||
0x80FD6039,
|
||||
0xCB600B13,
|
||||
0x90FD6039,
|
||||
0xCB602B13,
|
||||
0xA0FD6039,
|
||||
0xCB604B13,
|
||||
0xB0FD6039,
|
||||
0xCB606B13,
|
||||
0xC0FD6039,
|
||||
0xCB608B13,
|
||||
0xD0FD6039,
|
||||
0xCB60AB13,
|
||||
0xE0FD6039,
|
||||
0xCB60CB13,
|
||||
0xF0FD6039,
|
||||
0xCB60EB13,
|
||||
0x00FE6039,
|
||||
0xCF600B10,
|
||||
0x10FE6039,
|
||||
0xCF602B10,
|
||||
0x20FE6039,
|
||||
0xCF604B10,
|
||||
0x30FE6039,
|
||||
0xCF606B10,
|
||||
0x40FE6039,
|
||||
0xCF608B10,
|
||||
0x50FE6039,
|
||||
0xCF60AB10,
|
||||
0x60FE6039,
|
||||
0xCF60CB10,
|
||||
0x70FE6039,
|
||||
0xCF60EB10,
|
||||
0x80FE6039,
|
||||
0xCF600B11,
|
||||
0x90FE6039,
|
||||
0xCF602B11,
|
||||
0xA0FE6039,
|
||||
0xCF604B11,
|
||||
0xB0FE6039,
|
||||
0xCF606B11,
|
||||
0xC0FE6039,
|
||||
0xCF608B11,
|
||||
0xD0FE6039,
|
||||
0xCF60AB11,
|
||||
0xE0FE6039,
|
||||
0xCF60CB11,
|
||||
0xF0FE6039,
|
||||
0xCF60EB11,
|
||||
0x00FF6039,
|
||||
0xCF600B12,
|
||||
0x10FF6039,
|
||||
0xCF602B12,
|
||||
0x20FF6039,
|
||||
0xCF604B12,
|
||||
0x30FF6039,
|
||||
0xCF606B12,
|
||||
0x40FF6039,
|
||||
0xCF608B12,
|
||||
0x50FF6039,
|
||||
0xCF60AB12,
|
||||
0x60FF6039,
|
||||
0xCF60CB12,
|
||||
0x70FF6039,
|
||||
0xCF60EB12,
|
||||
0x80FF6039,
|
||||
0xCF600B13,
|
||||
0x90FF6039,
|
||||
0xCF602B13,
|
||||
0xA0FF6039,
|
||||
0xCF604B13,
|
||||
0xB0FF6039,
|
||||
0xCF606B13,
|
||||
0xC0FF6039,
|
||||
0xCF608B13,
|
||||
0xD0FF6039,
|
||||
0xCF60AB13,
|
||||
0xE0FF6039,
|
||||
0xCF60CB13,
|
||||
0xF0FF6039, // __restvmx_127
|
||||
0xCF60EB13,
|
||||
0x2000804E,
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint32_t gplr_start = 0;
|
||||
uint32_t fpr_start = 0;
|
||||
uint32_t vmx_start = 0;
|
||||
const xe_xex2_header_t* header = xe_xex2_get_header(xex_);
|
||||
for (size_t n = 0, i = 0; n < header->section_count; n++) {
|
||||
const xe_xex2_section_t* section = &header->sections[n];
|
||||
|
@ -144,21 +531,31 @@ int XexSymbolDatabase::FindGplr() {
|
|||
const size_t end_address =
|
||||
start_address + (section->info.page_count * xe_xex2_section_length);
|
||||
if (section->info.type == XEX_SECTION_CODE) {
|
||||
if (!gplr_start) {
|
||||
gplr_start = xe_memory_search_aligned(
|
||||
memory_, start_address, end_address,
|
||||
code_values, XECOUNT(code_values));
|
||||
if (gplr_start) {
|
||||
gprlr_code_values, XECOUNT(gprlr_code_values));
|
||||
}
|
||||
if (!fpr_start) {
|
||||
fpr_start = xe_memory_search_aligned(
|
||||
memory_, start_address, end_address,
|
||||
fpr_code_values, XECOUNT(fpr_code_values));
|
||||
}
|
||||
if (!vmx_start) {
|
||||
vmx_start = xe_memory_search_aligned(
|
||||
memory_, start_address, end_address,
|
||||
vmx_code_values, XECOUNT(vmx_code_values));
|
||||
}
|
||||
if (gplr_start && fpr_start && vmx_start) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += section->info.page_count;
|
||||
}
|
||||
if (!gplr_start) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add function stubs.
|
||||
char name[32];
|
||||
if (gplr_start) {
|
||||
uint32_t address = gplr_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__savegprlr_%d", n);
|
||||
|
@ -179,6 +576,72 @@ int XexSymbolDatabase::FindGplr() {
|
|||
fn->flags |= FunctionSymbol::kFlagRestGprLr;
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
if (fpr_start) {
|
||||
uint32_t address = fpr_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__savefpr_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->end_address = fn->start_address + (31 - n) * 4 + 1 * 4;
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagSaveFpr;
|
||||
address += 4;
|
||||
}
|
||||
address = fpr_start + (18 * 4) + (1 * 4);
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__restfpr_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->end_address = fn->start_address + (31 - n) * 4 + 1 * 4;
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagRestFpr;
|
||||
address += 4;
|
||||
}
|
||||
}
|
||||
if (vmx_start) {
|
||||
// vmx is:
|
||||
// 14-31 save
|
||||
// 64-127 save
|
||||
// 14-31 rest
|
||||
// 64-127 rest
|
||||
uint32_t address = vmx_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__savevmx_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
||||
address += 2 * 4;
|
||||
}
|
||||
address += 4;
|
||||
for (int n = 64; n <= 127; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__savevmx_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
||||
address += 2 * 4;
|
||||
}
|
||||
address = vmx_start + (18 * 2 * 4) + (1 * 4) + (64 * 2 * 4) + (1 * 4);
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__restvmx_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagRestVmx;
|
||||
address += 2 * 4;
|
||||
}
|
||||
address += 4;
|
||||
for (int n = 64; n <= 127; n++) {
|
||||
xesnprintfa(name, XECOUNT(name), "__restvmx_%d", n);
|
||||
FunctionSymbol* fn = GetOrInsertFunction(address);
|
||||
fn->set_name(name);
|
||||
fn->type = FunctionSymbol::User;
|
||||
fn->flags |= FunctionSymbol::kFlagSaveVmx;
|
||||
address += 2 * 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
virtual int Analyze();
|
||||
|
||||
private:
|
||||
int FindGplr();
|
||||
int FindSaveRest();
|
||||
int AddImports(const xe_xex2_import_library_t *library);
|
||||
int AddMethodHints();
|
||||
|
||||
|
|
Loading…
Reference in New Issue