If available, pass down the Fixup object to EvaluateAsRelocatable.

At least on PowerPC, the interpretation of certain modifiers depends on
the context they appear in.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215310 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Joerg Sonnenberger 2014-08-10 11:35:12 +00:00
parent f96cd1aeb5
commit b2b363408b
16 changed files with 70 additions and 49 deletions

View File

@ -19,6 +19,7 @@ class MCAsmInfo;
class MCAsmLayout; class MCAsmLayout;
class MCAssembler; class MCAssembler;
class MCContext; class MCContext;
class MCFixup;
class MCSection; class MCSection;
class MCSectionData; class MCSectionData;
class MCStreamer; class MCStreamer;
@ -54,6 +55,7 @@ protected:
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout, const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet, const SectionAddrMap *Addrs, bool InSet,
bool ForceVarExpansion) const; bool ForceVarExpansion) const;
@ -92,8 +94,10 @@ public:
/// ///
/// @param Res - The relocatable value, if evaluation succeeds. /// @param Res - The relocatable value, if evaluation succeeds.
/// @param Layout - The assembler layout object to use for evaluating values. /// @param Layout - The assembler layout object to use for evaluating values.
/// @param Fixup - The Fixup object if available.
/// @result - True on success. /// @result - True on success.
bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const; bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const;
/// \brief Try to evaluate the expression to the form (a - b + constant) where /// \brief Try to evaluate the expression to the form (a - b + constant) where
/// neither a nor b are variables. /// neither a nor b are variables.
@ -101,7 +105,8 @@ public:
/// This is a more aggressive variant of EvaluateAsRelocatable. The intended /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
/// use is for when relocations are not available, like the symbol value in /// use is for when relocations are not available, like the symbol value in
/// the symbol table. /// the symbol table.
bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const; bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const;
/// FindAssociatedSection - Find the "associated section" for this expression, /// FindAssociatedSection - Find the "associated section" for this expression,
/// which is currently defined as the absolute section for constants, or /// which is currently defined as the absolute section for constants, or
@ -524,7 +529,8 @@ public:
virtual void PrintImpl(raw_ostream &OS) const = 0; virtual void PrintImpl(raw_ostream &OS) const = 0;
virtual bool EvaluateAsRelocatableImpl(MCValue &Res, virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const = 0; const MCAsmLayout *Layout,
const MCFixup *Fixup) const = 0;
virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0; virtual const MCSection *FindAssociatedSection() const = 0;

View File

