summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp10
-rw-r--r--llvm/lib/MC/MCAssembler.cpp18
-rw-r--r--llvm/lib/MC/MCExpr.cpp68
-rw-r--r--llvm/lib/MC/MCObjectWriter.cpp2
4 files changed, 43 insertions, 55 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 0bc17ef3543..c99a3ee5e26 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -312,6 +312,8 @@ class ELFObjectWriter : public MCObjectWriter {
bool InSet,
bool IsPCRel) const override;
+ bool isWeak(const MCSymbolData &SD) const override;
+
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
void writeSection(MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
@@ -847,7 +849,7 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
Fixup.getLoc(), "Cannot represent a difference across sections");
const MCSymbolData &SymBD = Asm.getSymbolData(SymB);
- if (isWeak(SymBD))
+ if (::isWeak(SymBD))
Asm.getContext().FatalError(
Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
@@ -1817,12 +1819,16 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const {
- if (isWeak(DataA))
+ if (::isWeak(DataA))
return false;
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
Asm, DataA, FB,InSet, IsPCRel);
}
+bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {
+ return ::isWeak(SD);
+}
+
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_ostream &OS,
bool IsLittleEndian) {
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 6ba66762177..6345bd53417 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -142,7 +142,7 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
// If SD is a variable, evaluate it.
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
+ if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
@@ -188,7 +188,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
const MCExpr *Expr = Symbol.getVariableValue();
MCValue Value;
- if (!Expr->EvaluateAsValue(Value, this, nullptr))
+ if (!Expr->EvaluateAsRelocatable(Value, this, nullptr))
llvm_unreachable("Invalid Expression");
const MCSymbolRefExpr *RefB = Value.getSymB();
@@ -473,18 +473,6 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
return SD->getFragment()->getAtom();
}
-// Try to fully compute Expr to an absolute value and if that fails produce
-// a relocatable expr.
-// FIXME: Should this be the behavior of EvaluateAsRelocatable itself?
-static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout,
- const MCFixup &Fixup, MCValue &Target) {
- if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) {
- if (Target.isAbsolute())
- return true;
- }
- return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup);
-}
-
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const {
@@ -494,7 +482,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
// probably merge the two into a single callback that tries to evaluate a
// fixup and records a relocation if one is needed.
const MCExpr *Expr = Fixup.getValue();
- if (!evaluate(*Expr, Layout, Fixup, Target))
+ if (!Expr->EvaluateAsRelocatable(Target, &Layout, &Fixup))
getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index cac5110a4ff..f6350e2744c 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -432,8 +432,8 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return true;
}
- bool IsRelocatable = EvaluateAsRelocatableImpl(
- Value, Asm, Layout, nullptr, Addrs, InSet, /*ForceVarExpansion*/ true);
+ bool IsRelocatable =
+ EvaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet);
// Record the current value.
Res = Value.getConstant();
@@ -586,21 +586,21 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
const MCFixup *Fixup) const {
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
- false, /*ForceVarExpansion*/ false);
+ false);
}
-bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout,
- const MCFixup *Fixup) const {
- MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
- return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
- false, /*ForceVarExpansion*/ true);
+static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm) {
+ if (!Asm)
+ return false;
+ const MCSymbolData &SD = Asm->getSymbolData(Sym);
+ return !Asm->getWriter().isWeak(SD);
}
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
- const SectionAddrMap *Addrs, bool InSet,
- bool ForceVarExpansion) const {
+ const SectionAddrMap *Addrs,
+ bool InSet) const {
++stats::MCExprEvaluate;
switch (getKind()) {
@@ -617,28 +617,23 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCSymbol &Sym = SRE->getSymbol();
// Evaluate recursively if this is a variable.
- if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
+ if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None &&
+ canExpand(Sym, Asm)) {
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
- Res, Asm, Layout, Fixup, Addrs, true, ForceVarExpansion)) {
+ Res, Asm, Layout, Fixup, Addrs, true)) {
+ if (!SRE->hasSubsectionsViaSymbols())
+ return true;
+
const MCSymbolRefExpr *A = Res.getSymA();
const MCSymbolRefExpr *B = Res.getSymB();
-
- if (SRE->hasSubsectionsViaSymbols()) {
- // FIXME: This is small hack. Given
- // a = b + 4
- // .long a
- // the OS X assembler will completely drop the 4. We should probably
- // include it in the relocation or produce an error if that is not
- // possible.
- if (!A && !B)
- return true;
- } else {
- if (ForceVarExpansion)
- return true;
- bool IsSymbol = A && A->getSymbol().isDefined();
- if (!IsSymbol)
- return true;
- }
+ // FIXME: This is small hack. Given
+ // a = b + 4
+ // .long a
+ // the OS X assembler will completely drop the 4. We should probably
+ // include it in the relocation or produce an error if that is not
+ // possible.
+ if (!A && !B)
+ return true;
}
}
@@ -650,9 +645,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
- if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
- Fixup, Addrs, InSet,
- ForceVarExpansion))
+ if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Fixup,
+ Addrs, InSet))
return false;
switch (AUE->getOpcode()) {
@@ -685,12 +679,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
- if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
- Fixup, Addrs, InSet,
- ForceVarExpansion) ||
- !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
- Fixup, Addrs, InSet,
- ForceVarExpansion))
+ if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup,
+ Addrs, InSet) ||
+ !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup,
+ Addrs, InSet))
return false;
// We only support a few operations on non-constant expressions, handle
diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp
index 94d7cd6fd4f..55bdd0b8439 100644
--- a/llvm/lib/MC/MCObjectWriter.cpp
+++ b/llvm/lib/MC/MCObjectWriter.cpp
@@ -54,3 +54,5 @@ MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
// On ELF and COFF A - B is absolute if A and B are in the same section.
return &SecA == &SecB;
}
+
+bool MCObjectWriter::isWeak(const MCSymbolData &SD) const { return false; }
OpenPOWER on IntegriCloud