mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
ARM: move some logic from processFixupValue to applyFixup.
processFixupValue is called on every relaxation iteration. applyFixup is only called once at the very end. applyFixup is then the correct place to do last minute changes and value checks. While here, do proper range checks again for fixup_arm_thumb_bl. We used to do it, but dropped because of thumb2. We now do it again, but use the thumb2 range. llvm-svn: 306177
This commit is contained in:
parent
b766456220
commit
4a88e44b0d
@ -73,7 +73,8 @@ public:
|
||||
/// the offset specified by the fixup and following the fixup kind as
|
||||
/// appropriate. Errors (such as an out of range fixup value) should be
|
||||
/// reported via \p Ctx.
|
||||
virtual void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel,
|
||||
MCContext &Ctx) const = 0;
|
||||
|
||||
|
@ -195,8 +195,8 @@ private:
|
||||
/// finishLayout - Finalize a layout, including fragment lowering.
|
||||
void finishLayout(MCAsmLayout &Layout);
|
||||
|
||||
std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
|
||||
MCFragment &F, const MCFixup &Fixup);
|
||||
std::tuple<MCValue, uint64_t, bool>
|
||||
handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
|
||||
|
||||
public:
|
||||
/// Construct a new assembler instance.
|
||||
|
@ -648,9 +648,9 @@ void MCAssembler::writeSectionData(const MCSection *Sec,
|
||||
Layout.getSectionAddressSize(Sec));
|
||||
}
|
||||
|
||||
std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout,
|
||||
MCFragment &F,
|
||||
const MCFixup &Fixup) {
|
||||
std::tuple<MCValue, uint64_t, bool>
|
||||
MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F,
|
||||
const MCFixup &Fixup) {
|
||||
// Evaluate the fixup.
|
||||
MCValue Target;
|
||||
uint64_t FixedValue;
|
||||
@ -663,7 +663,7 @@ std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout,
|
||||
getWriter().recordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel,
|
||||
FixedValue);
|
||||
}
|
||||
return std::make_pair(FixedValue, IsPCRel);
|
||||
return std::make_tuple(Target, FixedValue, IsPCRel);
|
||||
}
|
||||
|
||||
void MCAssembler::layout(MCAsmLayout &Layout) {
|
||||
@ -740,9 +740,11 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
|
||||
for (const MCFixup &Fixup : Fixups) {
|
||||
uint64_t FixedValue;
|
||||
bool IsPCRel;
|
||||
std::tie(FixedValue, IsPCRel) = handleFixup(Layout, Frag, Fixup);
|
||||
getBackend().applyFixup(Fixup, Contents, FixedValue, IsPCRel,
|
||||
getContext());
|
||||
MCValue Target;
|
||||
std::tie(Target, FixedValue, IsPCRel) =
|
||||
handleFixup(Layout, Frag, Fixup);
|
||||
getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue,
|
||||
IsPCRel, getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,8 @@ public:
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override;
|
||||
@ -260,7 +261,8 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con
|
||||
}
|
||||
}
|
||||
|
||||
void AArch64AsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
|
||||
|
@ -36,7 +36,8 @@ public:
|
||||
const MCValue &Target, uint64_t &Value,
|
||||
bool &IsResolved) override;
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
@ -129,7 +130,8 @@ void AMDGPUAsmBackend::processFixupValue(const MCAssembler &Asm,
|
||||
Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
|
||||
}
|
||||
|
||||
void AMDGPUAsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
if (!Value)
|
||||
|
@ -358,11 +358,27 @@ static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
|
||||
return Value;
|
||||
}
|
||||
|
||||
unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx,
|
||||
bool IsLittleEndian,
|
||||
bool IsResolved) const {
|
||||
unsigned Kind = Fixup.getKind();
|
||||
|
||||
// MachO 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 (const MCSymbolRefExpr *A = Target.getSymA()) {
|
||||
if (A->hasSubsectionsViaSymbols() && Asm.isThumbFunc(&A->getSymbol()) &&
|
||||
(Kind == FK_Data_4 || Kind == ARM::fixup_arm_movw_lo16 ||
|
||||
Kind == ARM::fixup_arm_movt_hi16 || Kind == ARM::fixup_t2_movw_lo16 ||
|
||||
Kind == ARM::fixup_t2_movt_hi16))
|
||||
Value |= 1;
|
||||
}
|
||||
|
||||
switch (Kind) {
|
||||
default:
|
||||
Ctx.reportError(Fixup.getLoc(), "bad relocation fixup type");
|
||||
@ -505,6 +521,13 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
return swapHalfWords(out, IsLittleEndian);
|
||||
}
|
||||
case ARM::fixup_arm_thumb_bl: {
|
||||
// FIXME: We get both thumb1 and thumb2 in here, so we can only check for
|
||||
// the less strict thumb2 value.
|
||||
if (!isInt<26>(Value - 4)) {
|
||||
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The value doesn't encode the low bit (always zero) and is offset by
|
||||
// four. The 32-bit immediate value is encoded as
|
||||
// imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
|
||||
@ -724,21 +747,6 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
|
||||
const MCSymbolRefExpr *A = Target.getSymA();
|
||||
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
|
||||
const unsigned FixupKind = Fixup.getKind() ;
|
||||
// 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 (FixupKind == FK_Data_4 ||
|
||||
FixupKind == ARM::fixup_arm_movw_lo16 ||
|
||||
FixupKind == ARM::fixup_arm_movt_hi16 ||
|
||||
FixupKind == ARM::fixup_t2_movw_lo16 ||
|
||||
FixupKind == ARM::fixup_t2_movt_hi16) {
|
||||
if (Sym) {
|
||||
if (Asm.isThumbFunc(Sym))
|
||||
Value |= 1;
|
||||
}
|
||||
}
|
||||
if (IsResolved && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
|
||||
assert(Sym && "How did we resolve this?");
|
||||
|
||||
@ -747,7 +755,7 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
|
||||
|
||||
// If the symbol is out of range, produce a relocation and hope the
|
||||
// linker can handle it. GNU AS produces an error in this case.
|
||||
if (Sym->isExternal() || Value >= 0x400004)
|
||||
if (Sym->isExternal())
|
||||
IsResolved = false;
|
||||
}
|
||||
// Create relocations for unconditional branches to function symbols with
|
||||
@ -876,11 +884,13 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
|
||||
}
|
||||
}
|
||||
|
||||
void ARMAsmBackend::applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel,
|
||||
MCContext &Ctx) const {
|
||||
void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
|
||||
Value = adjustFixupValue(Fixup, Value, IsPCRel, Ctx, IsLittleEndian, true);
|
||||
Value = adjustFixupValue(Asm, Fixup, Target, Value, IsPCRel, Ctx,
|
||||
IsLittleEndian, true);
|
||||
if (!Value)
|
||||
return; // Doesn't change encoding.
|
||||
|
||||
|
@ -45,11 +45,13 @@ public:
|
||||
const MCValue &Target, uint64_t &Value,
|
||||
bool &IsResolved) override;
|
||||
|
||||
unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, bool IsPCRel,
|
||||
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, uint64_t Value, bool IsPCRel,
|
||||
MCContext &Ctx, bool IsLittleEndian,
|
||||
bool IsResolved) const;
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
unsigned getRelaxedOpcode(unsigned Op) const;
|
||||
|
@ -27,7 +27,8 @@ public:
|
||||
: MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
|
||||
~BPFAsmBackend() override = default;
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
@ -61,9 +62,10 @@ bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void BPFAsmBackend::applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel,
|
||||
MCContext &Ctx) const {
|
||||
void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
|
||||
assert(Value == 0);
|
||||
} else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) {
|
||||
|
@ -415,7 +415,8 @@ public:
|
||||
/// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
|
||||
/// data fragment, at the offset specified by the fixup and following the
|
||||
/// fixup kind as appropriate.
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t FixupValue, bool IsPCRel,
|
||||
MCContext &Ctx) const override {
|
||||
|
||||
|
@ -49,7 +49,8 @@ public:
|
||||
LanaiAsmBackend(const Target &T, Triple::OSType OST)
|
||||
: MCAsmBackend(), OSType(OST) {}
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
@ -88,7 +89,8 @@ bool LanaiAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LanaiAsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void LanaiAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool /*IsPCRel*/, MCContext & /*Ctx*/) const {
|
||||
MCFixupKind Kind = Fixup.getKind();
|
||||
|
@ -235,7 +235,8 @@ static unsigned calculateMMLEIndex(unsigned i) {
|
||||
/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
|
||||
/// data fragment, at the offset specified by the fixup and following the
|
||||
/// fixup kind as appropriate.
|
||||
void MipsAsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
MCFixupKind Kind = Fixup.getKind();
|
||||
|
@ -38,7 +38,8 @@ public:
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
|
||||
|
@ -113,7 +113,8 @@ public:
|
||||
return (IsLittleEndian? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override {
|
||||
Value = adjustFixupValue(Fixup.getKind(), Value);
|
||||
if (!Value) return; // Doesn't change encoding.
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
: MCAsmBackend(), OSABI(OSABI), Is64Bit(Is64Bit) {}
|
||||
~RISCVAsmBackend() override {}
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
|
||||
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
@ -69,7 +70,8 @@ bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RISCVAsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
return;
|
||||
|
@ -273,7 +273,8 @@ namespace {
|
||||
ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
|
||||
SparcAsmBackend(T), OSType(OSType) { }
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel,
|
||||
MCContext &Ctx) const override {
|
||||
|
||||
|
@ -50,7 +50,8 @@ public:
|
||||
return SystemZ::NumTargetFixupKinds;
|
||||
}
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override;
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override {
|
||||
return false;
|
||||
@ -89,7 +90,9 @@ SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void SystemZMCAsmBackend::applyFixup(const MCFixup &Fixup,
|
||||
void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data, uint64_t Value,
|
||||
bool IsPCRel, MCContext &Ctx) const {
|
||||
MCFixupKind Kind = Fixup.getKind();
|
||||
|
@ -108,7 +108,8 @@ public:
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void applyFixup(const MCFixup &Fixup, MutableArrayRef<char> Data,
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel, MCContext &Ctx) const override {
|
||||
unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
|
||||
|
||||
|
@ -1,25 +1,43 @@
|
||||
@ RUN: llvm-mc < %s -triple thumbv5-linux-gnueabi -filetype=obj -o - \
|
||||
@ RUN: | llvm-readobj -r | FileCheck %s
|
||||
@ RUN: not llvm-mc %s -triple thumbv5-linux-gnueabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
.code 16
|
||||
|
||||
bl end
|
||||
.space 0x3fffff
|
||||
.space 0x1ffffff
|
||||
end:
|
||||
|
||||
bl end2
|
||||
.space 0x3fffff
|
||||
.space 0x1ffffff
|
||||
.global end2
|
||||
end2:
|
||||
|
||||
bl end3
|
||||
.space 0x400000
|
||||
.space 0x2000000
|
||||
.global end3
|
||||
end3:
|
||||
|
||||
// CHECK-NOT: error
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
|
||||
bl end4
|
||||
.space 0x400000
|
||||
// CHECK-NOT: error
|
||||
.space 0x2000000
|
||||
end4:
|
||||
|
||||
@ CHECK: 0x400003 R_ARM_THM_CALL end2 0x0
|
||||
@ CHECK: 0x800006 R_ARM_THM_CALL end3 0x0
|
||||
@ CHECK: 0xC0000A R_ARM_THM_CALL end4 0x0
|
||||
start1:
|
||||
.space 0x1fffffc
|
||||
bl start1
|
||||
|
||||
.global start2
|
||||
start2:
|
||||
.space 0x1fffffc
|
||||
bl start2
|
||||
|
||||
.global start3
|
||||
start3:
|
||||
.space 0x1fffffd
|
||||
bl start3
|
||||
|
||||
start4:
|
||||
.space 0x1fffffd
|
||||
// CHECK: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
|
||||
bl start4
|
||||
|
Loading…
Reference in New Issue
Block a user