diff options
Diffstat (limited to 'contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 0fc7582..a58d5b3 100644 --- a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -375,7 +375,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_movt_hi16: if (!IsPCRel) Value >>= 16; - // Fallthrough + LLVM_FALLTHROUGH; case ARM::fixup_arm_movw_lo16: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned Lo12 = Value & 0x0FFF; @@ -387,7 +387,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_t2_movt_hi16: if (!IsPCRel) Value >>= 16; - // Fallthrough + LLVM_FALLTHROUGH; case ARM::fixup_t2_movw_lo16: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned i = (Value & 0x800) >> 11; @@ -403,7 +403,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_ldst_pcrel_12: // ARM PC-relative values are offset by 8. Value -= 4; - // FALLTHROUGH + LLVM_FALLTHROUGH; case ARM::fixup_t2_ldst_pcrel_12: { // Offset by 4, adjusted by two due to the half-word ordering of thumb. Value -= 4; @@ -541,7 +541,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, // // Note that the halfwords are stored high first, low second; so we need // to transpose the fixup value here to map properly. - if (Ctx && Value % 4 != 0) { + if (Ctx && Value % 4 != 0) { Ctx->reportError(Fixup.getLoc(), "misaligned ARM call destination"); return 0; } @@ -578,6 +578,13 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, // Offset by 4, and don't encode the low two bits. return ((Value - 4) >> 2) & 0xff; case ARM::fixup_arm_thumb_cb: { + // CB instructions can only branch to offsets in [4, 126] in multiples of 2 + // so ensure that the raw value LSB is zero and it lies in [2, 130]. + // An offset of 2 will be relaxed to a NOP. + if (Ctx && ((int64_t)Value < 2 || Value > 0x82 || Value & 1)) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } // Offset by 4 and don't encode the lower bit, which is always 0. // FIXME: diagnose if no Thumb2 uint32_t Binary = (Value - 4) >> 1; @@ -623,7 +630,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_pcrel_10: Value = Value - 4; // ARM fixups offset by an additional word and don't // need to adjust for the half-word ordering. - // Fall through. + LLVM_FALLTHROUGH; case ARM::fixup_t2_pcrel_10: { // Offset by 4, adjusted by two due to the half-word ordering of thumb. Value = Value - 4; @@ -650,7 +657,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value, case ARM::fixup_arm_pcrel_9: Value = Value - 4; // ARM fixups offset by an additional word and don't // need to adjust for the half-word ordering. - // Fall through. + LLVM_FALLTHROUGH; case ARM::fixup_t2_pcrel_9: { // Offset by 4, adjusted by two due to the half-word ordering of thumb. Value = Value - 4; @@ -696,14 +703,16 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm, bool &IsResolved) { const MCSymbolRefExpr *A = Target.getSymA(); const MCSymbol *Sym = A ? &A->getSymbol() : nullptr; - // Some fixups to thumb function symbols need the low bit (thumb bit) - // twiddled. - if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 && - (unsigned)Fixup.getKind() != ARM::fixup_t2_ldst_pcrel_12 && - (unsigned)Fixup.getKind() != ARM::fixup_arm_adr_pcrel_12 && - (unsigned)Fixup.getKind() != ARM::fixup_thumb_adr_pcrel_10 && - (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 && - (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp) { + // MachO (the only user of "Value") tries to make .o files that look vaguely + // pre-linked, so for MOVW/MOVT and .word relocations they put the Thumb bit + // into the addend if possible. Other relocation types don't want this bit + // though (branches couldn't encode it if it *was* present, and no other + // relocations exist) and it can interfere with checking valid expressions. + if ((unsigned)Fixup.getKind() == FK_Data_4 || + (unsigned)Fixup.getKind() == ARM::fixup_arm_movw_lo16 || + (unsigned)Fixup.getKind() == ARM::fixup_arm_movt_hi16 || + (unsigned)Fixup.getKind() == ARM::fixup_t2_movw_lo16 || + (unsigned)Fixup.getKind() == ARM::fixup_t2_movt_hi16) { if (Sym) { if (Asm.isThumbFunc(Sym)) Value |= 1; @@ -1111,6 +1120,7 @@ static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch) { MCAsmBackend *llvm::createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TheTriple, StringRef CPU, + const MCTargetOptions &Options, bool isLittle) { switch (TheTriple.getObjectFormat()) { default: @@ -1131,24 +1141,28 @@ MCAsmBackend *llvm::createARMAsmBackend(const Target &T, MCAsmBackend *llvm::createARMLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU) { - return createARMAsmBackend(T, MRI, TT, CPU, true); + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + return createARMAsmBackend(T, MRI, TT, CPU, Options, true); } MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU) { - return createARMAsmBackend(T, MRI, TT, CPU, false); + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + return createARMAsmBackend(T, MRI, TT, CPU, Options, false); } MCAsmBackend *llvm::createThumbLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU) { - return createARMAsmBackend(T, MRI, TT, CPU, true); + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + return createARMAsmBackend(T, MRI, TT, CPU, Options, true); } MCAsmBackend *llvm::createThumbBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU) { - return createARMAsmBackend(T, MRI, TT, CPU, false); + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options) { + return createARMAsmBackend(T, MRI, TT, CPU, Options, false); } |