aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCAssembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r--llvm/lib/MC/MCAssembler.cpp44
1 files changed, 24 insertions, 20 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index e142ac1..5c8e904 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -59,7 +59,8 @@ STATISTIC(EmittedFillFragments,
"Number of emitted assembler fragments - fill");
STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");
STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");
-STATISTIC(evaluateFixup, "Number of evaluated fixups");
+STATISTIC(Fixups, "Number of fixups");
+STATISTIC(FixupEvalForRelax, "Number of fixup evaluations for relaxation");
STATISTIC(ObjectBytes, "Number of emitted object file bytes");
STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
@@ -106,7 +107,6 @@ void MCAssembler::reset() {
bool MCAssembler::registerSection(MCSection &Section) {
if (Section.isRegistered())
return false;
- assert(Section.curFragList()->Head && "allocInitialFragment not called");
Sections.push_back(&Section);
Section.setIsRegistered(true);
return true;
@@ -141,9 +141,9 @@ 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 {
- ++stats::evaluateFixup;
+ bool RecordReloc, uint8_t *Data) const {
+ if (RecordReloc)
+ ++stats::Fixups;
// FIXME: This code has some duplication with recordRelocation. We should
// probably merge the two into a single callback that tries to evaluate a
@@ -186,7 +186,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;
}
@@ -704,21 +704,25 @@ void MCAssembler::layout() {
for (MCFixup &Fixup : F.getFixups()) {
uint64_t FixedValue;
MCValue Target;
+ assert(mc::isRelocRelocation(Fixup.getKind()) ||
+ Fixup.getOffset() <= F.getFixedSize());
+ auto *Data =
+ reinterpret_cast<uint8_t *>(Contents.data() + Fixup.getOffset());
evaluateFixup(F, Fixup, Target, FixedValue,
- /*RecordReloc=*/true, Contents);
+ /*RecordReloc=*/true, Data);
}
- 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()));
+ auto *Data = reinterpret_cast<uint8_t *>(
+ F.getVarContents().data() + (Fixup.getOffset() - F.getFixedSize()));
+ evaluateFixup(F, Fixup, Target, FixedValue,
+ /*RecordReloc=*/true, Data);
}
}
}
@@ -736,7 +740,7 @@ void MCAssembler::Finish() {
bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
const MCFixup &Fixup) const {
- assert(getBackendPtr() && "Expected assembler backend");
+ ++stats::FixupEvalForRelax;
MCValue Target;
uint64_t Value;
bool Resolved = evaluateFixup(F, const_cast<MCFixup &>(Fixup), Target, Value,