2
0
Эх сурвалжийг харах

Update embedded PCK virtual address.

Pāvels Nadtočajevs 2 сар өмнө
parent
commit
21aa53f718

+ 7 - 5
core/config/project_settings.cpp

@@ -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;

+ 58 - 24
platform/windows/export/export_plugin.cpp

@@ -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;
+
+		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(f->get_position() + 2 + opt_header_size);
+		// 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);
+		}
+
+		// 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 (!found) {
+	if (pck_old_pos == -1) {
 		add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable \"pck\" section not found."));
 		return ERR_FILE_CORRUPT;
 	}