diff options
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp')
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 9f6bc31f8aa0..1223210a76f6 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -579,13 +579,27 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm, case ARM::fixup_arm_uncondbl: case ARM::fixup_arm_condbl: case ARM::fixup_arm_blx: + // Check that the relocation value is legal. + Value -= 8; + if (!isInt<26>(Value)) { + Ctx.reportError(Fixup.getLoc(), "Relocation out of range"); + return 0; + } + // Alignment differs for blx. Because we are switching to thumb ISA, we use + // 16-bit alignment. Otherwise, use 32-bit. + if ((Kind == ARM::fixup_arm_blx && Value % 2 != 0) || + (Kind != ARM::fixup_arm_blx && Value % 4 != 0)) { + Ctx.reportError(Fixup.getLoc(), "Relocation not aligned"); + return 0; + } + // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Fixup.getValue())) if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL) return 0; - return 0xffffff & ((Value - 8) >> 2); + return 0xffffff & (Value >> 2); case ARM::fixup_t2_uncondbranch: { if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved && Value != 4) { |
