Skip to content

MCAsmBackend::applyFixup: Change Data to indicate the relocated location #151724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/include/llvm/MC/MCAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ class LLVM_ABI MCAsmBackend {
/// appropriate. Errors (such as an out of range fixup value) should be
/// reported via \p Ctx.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some documentation to this function to explain that the bounds on Data are given by the combination of fragment size and fixup offset. This is not obvious from the signature.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved the comment.

virtual void applyFixup(const MCFragment &, const MCFixup &,
const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved) = 0;
const MCValue &Target, char *Data, uint64_t Value,
bool IsResolved) = 0;

/// @}

Expand Down
3 changes: 1 addition & 2 deletions llvm/include/llvm/MC/MCAssembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ class MCAssembler {
/// \param RecordReloc Record relocation if needed.
/// relocation.
bool evaluateFixup(const MCFragment &F, MCFixup &Fixup, MCValue &Target,
uint64_t &Value, bool RecordReloc,
MutableArrayRef<char> Contents) const;
uint64_t &Value, bool RecordReloc, char *Data) const;

/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
Expand Down
34 changes: 18 additions & 16 deletions llvm/lib/MC/MCAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {

bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,
MCValue &Target, uint64_t &Value,
bool RecordReloc,
MutableArrayRef<char> Contents) const {
bool RecordReloc, char *Data) const {
++stats::evaluateFixup;

// FIXME: This code has some duplication with recordRelocation. We should
Expand Down Expand Up @@ -185,7 +184,7 @@ bool MCAssembler::evaluateFixup(const MCFragment &F, MCFixup &Fixup,

if (IsResolved && mc::isRelocRelocation(Fixup.getKind()))
IsResolved = false;
getBackend().applyFixup(F, Fixup, Target, Contents, Value, IsResolved);
getBackend().applyFixup(F, Fixup, Target, Data, Value, IsResolved);
return true;
}

Expand Down Expand Up @@ -703,21 +702,24 @@ void MCAssembler::layout() {
for (MCFixup &Fixup : F.getFixups()) {
uint64_t FixedValue;
MCValue Target;
assert(mc::isRelocRelocation(Fixup.getKind()) ||
Fixup.getOffset() <= F.getFixedSize());
evaluateFixup(F, Fixup, Target, FixedValue,
/*RecordReloc=*/true, Contents);
/*RecordReloc=*/true,
Contents.data() + Fixup.getOffset());
}
if (F.getVarFixups().size()) {
// In the variable part, fixup offsets are relative to the fixed part's
// start. Extend the variable contents to the left to account for the
// fixed part size.
Contents = MutableArrayRef(F.getParent()->ContentStorage)
.slice(F.VarContentStart - Contents.size(), F.getSize());
for (MCFixup &Fixup : F.getVarFixups()) {
uint64_t FixedValue;
MCValue Target;
evaluateFixup(F, Fixup, Target, FixedValue,
/*RecordReloc=*/true, Contents);
}
// In the variable part, fixup offsets are relative to the fixed part's
// start.
for (MCFixup &Fixup : F.getVarFixups()) {
uint64_t FixedValue;
MCValue Target;
assert(mc::isRelocRelocation(Fixup.getKind()) ||
(Fixup.getOffset() >= F.getFixedSize() &&
Fixup.getOffset() <= F.getSize()));
char *Data =
F.getVarContents().data() + (Fixup.getOffset() - F.getFixedSize());
evaluateFixup(F, Fixup, Target, FixedValue,
/*RecordReloc=*/true, Data);
}
}
}
Expand Down
18 changes: 8 additions & 10 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ class AArch64AsmBackend : public MCAsmBackend {
}

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;

bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value) const override;
Expand Down Expand Up @@ -421,9 +420,8 @@ static bool shouldForceRelocation(const MCFixup &Fixup) {
}

void AArch64AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
if (shouldForceRelocation(Fixup))
IsResolved = false;
maybeAddReloc(F, Fixup, Target, Value, IsResolved);
Expand Down Expand Up @@ -471,15 +469,15 @@ void AArch64AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
if (FulleSizeInBytes == 0) {
// Handle as little-endian
for (unsigned i = 0; i != NumBytes; ++i) {
Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
Data[i] |= uint8_t((Value >> (i * 8)) & 0xff);
}
} else {
// Handle as big-endian
assert((Offset + FulleSizeInBytes) <= Data.size() && "Invalid fixup size!");
assert(Offset + FulleSizeInBytes <= F.getSize() && "Invalid fixup size!");
assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!");
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx = FulleSizeInBytes - 1 - i;
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
Data[Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}

Expand All @@ -492,9 +490,9 @@ void AArch64AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
// If the immediate is negative, generate MOVN else MOVZ.
// (Bit 30 = 0) ==> MOVN, (Bit 30 = 1) ==> MOVZ.
if (SignedValue < 0)
Data[Offset + 3] &= ~(1 << 6);
Data[3] &= ~(1 << 6);
else
Data[Offset + 3] |= (1 << 6);
Data[3] |= (1 << 6);
}
}