@ -141,7 +141,7 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
// If SD is a variable, evaluate it. // If SD is a variable, evaluate it.
MCValue Target; MCValue Target;
if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout)) if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" + report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'"); S.getName() + "'");
@ -187,7 +187,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
const MCExpr *Expr = Symbol.getVariableValue(); const MCExpr *Expr = Symbol.getVariableValue();
MCValue Value; MCValue Value;
if (!Expr->EvaluateAsValue(Value, this)) if (!Expr->EvaluateAsValue(Value, this, nullptr))
llvm_unreachable("Invalid Expression"); llvm_unreachable("Invalid Expression");
const MCSymbolRefExpr *RefB = Value.getSymB(); const MCSymbolRefExpr *RefB = Value.getSymB();
@ -438,11 +438,12 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
// a relocatable expr. // a relocatable expr.
// FIXME: Should this be the behavior of EvaluateAsRelocatable itself? // FIXME: Should this be the behavior of EvaluateAsRelocatable itself?
static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout, static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout,
MCValue &Target) { const MCFixup &Fixup, MCValue &Target) {
if (Expr.EvaluateAsValue(Target, &Layout)) if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) {
if (Target.isAbsolute()) if (Target.isAbsolute())
return true; return true;
return Expr.EvaluateAsRelocatable(Target, &Layout); }
return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup);
} }
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
@ -454,7 +455,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
// probably merge the two into a single callback that tries to evaluate a // probably merge the two into a single callback that tries to evaluate a
// fixup and records a relocation if one is needed. // fixup and records a relocation if one is needed.
const MCExpr *Expr = Fixup.getValue(); const MCExpr *Expr = Fixup.getValue();
if (!evaluate(*Expr, Layout, Target)) if (!evaluate(*Expr, Layout, Fixup, Target))
getContext().FatalError(Fixup.getLoc(), "expected relocatable expression"); getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo( bool IsPCRel = Backend.getFixupKindInfo(

View File

@ -482,8 +482,8 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
// absolutize differences across sections and that is what the MachO writer // absolutize differences across sections and that is what the MachO writer
// uses Addrs for. // uses Addrs for.
bool IsRelocatable = bool IsRelocatable =
EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs, EvaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs,
/*ForceVarExpansion*/ false); /*InSet*/ Addrs, /*ForceVarExpansion*/ false);
// Record the current value. // Record the current value.
Res = Value.getConstant(); Res = Value.getConstant();
@ -632,27 +632,31 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
} }
bool MCExpr::EvaluateAsRelocatable(MCValue &Res, bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
const MCAsmLayout *Layout) const { const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false, return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
/*ForceVarExpansion*/ false); false, /*ForceVarExpansion*/ false);
} }
bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const { bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false, return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
/*ForceVarExpansion*/ true); false, /*ForceVarExpansion*/ true);
} }
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout, const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet, const SectionAddrMap *Addrs, bool InSet,
bool ForceVarExpansion) const { bool ForceVarExpansion) const {
++stats::MCExprEvaluate; ++stats::MCExprEvaluate;
switch (getKind()) { switch (getKind()) {
case Target: case Target:
return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout); return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout,
Fixup);
case Constant: case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue()); Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
@ -666,7 +670,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
// Evaluate recursively if this is a variable. // Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) { if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl( if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
Res, Asm, Layout, Addrs, true, ForceVarExpansion)) { Res, Asm, Layout, Fixup, Addrs, true, ForceVarExpansion)) {
const MCSymbolRefExpr *A = Res.getSymA(); const MCSymbolRefExpr *A = Res.getSymA();
const MCSymbolRefExpr *B = Res.getSymB(); const MCSymbolRefExpr *B = Res.getSymB();
@ -697,8 +701,9 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value; MCValue Value;
if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
InSet, ForceVarExpansion)) Fixup, Addrs, InSet,
ForceVarExpansion))
return false; return false;
switch (AUE->getOpcode()) { switch (AUE->getOpcode()) {
@ -731,10 +736,12 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue; MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Addrs, if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
InSet, ForceVarExpansion) || Fixup, Addrs, InSet,
!ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Addrs, ForceVarExpansion) ||
InSet, ForceVarExpansion)) !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
Fixup, Addrs, InSet,
ForceVarExpansion))
return false; return false;
// We only support a few operations on non-constant expressions, handle // We only support a few operations on non-constant expressions, handle

View File

@ -84,7 +84,7 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
MCValue Target; MCValue Target;
if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout)) if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" + report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'"); S.getName() + "'");
@ -664,7 +664,7 @@ void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
// and neither symbol is external, mark the variable as absolute. // and neither symbol is external, mark the variable as absolute.
const MCExpr *Expr = SD.getSymbol().getVariableValue(); const MCExpr *Expr = SD.getSymbol().getVariableValue();
MCValue Value; MCValue Value;
if (Expr->EvaluateAsRelocatable(Value, &Layout)) { if (Expr->EvaluateAsRelocatable(Value, &Layout, nullptr)) {
if (Value.getSymA() && Value.getSymB()) if (Value.getSymA() && Value.getSymB())
const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute(); const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
} }

View File

@ -90,8 +90,9 @@ const MCSection *AArch64MCExpr::FindAssociatedSection() const {
} }
bool AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, bool AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const { const MCAsmLayout *Layout,
if (!getSubExpr()->EvaluateAsRelocatable(Res, Layout)) const MCFixup *Fixup) const {
if (!getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup))
return false; return false;
Res = Res =

View File

@ -152,7 +152,8 @@ public:
const MCSection *FindAssociatedSection() const override; const MCSection *FindAssociatedSection() const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override; const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;

View File

