mirror of
				https://github.com/N64Recomp/N64Recomp.git
				synced 2025-10-30 08:02:11 +00:00 
			
		
		
		
	Move handling of HI16/LO16 relocs for non-relocatable reference sections into elf parsing by patching the output binary (fixes patch regeneration) (#127)
This commit is contained in:
		
							parent
							
								
									b18e0ca2dd
								
							
						
					
					
						commit
						198de1b5cf
					
				
					 2 changed files with 32 additions and 11 deletions
				
			
		
							
								
								
									
										32
									
								
								src/elf.cpp
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								src/elf.cpp
									
										
									
									
									
								
							|  | @ -104,10 +104,10 @@ bool read_symbols(N64Recomp::Context& context, const ELFIO::elfio& elf_file, ELF | ||||||
| 
 | 
 | ||||||
|                 if (section_index < context.sections.size()) { |                 if (section_index < context.sections.size()) { | ||||||
|                     auto section_offset = value - elf_file.sections[section_index]->get_address(); |                     auto section_offset = value - elf_file.sections[section_index]->get_address(); | ||||||
|                     const uint32_t* words = reinterpret_cast<const uint32_t*>(elf_file.sections[section_index]->get_data() + section_offset); |  | ||||||
|                     uint32_t vram = static_cast<uint32_t>(value); |                     uint32_t vram = static_cast<uint32_t>(value); | ||||||
|                     uint32_t num_instructions = type == ELFIO::STT_FUNC ? size / 4 : 0; |                     uint32_t num_instructions = type == ELFIO::STT_FUNC ? size / 4 : 0; | ||||||
|                     uint32_t rom_address = static_cast<uint32_t>(section_offset + section.rom_addr); |                     uint32_t rom_address = static_cast<uint32_t>(section_offset + section.rom_addr); | ||||||
|  |                     const uint32_t* words = reinterpret_cast<const uint32_t*>(context.rom.data() + rom_address); | ||||||
| 
 | 
 | ||||||
|                     section.function_addrs.push_back(vram); |                     section.function_addrs.push_back(vram); | ||||||
|                     context.functions_by_vram[vram].push_back(context.functions.size()); |                     context.functions_by_vram[vram].push_back(context.functions.size()); | ||||||
|  | @ -551,6 +551,36 @@ ELFIO::section* read_sections(N64Recomp::Context& context, const N64Recomp::ElfP | ||||||
|                     return a.address < b.address; |                     return a.address < b.address; | ||||||
|                 } |                 } | ||||||
|             ); |             ); | ||||||
|  | 
 | ||||||
|  |             // Patch the ROM word for HI16 and LO16 reference symbol relocs to non-relocatable sections.
 | ||||||
|  |             for (size_t i = 0; i < section_out.relocs.size(); i++) { | ||||||
|  |                 auto& reloc = section_out.relocs[i]; | ||||||
|  |                 if (reloc.reference_symbol && (reloc.type == N64Recomp::RelocType::R_MIPS_HI16 || reloc.type == N64Recomp::RelocType::R_MIPS_LO16)) { | ||||||
|  |                     bool target_section_relocatable = context.is_reference_section_relocatable(reloc.target_section); | ||||||
|  |                     if (!target_section_relocatable) { | ||||||
|  |                         uint32_t reloc_rom_addr = reloc.address - section_out.ram_addr + section_out.rom_addr; | ||||||
|  |                         uint32_t reloc_rom_word = byteswap(*reinterpret_cast<const uint32_t*>(context.rom.data() + reloc_rom_addr)); | ||||||
|  | 
 | ||||||
|  |                         uint32_t ref_section_vram = context.get_reference_section_vram(reloc.target_section); | ||||||
|  |                         uint32_t full_immediate = reloc.target_section_offset + ref_section_vram; | ||||||
|  | 
 | ||||||
|  |                         uint32_t imm; | ||||||
|  | 
 | ||||||
|  |                         if (reloc.type == N64Recomp::RelocType::R_MIPS_HI16) { | ||||||
|  |                             imm = (full_immediate >> 16) + ((full_immediate >> 15) & 1); | ||||||
|  |                         } | ||||||
|  |                         else { | ||||||
|  |                             imm = full_immediate & 0xFFFF; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         *reinterpret_cast<uint32_t*>(context.rom.data() + reloc_rom_addr) = byteswap(reloc_rom_word | imm); | ||||||
|  |                         // Remove the reloc by setting it to a type of NONE.
 | ||||||
|  |                         reloc.type = N64Recomp::RelocType::R_MIPS_NONE; | ||||||
|  |                         reloc.reference_symbol = false; | ||||||
|  |                         reloc.symbol_index = (uint32_t)-1; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -184,19 +184,10 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | ||||||
|                     reloc_reference_symbol = reloc.symbol_index; |                     reloc_reference_symbol = reloc.symbol_index; | ||||||
|                     // Don't try to relocate special section symbols.
 |                     // Don't try to relocate special section symbols.
 | ||||||
|                     if (context.is_regular_reference_section(reloc.target_section) || reloc_section == N64Recomp::SectionAbsolute) { |                     if (context.is_regular_reference_section(reloc.target_section) || reloc_section == N64Recomp::SectionAbsolute) { | ||||||
|  |                         // TODO this may not be needed anymore as HI16/LO16 relocs to non-relocatable sections is handled directly in elf parsing.
 | ||||||
|                         bool ref_section_relocatable = context.is_reference_section_relocatable(reloc.target_section); |                         bool ref_section_relocatable = context.is_reference_section_relocatable(reloc.target_section); | ||||||
|                         // Resolve HI16 and LO16 reference symbol relocs to non-relocatable sections by patching the instruction immediate.
 |                         // Resolve HI16 and LO16 reference symbol relocs to non-relocatable sections by patching the instruction immediate.
 | ||||||
|                         if (!ref_section_relocatable && (reloc_type == N64Recomp::RelocType::R_MIPS_HI16 || reloc_type == N64Recomp::RelocType::R_MIPS_LO16)) { |                         if (!ref_section_relocatable && (reloc_type == N64Recomp::RelocType::R_MIPS_HI16 || reloc_type == N64Recomp::RelocType::R_MIPS_LO16)) { | ||||||
|                             uint32_t ref_section_vram = context.get_reference_section_vram(reloc.target_section); |  | ||||||
|                             uint32_t full_immediate = reloc.target_section_offset + ref_section_vram; |  | ||||||
| 
 |  | ||||||
|                             if (reloc_type == N64Recomp::RelocType::R_MIPS_HI16) { |  | ||||||
|                                 imm = (full_immediate >> 16) + ((full_immediate >> 15) & 1); |  | ||||||
|                             } |  | ||||||
|                             else if (reloc_type == N64Recomp::RelocType::R_MIPS_LO16) { |  | ||||||
|                                 imm = full_immediate & 0xFFFF; |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             // The reloc has been processed, so set it to none to prevent it getting processed a second time during instruction code generation.
 |                             // The reloc has been processed, so set it to none to prevent it getting processed a second time during instruction code generation.
 | ||||||
|                             reloc_type = N64Recomp::RelocType::R_MIPS_NONE; |                             reloc_type = N64Recomp::RelocType::R_MIPS_NONE; | ||||||
|                             reloc_reference_symbol = (size_t)-1; |                             reloc_reference_symbol = (size_t)-1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Wiseguy
						Wiseguy