Expand Down
10 changes: 4 additions & 6 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
AMDGPUAsmBackend(const Target &T) : MCAsmBackend(llvm::endianness::little) {}

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;
bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value) const override;

Expand Down Expand Up @@ -129,9 +128,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
}

void AMDGPUAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
if (Target.getSpecifier())
IsResolved = false;
maybeAddReloc(F, Fixup, Target, Value, IsResolved);
Expand All @@ -154,7 +152,7 @@ void AMDGPUAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
// For each byte of the fragment that the fixup touches, mask in the bits from
// the fixup value.
for (unsigned i = 0; i != NumBytes; ++i)
Data[Offset + i] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
Data[i] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
}

std::optional<MCFixupKind>
Expand Down
9 changes: 4 additions & 5 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,9 +1108,8 @@ std::optional<bool> ARMAsmBackend::evaluateFixup(const MCFragment &F,
}

void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
if (IsResolved && shouldForceRelocation(Fixup, Target))
IsResolved = false;
maybeAddReloc(F, Fixup, Target, Value, IsResolved);
Expand All @@ -1131,7 +1130,7 @@ void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
unsigned FullSizeBytes;
if (Endian == llvm::endianness::big) {
FullSizeBytes = getFixupKindContainerSizeBytes(Kind);
assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
assert((Offset + FullSizeBytes) <= F.getSize() && "Invalid fixup size!");
assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
}

Expand All @@ -1141,7 +1140,7 @@ void ARMAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx =
Endian == llvm::endianness::little ? i : (FullSizeBytes - 1 - i);
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
Data[Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}

Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ class ARMAsmBackend : public MCAsmBackend {
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
uint64_t &) override;
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;

unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const;

Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,8 @@ AVRAsmBackend::createObjectTargetWriter() const {
}

void AVRAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
// AVR sets the fixup value to bypass the assembly time overflow with a
// relocation.
if (IsResolved) {
Expand Down Expand Up @@ -404,7 +403,7 @@ void AVRAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
// bits from the fixup value.
for (unsigned i = 0; i < NumBytes; ++i) {
uint8_t mask = (((Value >> (i * 8)) & 0xff));
Data[Offset + i] |= mask;
Data[i] |= mask;
}
}

Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ class AVRAsmBackend : public MCAsmBackend {
createObjectTargetWriter() const override;

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;

std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
Expand Down
29 changes: 12 additions & 17 deletions llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class BPFAsmBackend : public MCAsmBackend {
~BPFAsmBackend() override = default;

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;

std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override;
Expand Down Expand Up @@ -66,35 +65,32 @@ bool BPFAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
}

void BPFAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
maybeAddReloc(F, Fixup, Target, Value, IsResolved);
if (Fixup.getKind() == FK_SecRel_8) {
// The Value is 0 for global variables, and the in-section offset
// for static variables. Write to the immediate field of the inst.
assert(Value <= UINT32_MAX);
support::endian::write<uint32_t>(&Data[Fixup.getOffset() + 4],
static_cast<uint32_t>(Value),
support::endian::write<uint32_t>(Data + 4, static_cast<uint32_t>(Value),
Endian);
} else if (Fixup.getKind() == FK_Data_4 && !Fixup.isPCRel()) {
support::endian::write<uint32_t>(&Data[Fixup.getOffset()], Value, Endian);
support::endian::write<uint32_t>(Data, Value, Endian);
} else if (Fixup.getKind() == FK_Data_8) {
support::endian::write<uint64_t>(&Data[Fixup.getOffset()], Value, Endian);
support::endian::write<uint64_t>(Data, Value, Endian);
} else if (Fixup.getKind() == FK_Data_4 && Fixup.isPCRel()) {
Value = (uint32_t)((Value - 8) / 8);
if (Endian == llvm::endianness::little) {
Data[Fixup.getOffset() + 1] = 0x10;
support::endian::write32le(&Data[Fixup.getOffset() + 4], Value);
Data[1] = 0x10;
support::endian::write32le(Data + 4, Value);
} else {
Data[Fixup.getOffset() + 1] = 0x1;
support::endian::write32be(&Data[Fixup.getOffset() + 4], Value);
Data[1] = 0x1;
support::endian::write32be(Data + 4, Value);
}
} else if (Fixup.getKind() == BPF::FK_BPF_PCRel_4) {
// The input Value represents the number of bytes.
Value = (uint32_t)((Value - 8) / 8);
support::endian::write<uint32_t>(&Data[Fixup.getOffset() + 4], Value,
Endian);
support::endian::write<uint32_t>(Data + 4, Value, Endian);
} else {
assert(Fixup.getKind() == FK_Data_2 && Fixup.isPCRel());

Expand All @@ -103,8 +99,7 @@ void BPFAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
report_fatal_error("Branch target out of insn range");

Value = (uint16_t)((Value - 8) / 8);
support::endian::write<uint16_t>(&Data[Fixup.getOffset() + 2], Value,
Endian);
support::endian::write<uint16_t>(Data + 2, Value, Endian);
}
}

Expand Down
15 changes: 7 additions & 8 deletions llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,8 @@ std::optional<bool> CSKYAsmBackend::evaluateFixup(const MCFragment &F,
}

void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) {
const MCValue &Target, char *Data,
uint64_t Value, bool IsResolved) {
if (IsResolved && shouldForceRelocation(Fixup, Target))
IsResolved = false;
maybeAddReloc(F, Fixup, Target, Value, IsResolved);
Expand Down Expand Up @@ -228,14 +227,14 @@ void CSKYAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
bool IsInstFixup = (Kind >= FirstTargetFixupKind);

if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) {
Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff);
Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff);
Data[Offset + 2] |= uint8_t(Value & 0xff);
Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff);
Data[0] |= uint8_t((Value >> 16) & 0xff);
Data[1] |= uint8_t((Value >> 24) & 0xff);
Data[2] |= uint8_t(Value & 0xff);
Data[3] |= uint8_t((Value >> 8) & 0xff);
} else {
for (unsigned I = 0; I != NumBytes; I++) {
unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I);
Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff);
Data[Idx] |= uint8_t((Value >> (I * 8)) & 0xff);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class CSKYAsmBackend : public MCAsmBackend {
std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
uint64_t &) override;
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override;
char *Data, uint64_t Value, bool IsResolved) override;

MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;

Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ class DXILAsmBackend : public MCAsmBackend {
~DXILAsmBackend() override = default;

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) override {}
char *Data, uint64_t Value, bool IsResolved) override {}

std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
Expand Down
9 changes: 3 additions & 6 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,7 @@ class HexagonAsmBackend : public MCAsmBackend {
}

void applyFixup(const MCFragment &, const MCFixup &, const MCValue &,
MutableArrayRef<char> Data, uint64_t FixupValue,
bool IsResolved) override;
char *Data, uint64_t FixupValue, bool IsResolved) override;

bool isInstRelaxable(MCInst const &HMI) const {
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
Expand Down Expand Up @@ -649,8 +648,7 @@ class HexagonAsmBackend : public MCAsmBackend {
} // namespace

void HexagonAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data,
const MCValue &Target, char *InstAddr,
uint64_t FixupValue, bool IsResolved) {
if (IsResolved && shouldForceRelocation(Fixup))
IsResolved = false;
Expand All @@ -670,7 +668,6 @@ void HexagonAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
uint32_t Offset = Fixup.getOffset();
unsigned NumBytes = getFixupKindNumBytes(Kind);
assert(Offset + NumBytes <= F.getSize() && "Invalid fixup offset!");
char *InstAddr = Data.data() + Offset;

Value = adjustFixupValue(Kind, FixupValue);
if (!Value)
Expand Down Expand Up @@ -758,7 +755,7 @@ void HexagonAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
(InstAddr[i] << (i * 8)) & (0xff << (i * 8));
dbgs() << "\tBValue=0x"; dbgs().write_hex(Value) << ": AValue=0x";
dbgs().write_hex(FixupValue)
<< ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x";
<< ": Offset=" << Offset << ": Size=" << F.getSize() << ": OInst=0x";
dbgs().write_hex(OldData) << ": Reloc=0x"; dbgs().write_hex(Reloc););

// For each byte of the fragment that the fixup touches, mask in the
Expand Down
Loading
Loading