diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCSymbol.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/MC/MachObjectWriter.cpp | 21 |
3 files changed, 28 insertions, 4 deletions
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 995f4c96ee6..8a64403362c 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -775,9 +775,6 @@ const MCSection *MCExpr::FindAssociatedSection() const { if (RHS_S == MCSymbol::AbsolutePseudoSection) return LHS_S; - if (BE->getOpcode() == MCBinaryExpr::Sub) - return MCSymbol::AbsolutePseudoSection; - // Otherwise, return the first non-null section. return LHS_S ? LHS_S : RHS_S; } diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp index 6582574ae94..24165254e56 100644 --- a/llvm/lib/MC/MCSymbol.cpp +++ b/llvm/lib/MC/MCSymbol.cpp @@ -55,7 +55,13 @@ void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); this->Value = Value; - this->Section = nullptr; + + // Variables should always be marked as in the same "section" as the value. + const MCSection *Section = Value->FindAssociatedSection(); + if (Section) + setSection(*Section); + else + setUndefined(); } void MCSymbol::print(raw_ostream &OS) const { diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index 56cccab1d39..5e9e86f18a0 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -649,12 +649,33 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, } } +void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm, + const MCAsmLayout &Layout) { + for (MCSymbolData &SD : Asm.symbols()) { + if (!SD.getSymbol().isVariable()) + continue; + + // Is the variable is a symbol difference (SA - SB + C) expression, + // and neither symbol is external, mark the variable as absolute. + const MCExpr *Expr = SD.getSymbol().getVariableValue(); + MCValue Value; + if (Expr->EvaluateAsRelocatable(Value, &Layout, nullptr)) { + if (Value.getSymA() && Value.getSymB()) + const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute(); + } + } +} + void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { computeSectionAddresses(Asm, Layout); // Create symbol data for any indirect symbols. BindIndirectSymbols(Asm); + + // Mark symbol difference expressions in variables (from .set or = directives) + // as absolute. + markAbsoluteVariableSymbols(Asm, Layout); } bool MachObjectWriter:: |