From c2a0a6f1e10d8c51e78cd8b1f8591432fa9b44fc Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 28 Apr 2025 13:54:51 -0700 Subject: [PATCH] factored out format specific relocation code to COFF layer --- src/coff/coff.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/coff/coff.c b/src/coff/coff.c index 5b65582a..c2ab20a1 100644 --- a/src/coff/coff.c +++ b/src/coff/coff.c @@ -179,6 +179,94 @@ coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x) return 0; } +internal void +coff_apply_reloc_x64(String8 data, + COFF_Reloc_X64 type, + U64 apply_off, + U64 reloc_virtual_offset, + U32 symbol_section_number, + U32 symbol_section_offset, + U32 symbol_virtual_offset, + U64 symbol_address) +{ + U64 reloc_value_size = 0; + S64 reloc_value = 0; + switch (type) { + case COFF_Reloc_X64_Abs: {} break; + case COFF_Reloc_X64_Addr64: { + reloc_value_size = 8; + reloc_value = symbol_address; + } break; + case COFF_Reloc_X64_Addr32: { + reloc_value_size = 4; + reloc_value = safe_cast_u32(symbol_address); + } break; + case COFF_Reloc_X64_Addr32Nb: { + reloc_value_size = 4; + reloc_value = safe_cast_u32(symbol_virtual_offset); + } break; + case COFF_Reloc_X64_Rel32: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 0)); + } break; + case COFF_Reloc_X64_Rel32_1: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 1)); + } break; + case COFF_Reloc_X64_Rel32_2: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 2)); + } break; + case COFF_Reloc_X64_Rel32_3: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 3)); + } break; + case COFF_Reloc_X64_Rel32_4: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 4)); + } break; + case COFF_Reloc_X64_Rel32_5: { + reloc_value_size = 4; + reloc_value = safe_cast_s32(symbol_virtual_offset - reloc_virtual_offset - (4 + 5)); + } break; + case COFF_Reloc_X64_Section: { + reloc_value_size = 4; + reloc_value = symbol_section_number; + } break; + case COFF_Reloc_X64_SecRel: { + reloc_value_size = 4; + reloc_value = symbol_section_offset; + } break; + case COFF_Reloc_X64_SecRel7: { + NotImplemented; + } break; + case COFF_Reloc_X64_Token: { + NotImplemented; + } break; + case COFF_Reloc_X64_SRel32: { + NotImplemented; + } break; + case COFF_Reloc_X64_Pair: { + NotImplemented; + } break; + case COFF_Reloc_X64_SSpan32: { + NotImplemented; + } break; + } + + // read addend + Assert(apply_off + reloc_value_size <= data.size); + U64 raw_addend = 0; + str8_deserial_read(data, apply_off, &raw_addend, reloc_value_size, reloc_value_size); + + // compute new reloc value + S64 addend = extend_sign64(raw_addend, reloc_value_size); + U64 reloc_result = reloc_value + addend; + + // commit new reloc value + MemoryCopy(data.str + apply_off, &reloc_result, reloc_value_size); +} + internal String8 coff_make_import_lookup(Arena *arena, U16 hint, String8 name) {