[CPU/Kernel] Correct parsing of XEX_HEADER_IMPORT_LIBRARIES.

This commit is contained in:
gibbed
2018-11-24 04:05:41 -06:00
parent b3d509eb01
commit 207589e5a1
3 changed files with 51 additions and 39 deletions

View File

@@ -1119,23 +1119,23 @@ bool XexModule::LoadContinue() {
processor_->backend()->CommitExecutableRange(low_address_, high_address_);
// Add all imports (variables/functions).
xex2_opt_import_libraries* opt_import_header = nullptr;
GetOptHeader(XEX_HEADER_IMPORT_LIBRARIES, &opt_import_header);
xex2_opt_import_libraries* opt_import_libraries = nullptr;
GetOptHeader(XEX_HEADER_IMPORT_LIBRARIES, &opt_import_libraries);
if (opt_import_header) {
if (opt_import_libraries) {
// FIXME: Don't know if 32 is the actual limit, but haven't seen more than
// 2.
const char* string_table[32];
std::memset(string_table, 0, sizeof(string_table));
size_t max_string_table_index = 0;
// Parse the string table
for (size_t i = 0; i < opt_import_header->string_table_size;
++max_string_table_index) {
assert_true(max_string_table_index < xe::countof(string_table));
const char* str = opt_import_header->string_table + i;
for (size_t i = 0, o = 0; i < opt_import_libraries->string_table.size &&
o < opt_import_libraries->string_table.count;
++o) {
assert_true(o < xe::countof(string_table));
const char* str = &opt_import_libraries->string_table.data[i];
string_table[max_string_table_index] = str;
string_table[o] = str;
i += std::strlen(str) + 1;
// Padding
@@ -1144,15 +1144,19 @@ bool XexModule::LoadContinue() {
}
}
auto libraries_ptr = reinterpret_cast<uint8_t*>(opt_import_header) +
opt_import_header->string_table_size + 12;
auto library_data = reinterpret_cast<uint8_t*>(opt_import_libraries) +
opt_import_libraries->string_table.size + 12;
uint32_t library_offset = 0;
uint32_t library_count = opt_import_header->library_count;
for (uint32_t i = 0; i < library_count; i++) {
auto library = reinterpret_cast<xex2_import_library*>(libraries_ptr +
library_offset);
while (library_offset < opt_import_libraries->size) {
auto library =
reinterpret_cast<xex2_import_library*>(library_data + library_offset);
if (!library->size) {
break;
}
size_t library_name_index = library->name_index & 0xFF;
assert_true(library_name_index < max_string_table_index);
assert_true(library_name_index <
opt_import_libraries->string_table.count);
assert_not_null(string_table[library_name_index]);
SetupLibraryImports(string_table[library_name_index], library);
library_offset += library->size;
}
@@ -1312,10 +1316,12 @@ bool XexModule::SetupLibraryImports(const char* name,
var_info->set_status(Symbol::Status::kDefined);
} else if (record_type == 1) {
// Thunk.
assert_true(library_info.imports.size() > 0);
auto& prev_import = library_info.imports[library_info.imports.size() - 1];
assert_true(prev_import.ordinal == ordinal);
prev_import.thunk_address = record_addr;
if (library_info.imports.size() > 0) {
auto& prev_import =
library_info.imports[library_info.imports.size() - 1];
assert_true(prev_import.ordinal == ordinal);
prev_import.thunk_address = record_addr;
}
if (kernel_export) {
import_name.AppendFormat("%s", kernel_export->name);