mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 00:31:05 +00:00
Link the previous and current CRO by their link members.
This commit is contained in:
parent
74d1553d85
commit
d2d9709ea8
@ -76,6 +76,16 @@ struct ImportTableEntry {
|
|||||||
u32 symbol_offset;
|
u32 symbol_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ExportTreeEntry {
|
||||||
|
u16 segment_offset;
|
||||||
|
u16 unk;
|
||||||
|
u16 unk2;
|
||||||
|
u16 export_table_id;
|
||||||
|
|
||||||
|
u8 GetTargetSegment() { return segment_offset & 0x7; }
|
||||||
|
u32 GetSegmentOffset() { return segment_offset >> 3; }
|
||||||
|
};
|
||||||
|
|
||||||
struct ExportedSymbol {
|
struct ExportedSymbol {
|
||||||
std::string name;
|
std::string name;
|
||||||
u32 cro_base;
|
u32 cro_base;
|
||||||
@ -86,8 +96,8 @@ struct CROHeader {
|
|||||||
u8 sha2_hash[0x80];
|
u8 sha2_hash[0x80];
|
||||||
char magic[4];
|
char magic[4];
|
||||||
u32 name_offset;
|
u32 name_offset;
|
||||||
u32 previous_cro;
|
|
||||||
u32 next_cro;
|
u32 next_cro;
|
||||||
|
u32 previous_cro;
|
||||||
u32 file_size;
|
u32 file_size;
|
||||||
INSERT_PADDING_WORDS(0x6);
|
INSERT_PADDING_WORDS(0x6);
|
||||||
u32 segment_offset;
|
u32 segment_offset;
|
||||||
@ -135,6 +145,8 @@ struct CROHeader {
|
|||||||
ExportTableEntry* GetExportTableEntry(u32 index);
|
ExportTableEntry* GetExportTableEntry(u32 index);
|
||||||
void RelocateExportsTable(u32 base);
|
void RelocateExportsTable(u32 base);
|
||||||
|
|
||||||
|
ExportTreeEntry* GetExportTreeEntry(u32 index);
|
||||||
|
|
||||||
Patch* GetImportPatch(u32 index);
|
Patch* GetImportPatch(u32 index);
|
||||||
|
|
||||||
ImportTableEntry* GetImportTable1Entry(u32 index);
|
ImportTableEntry* GetImportTable1Entry(u32 index);
|
||||||
@ -182,6 +194,10 @@ void CROHeader::RelocateSegmentsTable(u32 base, u32 data_section0, u32 data_sect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExportTreeEntry* CROHeader::GetExportTreeEntry(u32 index) {
|
||||||
|
return reinterpret_cast<ExportTreeEntry*>(reinterpret_cast<u8*>(this) + export_tree_offset + sizeof(ExportTreeEntry) * index);
|
||||||
|
}
|
||||||
|
|
||||||
u32 CROHeader::GetUnk1TableEntry(u32 index) {
|
u32 CROHeader::GetUnk1TableEntry(u32 index) {
|
||||||
return *reinterpret_cast<u32*>(reinterpret_cast<u8*>(this) + unk1_offset + sizeof(u32) * index);
|
return *reinterpret_cast<u32*>(reinterpret_cast<u8*>(this) + unk1_offset + sizeof(u32) * index);
|
||||||
}
|
}
|
||||||
@ -421,15 +437,48 @@ static void LoadExportsTable(CROHeader* header, u32 base) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 GetAddress(CROHeader* header, char* str) {
|
||||||
|
if (header->export_tree_num) {
|
||||||
|
ExportTreeEntry* first_entry = header->GetExportTreeEntry(0);
|
||||||
|
u32 len = strlen(str);
|
||||||
|
ExportTreeEntry* next_entry = header->GetExportTreeEntry(first_entry->unk);
|
||||||
|
bool v16 = false;
|
||||||
|
do {
|
||||||
|
u16 v14 = 0;
|
||||||
|
bool v12 = next_entry->GetSegmentOffset() >= len;
|
||||||
|
if (v12 || !((*(str + next_entry->GetSegmentOffset()) >> next_entry->GetTargetSegment()) & 1))
|
||||||
|
v14 = next_entry->unk;
|
||||||
|
else
|
||||||
|
v14 = next_entry->unk2;
|
||||||
|
v16 = (v14 & 0x8000) == 0;
|
||||||
|
next_entry = header->GetExportTreeEntry(v14 & 0x7FFF);
|
||||||
|
} while (v16);
|
||||||
|
|
||||||
|
u32 export_id = next_entry->export_table_id;
|
||||||
|
ExportTableEntry* export_entry = header->GetExportTableEntry(export_id);
|
||||||
|
char* export_name = (char*)Memory::GetPointer(export_entry->name_offset);
|
||||||
|
if (!strcmp(export_name, str)) {
|
||||||
|
SegmentTableEntry* segment = header->GetSegmentTableEntry(export_entry->GetTargetSegment());
|
||||||
|
return segment->segment_offset + export_entry->GetSegmentOffset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LinkCROs(CROHeader* new_cro, u32 base) {
|
||||||
|
if (!loaded_cros.empty())
|
||||||
|
new_cro->previous_cro = loaded_cros.back();
|
||||||
|
|
||||||
|
if (new_cro->previous_cro) {
|
||||||
|
CROHeader* previous_cro = reinterpret_cast<CROHeader*>(Memory::GetPointer(new_cro->previous_cro));
|
||||||
|
previous_cro->next_cro = base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void LoadCRO(u32 base, u8* cro, bool relocate_segments, u32 data_section0, u32 data_section1) {
|
static void LoadCRO(u32 base, u8* cro, bool relocate_segments, u32 data_section0, u32 data_section1) {
|
||||||
CROHeader* header = reinterpret_cast<CROHeader*>(cro);
|
CROHeader* header = reinterpret_cast<CROHeader*>(cro);
|
||||||
memcpy(header->magic, "FIXD", 4);
|
memcpy(header->magic, "FIXD", 4);
|
||||||
|
|
||||||
for (int i = 0; i < header->file_size; ++i) {
|
|
||||||
u32* d = (u32*)header + i;
|
|
||||||
if (*d == 0x2020E || *d == 0x2020D)
|
|
||||||
__debugbreak();
|
|
||||||
}
|
|
||||||
if (relocate_segments) {
|
if (relocate_segments) {
|
||||||
// Relocate segments
|
// Relocate segments
|
||||||
header->RelocateSegmentsTable(base, data_section0, data_section1);
|
header->RelocateSegmentsTable(base, data_section0, data_section1);
|
||||||
@ -480,7 +529,14 @@ static void LoadCRO(u32 base, u8* cro, bool relocate_segments, u32 data_section0
|
|||||||
// Relocate all offsets
|
// Relocate all offsets
|
||||||
header->RelocateOffsets(base);
|
header->RelocateOffsets(base);
|
||||||
|
|
||||||
|
// Link the CROs
|
||||||
|
LinkCROs(header, base);
|
||||||
|
|
||||||
loaded_cros.push_back(base);
|
loaded_cros.push_back(base);
|
||||||
|
|
||||||
|
FileUtil::IOFile file(std::to_string(base) + ".cro", "wb+");
|
||||||
|
file.WriteBytes(header, header->file_size);
|
||||||
|
file.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user