@ -288,7 +288,8 @@ void AArch64MachObjectWriter::RecordRelocation(
// FIXME: Will the Target we already have ever have any data in it // FIXME: Will the Target we already have ever have any data in it
// we need to preserve and merge with the new Target? How about // we need to preserve and merge with the new Target? How about
// the FixedValue? // the FixedValue?
if (!Symbol->getVariableValue()->EvaluateAsRelocatable(Target, &Layout)) if (!Symbol->getVariableValue()->EvaluateAsRelocatable(Target, &Layout,
&Fixup))
Asm.getContext().FatalError(Fixup.getLoc(), Asm.getContext().FatalError(Fixup.getLoc(),
"unable to resolve variable '" + "unable to resolve variable '" +
Symbol->getName() + "'"); Symbol->getName() + "'");

View File

@ -35,12 +35,6 @@ void ARMMCExpr::PrintImpl(raw_ostream &OS) const {
OS << ')'; OS << ')';
} }
bool
ARMMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const {
return false;
}
void ARMMCExpr::visitUsedExpr(MCStreamer &Streamer) const { void ARMMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Streamer.visitUsedExpr(*getSubExpr()); Streamer.visitUsedExpr(*getSubExpr());
} }

View File

@ -58,8 +58,11 @@ public:
void PrintImpl(raw_ostream &OS) const override; void PrintImpl(raw_ostream &OS) const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override; const MCAsmLayout *Layout,
void visitUsedExpr(MCStreamer &Streamer) const override; const MCFixup *Fixup) const override {
return false;
}
void visitUsedExpr(MCStreamer &Streamer) const override;
const MCSection *FindAssociatedSection() const override { const MCSection *FindAssociatedSection() const override {
return getSubExpr()->FindAssociatedSection(); return getSubExpr()->FindAssociatedSection();
} }

View File

@ -80,8 +80,9 @@ void MipsMCExpr::PrintImpl(raw_ostream &OS) const {
bool bool
MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const { const MCAsmLayout *Layout,
return getSubExpr()->EvaluateAsRelocatable(Res, Layout); const MCFixup *Fixup) const {
return getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup);
} }
void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {

View File

@ -48,7 +48,8 @@ public:
void PrintImpl(raw_ostream &OS) const override; void PrintImpl(raw_ostream &OS) const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override; const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override; void visitUsedExpr(MCStreamer &Streamer) const override;
const MCSection *FindAssociatedSection() const override { const MCSection *FindAssociatedSection() const override {
return getSubExpr()->FindAssociatedSection(); return getSubExpr()->FindAssociatedSection();

View File

@ -63,7 +63,8 @@ public:
void PrintImpl(raw_ostream &OS) const override; void PrintImpl(raw_ostream &OS) const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override { const MCAsmLayout *Layout,
const MCFixup *Fixup) const override {
return false; return false;
} }
void visitUsedExpr(MCStreamer &Streamer) const override {}; void visitUsedExpr(MCStreamer &Streamer) const override {};

View File

@ -53,10 +53,11 @@ void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
bool bool
PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const { const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
MCValue Value; MCValue Value;
if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout)) if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup))
return false; return false;
if (Value.isAbsolute()) { if (Value.isAbsolute()) {

View File

@ -78,7 +78,8 @@ public:
void PrintImpl(raw_ostream &OS) const override; void PrintImpl(raw_ostream &OS) const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override; const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override; void visitUsedExpr(MCStreamer &Streamer) const override;
const MCSection *FindAssociatedSection() const override { const MCSection *FindAssociatedSection() const override {
return getSubExpr()->FindAssociatedSection(); return getSubExpr()->FindAssociatedSection();

View File

@ -161,8 +161,9 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) {
bool bool
SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const { const MCAsmLayout *Layout,
return getSubExpr()->EvaluateAsRelocatable(Res, Layout); const MCFixup *Fixup) const {
return getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup);
} }
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {

View File

@ -87,7 +87,8 @@ public:
/// @} /// @}
void PrintImpl(raw_ostream &OS) const override; void PrintImpl(raw_ostream &OS) const override;
bool EvaluateAsRelocatableImpl(MCValue &Res, bool EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const override; const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override; void visitUsedExpr(MCStreamer &Streamer) const override;
const MCSection *FindAssociatedSection() const override { const MCSection *FindAssociatedSection() const override {
return getSubExpr()->FindAssociatedSection(); return getSubExpr()->FindAssociatedSection();