[llvm] r200842 - ARM: Resolve thumb_bl fixup in same MCFragment.

Logan Chien tzuhsiang.chien at gmail.com
Wed Feb 5 06:15:16 PST 2014


Author: logan
Date: Wed Feb  5 08:15:16 2014
New Revision: 200842

URL: http://llvm.org/viewvc/llvm-project?rev=200842&view=rev
Log:
ARM: Resolve thumb_bl fixup in same MCFragment.

In Thumb1 mode, bl instruction might be selected for branches between
basic blocks in the function if the offset is greater than 2KB.
However, this might cause SEGV because the destination symbol
is not marked as thumb function and the execution mode will be reset
to ARM mode.

Since we are sure that these symbols are in the same data fragment, we
can simply resolve these local symbols, and don't emit any relocation
information for this bl instruction.

Added:
    llvm/trunk/test/MC/ARM/thumb-far-jump.s
Modified:
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp?rev=200842&r1=200841&r2=200842&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Wed Feb  5 08:15:16 2014
@@ -565,11 +565,18 @@ void ARMAsmBackend::processFixupValue(co
         Value |= 1;
     }
   }
+  // For Thumb1 BL instruction, it is possible to be a long jump between
+  // the basic blocks of the same function.  Thus, we would like to resolve
+  // the offset when the destination has the same MCFragment.
+  if (A && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
+    const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
+    MCSymbolData &SymData = Asm.getSymbolData(Sym);
+    IsResolved = (SymData.getFragment() == DF);
+  }
   // We must always generate a relocation for BL/BLX instructions if we have
   // a symbol to reference, as the linker relies on knowing the destination
   // symbol's thumb-ness to get interworking right.
   if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
-            (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl ||
             (unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
             (unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl ||
             (unsigned)Fixup.getKind() == ARM::fixup_arm_condbl))

Added: llvm/trunk/test/MC/ARM/thumb-far-jump.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-far-jump.s?rev=200842&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-far-jump.s (added)
+++ llvm/trunk/test/MC/ARM/thumb-far-jump.s Wed Feb  5 08:15:16 2014
@@ -0,0 +1,26 @@
+@ RUN: llvm-mc < %s -triple thumbv5-linux-gnueabi -filetype=obj -o - \
+@ RUN:   | llvm-readobj -r | FileCheck %s
+	.syntax	unified
+
+	.text
+	.align	2
+	.globl	main
+	.type	main,%function
+	.thumb_func
+main:
+	bl	end
+	.space 8192
+end:
+	bl	main2
+	bx	lr
+
+	.text
+	.align	2
+	.globl	main2
+	.type	main2,%function
+	.thumb_func
+main2:
+	bx	lr
+
+@ CHECK-NOT: 0x0 R_ARM_THM_CALL end 0x0
+@ CHECK: 0x2004 R_ARM_THM_CALL main2 0x0





More information about the llvm-commits mailing list