From c98ae0925fd0afd87242bee6933fc61dd328bdac Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sun, 18 May 2025 18:19:10 -0700 Subject: [PATCH] error check relocations --- src/coff/coff.h | 1 + src/linker/lnk.c | 19 ++++++++++++++++++- src/linker/lnk_error.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/coff/coff.h b/src/coff/coff.h index 2dd187b6..a0f18d2e 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -385,6 +385,7 @@ enum COFF_Reloc_X64_Pair = 0xF, COFF_Reloc_X64_SSpan32 = 0x10, COFF_Reloc_X64_Unknown_11 = 0x11, + COFF_Reloc_X64_Last = COFF_Reloc_X64_Unknown_11, }; typedef COFF_RelocType COFF_Reloc_X86; diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 32f771e3..47264f38 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1101,6 +1101,15 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) for (U64 reloc_idx = 0; reloc_idx < reloc_info.count; reloc_idx += 1) { COFF_Reloc *reloc = &relocs[reloc_idx]; + // error check relocation + if (obj->header.machine == COFF_MachineType_X64) { + if (reloc->type > COFF_Reloc_X64_Last) { + lnk_error_obj(LNK_Error_IllegalRelocation, obj, "unknown relocation 0x%x", reloc->type); + } + } else if (obj->header.machine == COFF_MachineType_Unknown) { + NotImplemented; + } + // compute relocation file/virtual offsets U64 reloc_foff = section_header->foff + reloc->apply_off; U64 reloc_voff = section_header->voff + reloc->apply_off; @@ -1121,8 +1130,16 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) if (interp == COFF_SymbolValueInterp_Regular) { symbol_secnum = symbol.section_number; symbol_secoff = symbol.value; - symbol_voff = task->image_section_table[symbol.section_number]->voff + symbol_secoff; + symbol_voff = safe_cast_u32((U64)task->image_section_table[symbol.section_number]->voff + (U64)symbol_secoff); } else if (interp == COFF_SymbolValueInterp_Abs) { + // error check relocation + if (obj->header.machine == COFF_MachineType_X64) { + if (reloc->type == COFF_Reloc_X64_SecRel) { + lnk_error_obj(LNK_Error_IllegalRelocation, obj, "section-relative relocation (No. 0x%x) cannot be applied to absolute symbol (No. 0x%x)", reloc_idx, reloc->isymbol); + } + } else if (obj->header.machine != COFF_MachineType_Unknown) { + NotImplemented; + } symbol_secnum = 0; symbol_secoff = 0; symbol_voff = safe_cast_u32(symbol.value); diff --git a/src/linker/lnk_error.h b/src/linker/lnk_error.h index d1fa096c..af146ade 100644 --- a/src/linker/lnk_error.h +++ b/src/linker/lnk_error.h @@ -35,6 +35,7 @@ typedef enum LNK_Error_MultiplyDefinedSymbol, LNK_Error_SectRefsDiscardedMemory, LNK_Error_IllegalSectionMerge, + LNK_Error_IllegalRelocation, LNK_Error_StopLast, LNK_Error_First,