diff options
author | Fangrui Song <i@maskray.me> | 2024-06-30 14:22:25 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2024-06-30 14:22:25 -0700 |
commit | 10c894cffd0f4bef21b54a43b5780240532e44cf (patch) | |
tree | d9cbca35f77169754a8d9b5f489d983561e46a9c /llvm | |
parent | 038bc1c18c786e14cc306401b00144265f8860f5 (diff) | |
download | llvm-10c894cffd0f4bef21b54a43b5780240532e44cf.zip llvm-10c894cffd0f4bef21b54a43b5780240532e44cf.tar.gz llvm-10c894cffd0f4bef21b54a43b5780240532e44cf.tar.bz2 |
[MC] Move MCAsmLayout from MCFragment.cpp to MCAssembler.cpp. NFC
8d736236d36ca5c98832b7631aea2e538f6a54aa (2015) moved these MCAsmLayout
functions to MCFragment.cpp, but the original placement is better as
these functions are tightly coupled with MCAssembler.cpp.
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 132 | ||||
-rw-r--r-- | llvm/lib/MC/MCFragment.cpp | 127 |
2 files changed, 127 insertions, 132 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index dd563d8..e6e77d3 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -383,6 +383,16 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, llvm_unreachable("invalid fragment kind"); } +MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) { + // Compute the section layout order. Virtual sections must go last. + for (MCSection &Sec : Asm) + if (!Sec.isVirtualSection()) + SectionOrder.push_back(&Sec); + for (MCSection &Sec : Asm) + if (Sec.isVirtualSection()) + SectionOrder.push_back(&Sec); +} + // Compute the amount of padding required before the fragment \p F to // obey bundling restrictions, where \p FOffset is the fragment's offset in // its section and \p FSize is the fragment's size. @@ -464,11 +474,6 @@ void MCAsmLayout::layoutBundle(MCFragment *Prev, MCFragment *F) { DF->Offset = EF->Offset; } -uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { - ensureValid(F); - return F->Offset; -} - void MCAsmLayout::ensureValid(const MCFragment *Frag) const { MCSection &Sec = *Frag->getParent(); if (Sec.hasLayout()) @@ -487,6 +492,123 @@ void MCAsmLayout::ensureValid(const MCFragment *Frag) const { } } +uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { + ensureValid(F); + return F->Offset; +} + +// Simple getSymbolOffset helper for the non-variable case. +static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, + bool ReportError, uint64_t &Val) { + if (!S.getFragment()) { + if (ReportError) + report_fatal_error("unable to evaluate offset to undefined symbol '" + + S.getName() + "'"); + return false; + } + Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset(); + return true; +} + +static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, + bool ReportError, uint64_t &Val) { + if (!S.isVariable()) + return getLabelOffset(Layout, S, ReportError, Val); + + // If SD is a variable, evaluate it. + MCValue Target; + if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) + report_fatal_error("unable to evaluate offset for variable '" + + S.getName() + "'"); + + uint64_t Offset = Target.getConstant(); + + const MCSymbolRefExpr *A = Target.getSymA(); + if (A) { + uint64_t ValA; + // FIXME: On most platforms, `Target`'s component symbols are labels from + // having been simplified during evaluation, but on Mach-O they can be + // variables due to PR19203. This, and the line below for `B` can be + // restored to call `getLabelOffset` when PR19203 is fixed. + if (!getSymbolOffsetImpl(Layout, A->getSymbol(), ReportError, ValA)) + return false; + Offset += ValA; + } + + const MCSymbolRefExpr *B = Target.getSymB(); + if (B) { + uint64_t ValB; + if (!getSymbolOffsetImpl(Layout, B->getSymbol(), ReportError, ValB)) + return false; + Offset -= ValB; + } + + Val = Offset; + return true; +} + +bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { + return getSymbolOffsetImpl(*this, S, false, Val); +} + +uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const { + uint64_t Val; + getSymbolOffsetImpl(*this, S, true, Val); + return Val; +} + +const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { + if (!Symbol.isVariable()) + return &Symbol; + + const MCExpr *Expr = Symbol.getVariableValue(); + MCValue Value; + if (!Expr->evaluateAsValue(Value, *this)) { + Assembler.getContext().reportError(Expr->getLoc(), + "expression could not be evaluated"); + return nullptr; + } + + const MCSymbolRefExpr *RefB = Value.getSymB(); + if (RefB) { + Assembler.getContext().reportError( + Expr->getLoc(), + Twine("symbol '") + RefB->getSymbol().getName() + + "' could not be evaluated in a subtraction expression"); + return nullptr; + } + + const MCSymbolRefExpr *A = Value.getSymA(); + if (!A) + return nullptr; + + const MCSymbol &ASym = A->getSymbol(); + const MCAssembler &Asm = getAssembler(); + if (ASym.isCommon()) { + Asm.getContext().reportError(Expr->getLoc(), + "Common symbol '" + ASym.getName() + + "' cannot be used in assignment expr"); + return nullptr; + } + + return &ASym; +} + +uint64_t MCAsmLayout::getSectionAddressSize(const MCSection *Sec) const { + // The size is the last fragment's end offset. + const MCFragment &F = *Sec->curFragList()->Tail; + return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); +} + +uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const { + // Virtual sections have no file size. + if (Sec->isVirtualSection()) + return 0; + + // Otherwise, the file size is the same as the address space size. + return getSectionAddressSize(Sec); +} + bool MCAssembler::registerSymbol(const MCSymbol &Symbol) { bool Changed = !Symbol.isRegistered(); if (Changed) { diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp index d2b8b1d..b101250 100644 --- a/llvm/lib/MC/MCFragment.cpp +++ b/llvm/lib/MC/MCFragment.cpp @@ -11,15 +11,11 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/llvm-config.h" -#include "llvm/MC/MCAsmLayout.h" -#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -30,129 +26,6 @@ using namespace llvm; -MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) { - // Compute the section layout order. Virtual sections must go last. - for (MCSection &Sec : Asm) - if (!Sec.isVirtualSection()) - SectionOrder.push_back(&Sec); - for (MCSection &Sec : Asm) - if (Sec.isVirtualSection()) - SectionOrder.push_back(&Sec); -} - -// Simple getSymbolOffset helper for the non-variable case. -static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, - bool ReportError, uint64_t &Val) { - if (!S.getFragment()) { - if (ReportError) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - S.getName() + "'"); - return false; - } - Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset(); - return true; -} - -static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, - bool ReportError, uint64_t &Val) { - if (!S.isVariable()) - return getLabelOffset(Layout, S, ReportError, Val); - - // If SD is a variable, evaluate it. - MCValue Target; - if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) - report_fatal_error("unable to evaluate offset for variable '" + - S.getName() + "'"); - - uint64_t Offset = Target.getConstant(); - - const MCSymbolRefExpr *A = Target.getSymA(); - if (A) { - uint64_t ValA; - // FIXME: On most platforms, `Target`'s component symbols are labels from - // having been simplified during evaluation, but on Mach-O they can be - // variables due to PR19203. This, and the line below for `B` can be - // restored to call `getLabelOffset` when PR19203 is fixed. - if (!getSymbolOffsetImpl(Layout, A->getSymbol(), ReportError, ValA)) - return false; - Offset += ValA; - } - - const MCSymbolRefExpr *B = Target.getSymB(); - if (B) { - uint64_t ValB; - if (!getSymbolOffsetImpl(Layout, B->getSymbol(), ReportError, ValB)) - return false; - Offset -= ValB; - } - - Val = Offset; - return true; -} - -bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { - return getSymbolOffsetImpl(*this, S, false, Val); -} - -uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const { - uint64_t Val; - getSymbolOffsetImpl(*this, S, true, Val); - return Val; -} - -const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { - if (!Symbol.isVariable()) - return &Symbol; - - const MCExpr *Expr = Symbol.getVariableValue(); - MCValue Value; - if (!Expr->evaluateAsValue(Value, *this)) { - Assembler.getContext().reportError( - Expr->getLoc(), "expression could not be evaluated"); - return nullptr; - } - - const MCSymbolRefExpr *RefB = Value.getSymB(); - if (RefB) { - Assembler.getContext().reportError( - Expr->getLoc(), Twine("symbol '") + RefB->getSymbol().getName() + - "' could not be evaluated in a subtraction expression"); - return nullptr; - } - - const MCSymbolRefExpr *A = Value.getSymA(); - if (!A) - return nullptr; - - const MCSymbol &ASym = A->getSymbol(); - const MCAssembler &Asm = getAssembler(); - if (ASym.isCommon()) { - Asm.getContext().reportError(Expr->getLoc(), - "Common symbol '" + ASym.getName() + - "' cannot be used in assignment expr"); - return nullptr; - } - - return &ASym; -} - -uint64_t MCAsmLayout::getSectionAddressSize(const MCSection *Sec) const { - // The size is the last fragment's end offset. - const MCFragment &F = *Sec->curFragList()->Tail; - return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); -} - -uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const { - // Virtual sections have no file size. - if (Sec->isVirtualSection()) - return 0; - - // Otherwise, the file size is the same as the address space size. - return getSectionAddressSize(Sec); -} - -/* *** */ - MCFragment::MCFragment(FragmentType Kind, bool HasInstructions) : Kind(Kind), HasInstructions(HasInstructions), LinkerRelaxable(false) {} |