https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/200128
Backport 5c95f6a859394757b92b0d63ff90b9175056deb6 Requested by: @mstorsjo >From 47483c0b6531cddd9874304f0abc52e0ca7103f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <[email protected]> Date: Thu, 28 May 2026 11:03:51 +0300 Subject: [PATCH] [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) --- lld/COFF/Chunks.cpp | 9 ++++++--- lld/test/COFF/arm64-relocs-imports.test | 10 +++++----- 2 files changed, 11 insertions(+), 8 deletions(-) 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
