summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCExpr.cpp3
-rw-r--r--llvm/lib/MC/MCSymbol.cpp8
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp21
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::
OpenPOWER on IntegriCloud