From eabf8a7434a9ac708cf92db044f133da68882bd2 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh <aquynh@gmail.com> Date: Sun, 5 Jun 2016 18:19:13 +0800 Subject: [PATCH] fix issue #148 --- llvm/include/llvm/MC/MCExpr.h | 2 +- llvm/include/llvm/MC/MCObjectWriter.h | 2 +- llvm/lib/MC/MCExpr.cpp | 52 ++++++++++++++++++--------- llvm/lib/MC/MCObjectWriter.cpp | 8 ++++- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h index 755e67d..20952a8 100644 --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -61,7 +61,7 @@ protected: bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, - const SectionAddrMap *Addrs, bool InSet) const; + const SectionAddrMap *Addrs, bool InSet, bool &valid) const; public: /// \name Accessors diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h index 0ecebe4..815a4de 100644 --- a/llvm/include/llvm/MC/MCObjectWriter.h +++ b/llvm/include/llvm/MC/MCObjectWriter.h @@ -95,7 +95,7 @@ public: bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, - bool InSet) const; + bool InSet, bool &valid) const; virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index dc53e2a..4a26231 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -449,8 +449,9 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, return true; } + bool valid; bool IsRelocatable = - evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet); + evaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet, valid); // Record the current value. Res = Value.getConstant(); @@ -462,7 +463,8 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, static void AttemptToFoldSymbolOffsetDifference( const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, - const MCSymbolRefExpr *&B, int64_t &Addend) { + const MCSymbolRefExpr *&B, int64_t &Addend, bool &valid) { + valid = true; if (!A || !B) return; @@ -472,8 +474,10 @@ static void AttemptToFoldSymbolOffsetDifference( if (SA.isUndefined() || SB.isUndefined()) return; - if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet)) + if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet, valid)) return; + if (!valid) + return; if (SA.getFragment() == SB.getFragment() && !SA.isVariable() && !SB.isVariable()) { @@ -539,7 +543,8 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B, - int64_t RHS_Cst, MCValue &Res) { + int64_t RHS_Cst, MCValue &Res, bool &valid) +{ // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy // about dealing with modifiers. This will ultimately bite us, one day. const MCSymbolRefExpr *LHS_A = LHS.getSymA(); @@ -565,13 +570,21 @@ EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, // Since we are attempting to be as aggressive as possible about folding, we // attempt to evaluate each possible alternative. AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B, - Result_Cst); + Result_Cst, valid); + if (!valid) + return false; AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B, - Result_Cst); + Result_Cst, valid); + if (!valid) + return false; AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B, - Result_Cst); + Result_Cst, valid); + if (!valid) + return false; AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B, - Result_Cst); + Result_Cst, valid); + if (!valid) + return false; } // We can't represent the addition or subtraction of two symbols. @@ -592,15 +605,17 @@ bool MCExpr::evaluateAsRelocatable(MCValue &Res, const MCFixup *Fixup) const { MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; + bool valid; return evaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, - false); + false, valid); } bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { MCAssembler *Assembler = &Layout.getAssembler(); + bool valid; return evaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr, - true); + true, valid); } static bool canExpand(const MCSymbol &Sym, bool InSet) { @@ -620,7 +635,7 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, - bool InSet) const + bool InSet, bool &valid) const { switch (getKind()) { case Target: @@ -639,8 +654,9 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None && canExpand(Sym, InSet)) { bool IsMachO = SRE->hasSubsectionsViaSymbols(); + bool valid; if (Sym.getVariableValue()->evaluateAsRelocatableImpl( - Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) { + Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO, valid)) { if (!IsMachO) return true; @@ -665,8 +681,9 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); MCValue Value; + bool valid; if (!AUE->getSubExpr()->evaluateAsRelocatableImpl(Value, Asm, Layout, Fixup, - Addrs, InSet)) + Addrs, InSet, valid)) return false; switch (AUE->getOpcode()) { @@ -698,11 +715,12 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, case Binary: { const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); MCValue LHSValue, RHSValue; + bool valid; if (!ABE->getLHS()->evaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup, - Addrs, InSet) || + Addrs, InSet, valid) || !ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, - Addrs, InSet)) + Addrs, InSet, valid)) return false; // We only support a few operations on non-constant expressions, handle @@ -715,12 +733,12 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, // Negate RHS and add. return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, RHSValue.getSymB(), RHSValue.getSymA(), - -RHSValue.getConstant(), Res); + -RHSValue.getConstant(), Res, valid); case MCBinaryExpr::Add: return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, RHSValue.getSymA(), RHSValue.getSymB(), - RHSValue.getConstant(), Res); + RHSValue.getConstant(), Res, valid); } } diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp index e84f74a..8a1ae85 100644 --- a/llvm/lib/MC/MCObjectWriter.cpp +++ b/llvm/lib/MC/MCObjectWriter.cpp @@ -19,7 +19,9 @@ MCObjectWriter::~MCObjectWriter() { bool MCObjectWriter::isSymbolRefDifferenceFullyResolved( const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, - bool InSet) const { + bool InSet, bool &valid) const +{ + valid = true; // Modified symbol references cannot be resolved. if (A->getKind() != MCSymbolRefExpr::VK_None || B->getKind() != MCSymbolRefExpr::VK_None) @@ -33,6 +35,10 @@ bool MCObjectWriter::isSymbolRefDifferenceFullyResolved( if (!SA.getFragment() || !SB.getFragment()) return false; + if (!SA.isInSection()) { + valid = false; + return false; + } return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, SB, InSet); } -- GitLab