diff options
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 44 |
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, |