[PATCH] D155732: [MC][COFF][AArch64] Avoid incorrect IMAGE_REL_ARM64_BRANCH26 relocations.
Hiroshi Yamauchi via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 19 10:59:56 PDT 2023
hjyamauchi created this revision.
Herald added subscribers: hiraditya, kristof.beyls.
Herald added a project: All.
hjyamauchi requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
For a b/bl instruction that branches a temporary symbol (private assembly label), an IMAGE_REL_ARM64_BRANCH26 relocation to another symbol + a non-zero offset could be emitted but the linkers don't support this type of relocation and cause incorrect relocations and crashes. Avoid emitting this type of relocations.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D155732
Files:
llvm/lib/MC/WinCOFFObjectWriter.cpp
llvm/test/MC/AArch64/coff-relocations-branch26.s
Index: llvm/test/MC/AArch64/coff-relocations-branch26.s
===================================================================
--- /dev/null
+++ llvm/test/MC/AArch64/coff-relocations-branch26.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple aarch64-unknown-windows-msvc -filetype obj %s -o - | \
+// RUN: llvm-objdump -D -r - | FileCheck %s
+
+ .text
+main:
+ nop
+ b .Ltarget
+ b .Lother_target
+.Ltarget:
+ ret
+
+// A privte label target in another section
+ .section "other"
+ nop
+.Lother_target:
+ ret
+
+// Check that the first branch has a correct branch offset and that
+// the second (cross-section) branch has a zero offset with a
+// relocation.
+//
+// CHECK: 0000000000000000 <main>:
+// CHECK: 0: d503201f nop
+// CHECK: 4: 14000002 b 0xc <main+0xc>
+// CHECK: 8: 14000000 b 0x8 <main+0x8>
+// CHECK: 0000000000000008: IMAGE_REL_ARM64_BRANCH26 $L.Lother_target
+// CHECK: c: d65f03c0 ret
+// CHECK: 0000000000000000 <other>:
+// CHECK: 0: d503201f nop
+// CHECK: 0000000000000004 <$L.Lother_target>:
+// CHECK: 4: d65f03c0 ret
Index: llvm/lib/MC/WinCOFFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -944,6 +944,38 @@
Reloc.Data.Type = OWriter.TargetObjectWriter->getRelocType(
Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
+ if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 &&
+ Reloc.Data.Type == COFF::IMAGE_REL_ARM64_BRANCH26 &&
+ A.isTemporary()) {
+ // For a b/bl instruction that branches a temporary symbol
+ // (private assembly label), an IMAGE_REL_ARM64_BRANCH26
+ // relocation to another symbol + a non-zero offset could be
+ // emitted but the linkers (link.exe and lld) don't currently
+ // support this type of relocation and cause incorrect relocations
+ // and crashes. Avoid this by using a relative offset without a
+ // relocation if within the same section or inserting a new symbol
+ // otherwise.
+ if (MCSec == &A.getSection()) {
+ // If within the same section, write the relative offset in the
+ // instruction to symbol A and drop the relocation. Set to the
+ // correct relative offset.
+ FixedValue = Layout.getSymbolOffset(A) - Reloc.Data.VirtualAddress;
+ // Cancel the increment above.
+ --Reloc.Symb->Relocations;
+ // Drop the relocation.
+ return;
+ } else {
+ // Add a non-temporary symbol at A and use a relocation to that
+ // symbol without an offset.
+ COFFSymbol *NewSymbol = createSymbol(("$L" + A.getName()).str());
+ NewSymbol->Section = SectionMap[&A.getSection()];
+ NewSymbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL;
+ NewSymbol->Data.Value = Layout.getSymbolOffset(A);
+ Reloc.Symb = NewSymbol;
+ FixedValue = 0;
+ }
+ }
+
// The *_REL32 relocations are relative to the end of the relocation,
// not to the start.
if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D155732.542112.patch
Type: text/x-patch
Size: 3153 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230719/9190535f/attachment.bin>
More information about the llvm-commits
mailing list