Author: Martin Storsjö Date: 2026-06-01T07:17:28Z New Revision: a760d7c07024feaf3b58212edd388a4f016a71ce
URL: https://github.com/llvm/llvm-project/commit/a760d7c07024feaf3b58212edd388a4f016a71ce DIFF: https://github.com/llvm/llvm-project/commit/a760d7c07024feaf3b58212edd388a4f016a71ce.diff LOG: [LLD] [COFF] Fix handling of immediates in ARM64_SECREL_HIGH12A (#200060) Just like for PAGEBASE_REL21, the immediate in SECREL_HIGH12A is the byte offset, not a page offset. The byte level offset is added to the symbol offset, which only then after that gets shifted right by 12. This makes the handling of this immediate consistent with what MS link.exe does. The existing testcase had a zero immediate in the instruction for this relocation. This makes it clear that immediate offsets with SECREL_HIGH12A do work fine, where the byte level offsets end up carrying over to the upper bits. (cherry picked from commit 5c95f6a859394757b92b0d63ff90b9175056deb6) Added: Modified: lld/COFF/Chunks.cpp lld/test/COFF/arm64-relocs-imports.test Removed: ################################################################################ diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 409491d4a1f89..efc9ff113e623 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -300,13 +300,16 @@ static void applySecRelHigh12A(const SectionChunk *sec, uint8_t *off, OutputSection *os, uint64_t s) { if (!checkSecRel(sec, os)) return; - uint64_t secRel = (s - os->getRVA()) >> 12; - if (0xfff < secRel) { + uint32_t orig = read32le(off); + uint64_t imm = (orig >> 10) & 0xFFF; + orig &= ~(0xFFF << 10); + imm = (s + imm - os->getRVA()) >> 12; + if (0xfff < imm) { error("overflow in SECREL_HIGH12A relocation in section: " + sec->getSectionName()); return; } - applyArm64Imm(off, secRel & 0xfff, 0); + write32le(off, orig | (imm << 10)); } static void applySecRelLdr(const SectionChunk *sec, uint8_t *off, diff --git a/lld/test/COFF/arm64-relocs-imports.test b/lld/test/COFF/arm64-relocs-imports.test index da2fd1f941d8a..c048a570674c7 100644 --- a/lld/test/COFF/arm64-relocs-imports.test +++ b/lld/test/COFF/arm64-relocs-imports.test @@ -39,8 +39,8 @@ # BEFORE: 74: 00000000 udf #0 # BEFORE: 78: 00000001 udf #1 # BEFORE: 7c: 00000001 udf #1 -# BEFORE: 80: 91000000 add x0, x0, #0 -# BEFORE: 84: 91400000 add x0, x0, #0, lsl #12 +# BEFORE: 80: 913c0000 add x0, x0, #3840 +# BEFORE: 84: 917c0000 add x0, x0, #3840, lsl #12 # BEFORE: 88: f9400000 ldr x0, [x0] # BEFORE: 8c: 00000001 udf #1 # BEFORE: 90: 30091a20 adr x0, 0x123d5 @@ -83,8 +83,8 @@ # AFTER: 140001074: 00000001 udf #1 # AFTER: 140001078: 00002009 udf #8201 # AFTER: 14000107c: 00000009 udf #9 -# AFTER: 140001080: 910e2000 add x0, x0, #904 -# AFTER: 140001084: 91400400 add x0, x0, #1, lsl #12 +# AFTER: 140001080: 910a2000 add x0, x0, #648 +# AFTER: 140001084: 91400800 add x0, x0, #2, lsl #12 # AFTER: 140001088: f941c400 ldr x0, [x0, #904] # AFTER: 14000108c: 00000003 udf #3 # AFTER: 140001090: 300995e0 adr x0, 0x14001434d @@ -104,7 +104,7 @@ sections: - Name: .text Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD6080000000000000001000000010000000000009100004091000040f901000000201a093001000054000000360100000002008090 + SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F90001003900010079000100B9000100F90001403D0001407D000140BD000140FD0001C03D0001003D0001007D000100BD000100FD0001803D000540F9201A01B000FC4FF9E0031F2AFE0741F8C0035FD60800000000000000010000000100000000003C9100007C91000040f901000000201a093001000054000000360100000002008090 Relocations: - VirtualAddress: 4 SymbolName: .Lstr _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
