1
0
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:
Rafael Espindola 2017-06-23 22:52:36 +00:00
parent b766456220
commit 4a88e44b0d
18 changed files with 114 additions and 62 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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());
}
}
}

View File

@ -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());

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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) {

View File

@ -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 {

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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 {

View File

@ -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();

View File

@ -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());

View File

@ -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