1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Update embedded PCK virtual address.

This commit is contained in:
Pāvels Nadtočajevs
2025-10-15 12:31:18 +03:00
parent 36b92128b1
commit 21aa53f718
2 changed files with 65 additions and 29 deletions

View File

@@ -783,12 +783,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
resource_path = current_dir;
resource_path = resource_path.replace_char('\\', '/'); // Windows path to Unix path just in case.
err = _load_settings_text_or_binary(current_dir.path_join("project.godot"), current_dir.path_join("project.binary"));
if (err == OK && !p_ignore_override) {
// Optional, we don't mind if it fails.
if (err == OK) {
#ifdef OVERRIDE_ENABLED
bool disable_override = GLOBAL_GET("application/config/disable_project_settings_override");
if (!disable_override) {
_load_settings_text(current_dir.path_join("override.cfg"));
if (!p_ignore_override) {
// Optional, we don't mind if it fails.
bool disable_override = GLOBAL_GET("application/config/disable_project_settings_override");
if (!disable_override) {
_load_settings_text(current_dir.path_join("override.cfg"));
}
}
#endif // OVERRIDE_ENABLED
found = true;

View File

@@ -802,9 +802,9 @@ String EditorExportPlatformWindows::_get_exe_arch(const String &p_path) const {
}
Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data.
if (p_embedded_size + p_embedded_start >= 0x100000000) { // Check for total executable size
if (p_embedded_size + p_embedded_start >= 0x100000000) { // Check for total executable size.
add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Windows executables cannot be >= 4 GiB."));
return ERR_INVALID_DATA;
}
@@ -815,7 +815,7 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6
return ERR_CANT_OPEN;
}
// Jump to the PE header and check the magic number
// Jump to the PE header and check the magic number.
{
f->seek(0x3c);
uint32_t pe_pos = f->get_32();
@@ -828,27 +828,36 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6
}
}
// Process header
// Process header.
uint32_t sect_alignment = 0x1000;
uint32_t image_size = 0;
int num_sections;
{
int64_t header_pos = f->get_position();
int64_t header_pos = f->get_position();
int64_t opt_header_pos = 0;
{
f->seek(header_pos + 2);
num_sections = f->get_16();
f->seek(header_pos + 16);
uint16_t opt_header_size = f->get_16();
opt_header_pos = f->get_position() + 2;
// Skip rest of header + optional header to go to the section headers
f->seek(f->get_position() + 2 + opt_header_size);
f->seek(opt_header_pos + 32);
sect_alignment = f->get_32();
f->seek(opt_header_pos + 56);
image_size = f->get_32();
// Skip rest of header + optional header to go to the section headers.
f->seek(opt_header_pos + opt_header_size);
}
// Search for the "pck" section
// Search for the "pck" section.
int64_t section_table_pos = f->get_position();
bool found = false;
for (int i = 0; i < num_sections; ++i) {
int pck_old_pos = -1;
for (int i = 0; i < num_sections; i++) {
int64_t section_header_pos = section_table_pos + i * 40;
f->seek(section_header_pos);
@@ -857,23 +866,48 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6
section_name[8] = '\0';
if (strcmp((char *)section_name, "pck") == 0) {
// "pck" section found, let's patch!
pck_old_pos = i;
// Set virtual size to a little to avoid it taking memory (zero would give issues)
f->seek(section_header_pos + 8);
f->store_32(8);
f->seek(section_header_pos + 16);
f->store_32(p_embedded_size);
f->seek(section_header_pos + 20);
f->store_32(p_embedded_start);
found = true;
// Update virtual size of previous section to avoid gaps in the virtual addresses.
f->seek(section_table_pos + (i - 1) * 40 + 8);
uint32_t virt_size = f->get_32();
f->seek(section_table_pos + (i - 1) * 40 + 8);
f->store_32(virt_size + sect_alignment);
break;
}
}
if (pck_old_pos >= 0) {
// Move section data.
uint8_t section_data[40];
for (int i = pck_old_pos; i < num_sections - 1; i++) {
f->seek(section_table_pos + (i + 1) * 40);
f->get_buffer(section_data, 40);
f->seek(section_table_pos + i * 40);
f->store_buffer(section_data, 40);
}
if (!found) {
// Add "pck" at the end.
f->seek(section_table_pos + (num_sections - 1) * 40);
uint8_t section_name[8] = { 'p', 'c', 'k', '\0', '\0', '\0', '\0', '\0' };
f->store_buffer(section_name, 8); // Name.
f->store_32(8); // VirtualSize, set to a little to avoid it taking memory (zero would give issues).
f->store_32(image_size); // VirtualAddress.
f->store_32(p_embedded_size); // SizeOfRawData.
f->store_32(p_embedded_start); // PointerToRawData.
f->store_32(0); // PointerToRelocations, not used.
f->store_32(0); // PointerToLinenumbers, not used.
f->store_16(0); // NumberOfRelocations.
f->store_16(0); // NumberOfLinenumbers.
f->store_32(0x40000000); // Characteristics: Read.
// Update image virtual size.
f->seek(opt_header_pos + 56);
f->store_32(image_size + sect_alignment);
}
f->close();
if (pck_old_pos == -1) {
add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable \"pck\" section not found."));
return ERR_FILE_CORRUPT;
}