summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2014-02-05 14:15:16 +0000
committerLogan Chien <tzuhsiang.chien@gmail.com>2014-02-05 14:15:16 +0000
commitd5c48aa3d384e58e964317cd549a7e217080a08c (patch)
tree0dad09047a423899456488910444e53bca2baba0 /llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
parent99c9d6a0f67ac71188377404af221c00062b58e9 (diff)
downloadbcm5719-llvm-d5c48aa3d384e58e964317cd549a7e217080a08c.tar.gz
bcm5719-llvm-d5c48aa3d384e58e964317cd549a7e217080a08c.zip
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. llvm-svn: 200842
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 7db700472cb..698487980c3 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -565,11 +565,18 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
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))
OpenPOWER on IntegriCloud