[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