diff --git a/include/eld/Readers/Relocation.h b/include/eld/Readers/Relocation.h index a722b3e56..2963f131b 100644 --- a/include/eld/Readers/Relocation.h +++ b/include/eld/Readers/Relocation.h @@ -62,6 +62,7 @@ class Relocation { Type type() const { return m_Type; } /// symValue - S value - the symbol address + Address symValue(Module &M, bool &Uncertain) const; Address symValue(Module &M) const; /// symOffset - Offset of the symbol diff --git a/include/eld/Script/Expression.h b/include/eld/Script/Expression.h index ba014ae4c..49755a322 100644 --- a/include/eld/Script/Expression.h +++ b/include/eld/Script/Expression.h @@ -23,6 +23,128 @@ class Module; class GNULDBackend; class ScriptFile; +class UncertainValue { + uint64_t Value; + bool Uncertain; + +public: + uint64_t value() const { return Value; } + uint64_t &value() { return Value; } + bool isUncertain() const { return Uncertain; } + + UncertainValue(uint64_t Value, bool Uncertain = false) + : Value(Value), Uncertain(Uncertain) {} + + UncertainValue(uint64_t Value, const UncertainValue &Base) + : Value(Value), Uncertain(Base.isUncertain()) {} + + UncertainValue(uint64_t Value, const UncertainValue &BaseL, + const UncertainValue &BaseR) + : Value(Value), Uncertain(BaseL.isUncertain() || BaseR.isUncertain()) {} + + UncertainValue(uint64_t Value, const UncertainValue &Base, + const UncertainValue &BaseL, const UncertainValue &BaseR) + : Value(Value), Uncertain(Base.isUncertain() || BaseL.isUncertain() || + BaseR.isUncertain()) {} +}; + +inline UncertainValue operator+(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() + R.value(), L, R); +} + +inline UncertainValue operator-(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() - R.value(), L, R); +} + +inline UncertainValue operator*(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() * R.value(), L, R); +} + +inline UncertainValue operator/(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() / R.value(), L, R); +} + +inline UncertainValue operator%(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() % R.value(), L, R); +} + +inline UncertainValue operator>>(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() >> R.value(), L, R); +} + +inline UncertainValue operator<<(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() << R.value(), L, R); +} + +inline UncertainValue operator|(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() | R.value(), L, R); +} + +inline UncertainValue operator&(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() & R.value(), L, R); +} + +inline UncertainValue operator>(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() > R.value(), L, R); +} + +inline UncertainValue operator>=(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() >= R.value(), L, R); +} + +inline UncertainValue operator<(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() < R.value(), L, R); +} + +inline UncertainValue operator<=(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() <= R.value(), L, R); +} + +inline UncertainValue operator==(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() == R.value(), L, R); +} + +inline UncertainValue operator!=(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() != R.value(), L, R); +} + +inline UncertainValue operator~(const UncertainValue &E) { + return UncertainValue(~E.value(), E); +} + +inline UncertainValue operator-(const UncertainValue &E) { + return UncertainValue(-E.value(), E); +} + +inline UncertainValue operator!(const UncertainValue &E) { + return UncertainValue(!E.value(), E); +} + +inline UncertainValue operator&&(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() && R.value(), L, R); +} + +inline UncertainValue operator||(const UncertainValue &L, + const UncertainValue &R) { + return UncertainValue(L.value() || R.value(), L, R); +} + //===----------------------------------------------------------------------===// /** \class Expression * \brief This class defines the interfaces to an expression. @@ -192,6 +314,10 @@ class Expression { /// This method is intended to be called by Expression users. eld::Expected evaluateAndReturnError(); + /// evaluateUncertainAndRaiseError + /// \brief Same as evaluateAndReturnError, but return an UncertainValue. + std::optional evaluateUncertainAndRaiseError(); + /// evaluateAndRaiseError /// \brief Evaluate the expression and return the value when /// evaluation is successful. Raise an error if evaluation fails and @@ -206,7 +332,7 @@ class Expression { /// evaluation is successful or an error when failed. Commit is /// not called. This method is intended to be recursively called by /// parent expression nodes. - eld::Expected eval(); + eld::Expected eval(); private: /// eval @@ -214,7 +340,7 @@ class Expression { /// should be to verify and evaluate the expression. eval() should /// return the value if evaluation is successful or raise an error /// and return an empty object otherwise. - virtual eld::Expected evalImpl() = 0; + virtual eld::Expected evalImpl() = 0; static std::unique_ptr addContextToDiagEntry(std::unique_ptr, @@ -312,7 +438,7 @@ class Symbol : public Expression { private: bool hasDot() const override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; /// Returns a set of all the symbol names contained in the expression. void getSymbolNames(std::unordered_set &SymbolTokens) override; @@ -339,7 +465,7 @@ class Integer : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -366,7 +492,7 @@ class Add : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -394,7 +520,7 @@ class Subtract : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -422,7 +548,7 @@ class Modulo : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -450,7 +576,7 @@ class Multiply : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -478,7 +604,7 @@ class Divide : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -502,7 +628,7 @@ class SizeOf : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -525,7 +651,7 @@ class SizeOfHeaders : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -550,7 +676,7 @@ class OffsetOf : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -575,7 +701,7 @@ class Addr : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -598,7 +724,7 @@ class LoadAddr : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -627,7 +753,7 @@ class AlignExpr : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { @@ -661,7 +787,7 @@ class AlignOf : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -687,7 +813,7 @@ class Absolute : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -719,7 +845,7 @@ class Ternary : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -749,7 +875,7 @@ class ConditionGT : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -777,7 +903,7 @@ class ConditionLT : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -805,7 +931,7 @@ class ConditionEQ : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -835,7 +961,7 @@ class ConditionGTE : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -865,7 +991,7 @@ class ConditionLTE : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -893,7 +1019,7 @@ class ConditionNEQ : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -920,7 +1046,7 @@ class Complement : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -948,7 +1074,7 @@ class UnaryPlus : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -976,7 +1102,7 @@ class UnaryMinus : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1004,7 +1130,7 @@ class UnaryNot : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1031,7 +1157,7 @@ class Constant : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1058,7 +1184,7 @@ class SegmentStart : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1090,7 +1216,7 @@ class AssertCmd : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1121,7 +1247,7 @@ class RightShift : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1151,7 +1277,7 @@ class LeftShift : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1179,7 +1305,7 @@ class BitwiseOr : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1207,7 +1333,7 @@ class BitwiseAnd : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1232,7 +1358,7 @@ class Defined : public Expression { private: bool hasDot() const override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1260,7 +1386,7 @@ class DataSegmentAlign : public Expression { bool hasDot() const override { return false; } void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &MaxPageSize; } @@ -1294,7 +1420,7 @@ class DataSegmentRelRoEnd : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1324,7 +1450,7 @@ class DataSegmentEnd : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1354,7 +1480,7 @@ class Max : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1382,7 +1508,7 @@ class Min : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1408,7 +1534,7 @@ class Fill : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1436,7 +1562,7 @@ class Log2Ceil : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1467,7 +1593,7 @@ class LogicalOp : public Expression { bool hasDot() const override; void commit() override; void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return &LeftExpression; } @@ -1495,7 +1621,7 @@ class QueryMemory : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } @@ -1519,7 +1645,7 @@ class NullExpression : public Expression { private: bool hasDot() const override { return false; } void dump(llvm::raw_ostream &Outs, bool WithValues = true) const override; - eld::Expected evalImpl() override; + eld::Expected evalImpl() override; void getSymbols(std::vector &Symbols) override; void getSymbolNames(std::unordered_set &SymbolTokens) override; Expression *getLeftExpression() const override { return nullptr; } diff --git a/include/eld/SymbolResolver/LDSymbol.h b/include/eld/SymbolResolver/LDSymbol.h index 3244463a1..04015be17 100644 --- a/include/eld/SymbolResolver/LDSymbol.h +++ b/include/eld/SymbolResolver/LDSymbol.h @@ -112,10 +112,13 @@ class LDSymbol { bool scriptValueDefined() const { return ThisSymbolHasScriptValue; } - void setScriptValueDefined(bool Value = true) { - ThisSymbolHasScriptValue = Value; + void setScriptValueDefined(bool Uncertain) { + ThisSymbolHasScriptValue = true; + ThisSymbolHasUncertainValue = Uncertain; } + bool isUncertain() const { return ThisSymbolHasUncertainValue; } + const FragmentRef *fragRef() const { return ThisFragRef; } FragmentRef *fragRef() { return ThisFragRef; } @@ -166,6 +169,7 @@ class LDSymbol { uint32_t ThisSymIdx; bool ThisSymbolsIsScriptDefined; bool ThisSymbolHasScriptValue; + bool ThisSymbolHasUncertainValue; // used for ignore garbage collected Common symbols bool ThisSymbolGarbageCollected; }; diff --git a/include/eld/Target/Relocator.h b/include/eld/Target/Relocator.h index 00df613fc..0aff2d4e0 100644 --- a/include/eld/Target/Relocator.h +++ b/include/eld/Target/Relocator.h @@ -143,6 +143,7 @@ class Relocator { bool doDeMangle() const; // Get the address for a relocation + Relocation::Address getSymValue(Relocation *R, bool &Uncertain); Relocation::Address getSymValue(Relocation *R); private: diff --git a/lib/Readers/Relocation.cpp b/lib/Readers/Relocation.cpp index 499966835..1e8a70bf5 100644 --- a/lib/Readers/Relocation.cpp +++ b/lib/Readers/Relocation.cpp @@ -76,7 +76,7 @@ Relocation::Address Relocation::place(Module &M) const { return sect_addr + m_TargetAddress->getOutputOffset(M); } -Relocation::Address Relocation::symValue(Module &M) const { +Relocation::Address Relocation::symValue(Module &M, bool &Uncertain) const { const ELFSection *section = nullptr; const FragmentRef *fragRef = nullptr; ResolveInfo *info = m_pSymInfo; @@ -99,16 +99,26 @@ Relocation::Address Relocation::symValue(Module &M) const { bool isAllocSection = section ? section->isAlloc() : false; // If allocatable section, value => (address + offset) - if (isAllocSection) + if (isAllocSection) { + Uncertain = false; return section->addr() + fragRef->getOutputOffset(M); + } // If non allocatable section, value => (offset) - if (section && !isAllocSection) + if (section) { + Uncertain = false; return fragRef->getOutputOffset(M); + } + Uncertain = info->outSymbol()->isUncertain(); return info->outSymbol()->value(); } +Relocation::Address Relocation::symValue(Module &M) const { + bool Ignored; + return symValue(M, Ignored); +} + Relocation::Address Relocation::symOffset(Module &M) const { const ELFSection *section = nullptr; const FragmentRef *fragRef = nullptr; diff --git a/lib/Script/Assignment.cpp b/lib/Script/Assignment.cpp index e1991c142..5f9e59b78 100644 --- a/lib/Script/Assignment.cpp +++ b/lib/Script/Assignment.cpp @@ -211,10 +211,10 @@ bool Assignment::assign(Module &CurModule, const ELFSection *Section) { } // evaluate, commit, then get the result of the expression - auto Result = ExpressionToEvaluate->evaluateAndRaiseError(); + auto Result = ExpressionToEvaluate->evaluateUncertainAndRaiseError(); if (!Result) return false; - ExpressionValue = *Result; + ExpressionValue = Result->value(); if (!checkLinkerScript(CurModule)) return false; @@ -223,7 +223,7 @@ bool Assignment::assign(Module &CurModule, const ELFSection *Section) { if (Sym != nullptr) { ThisSymbol = Sym; ThisSymbol->setValue(ExpressionValue); - ThisSymbol->setScriptValueDefined(); + ThisSymbol->setScriptValueDefined(Result->isUncertain()); } if (CurModule.getPrinter()->traceAssignments()) diff --git a/lib/Script/Expression.cpp b/lib/Script/Expression.cpp index 0759322ca..bdb1f3a7e 100644 --- a/lib/Script/Expression.cpp +++ b/lib/Script/Expression.cpp @@ -68,10 +68,10 @@ eld::Expected Expression::evaluateAndReturnError() { if (!Result) return addContextToDiagEntry(std::move(Result.error()), MContext); commit(); - return Result; + return Result->value(); } -std::optional Expression::evaluateAndRaiseError() { +std::optional Expression::evaluateUncertainAndRaiseError() { ASSERT(!MContext.empty(), "Context not set for expression"); auto Result = eval(); if (!Result) { @@ -86,10 +86,17 @@ std::optional Expression::evaluateAndRaiseError() { return Result.value(); } -eld::Expected Expression::eval() { +std::optional Expression::evaluateAndRaiseError() { + auto Result = evaluateUncertainAndRaiseError(); + if (!Result) + return {}; + return Result->value(); +} + +eld::Expected Expression::eval() { auto V = evalImpl(); if (V) - EvaluatedValue = V.value(); + EvaluatedValue = V->value(); return V; } @@ -122,7 +129,7 @@ bool Symbol::hasDot() const { return ThisSymbol == ThisModule.getDotSymbol(); } -eld::Expected Symbol::evalImpl() { +eld::Expected Symbol::evalImpl() { if (!ThisSymbol) ThisSymbol = ThisModule.getNamePool().findSymbol(Name); @@ -174,7 +181,7 @@ void Integer::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Integer::evalImpl() { return ExpressionValue; } +eld::Expected Integer::evalImpl() { return ExpressionValue; } void Integer::getSymbols(std::vector &Symbols) {} void Integer::getSymbolNames(std::unordered_set &SymbolTokens) {} @@ -198,7 +205,7 @@ void Add::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Add::evalImpl() { +eld::Expected Add::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -251,7 +258,7 @@ void Subtract::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Subtract::evalImpl() { +eld::Expected Subtract::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -291,7 +298,7 @@ void Modulo::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Modulo::evalImpl() { +eld::Expected Modulo::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -299,7 +306,7 @@ eld::Expected Modulo::evalImpl() { auto Right = RightExpression.eval(); if (!Right) return Right; - if (Right.value() == 0) { + if (Right->value() == 0) { std::string ErrorString; llvm::raw_string_ostream ErrorStringStream(ErrorString); dump(ErrorStringStream); @@ -342,7 +349,7 @@ void Multiply::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Multiply::evalImpl() { +eld::Expected Multiply::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -385,7 +392,7 @@ void Divide::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Divide::evalImpl() { +eld::Expected Divide::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -393,7 +400,7 @@ eld::Expected Divide::evalImpl() { auto Right = RightExpression.eval(); if (!Right) return Right; - if (Right.value() == 0) { + if (Right->value() == 0) { std::string ErrorString; llvm::raw_string_ostream ErrorStringStream(ErrorString); dump(ErrorStringStream); @@ -430,7 +437,7 @@ void SizeOf::dump(llvm::raw_ostream &Outs, bool WithValues) const { } Outs << ")"; } -eld::Expected SizeOf::evalImpl() { +eld::Expected SizeOf::evalImpl() { if (Name.size() && Name[0] == ':') { // If the name is a segment and we don't have PHDR's. SIZEOF on segment will @@ -497,7 +504,7 @@ void SizeOfHeaders::dump(llvm::raw_ostream &Outs, bool WithValues) const { } } -eld::Expected SizeOfHeaders::evalImpl() { +eld::Expected SizeOfHeaders::evalImpl() { uint64_t Offset = 0; std::vector Sections; if (!ThisBackend.isEhdrNeeded()) @@ -527,7 +534,7 @@ void Addr::dump(llvm::raw_ostream &Outs, bool WithValues) const { } Outs << "\")"; } -eld::Expected Addr::evalImpl() { +eld::Expected Addr::evalImpl() { // As the section table is populated only during PostLayout, we have to // go the other way around to access the section. This is because size of // empty @@ -542,7 +549,7 @@ eld::Expected Addr::evalImpl() { ThisModule.getConfig().raise(Diag::warn_forward_reference) << MContext << Name; // evaluate sub expression - return ThisSection->addr(); + return UncertainValue(ThisSection->addr(), !ThisSection->hasVMA()); } void Addr::getSymbols(std::vector &Symbols) {} @@ -565,7 +572,7 @@ void LoadAddr::dump(llvm::raw_ostream &Outs, bool WithValues) const { } Outs << ")"; } -eld::Expected LoadAddr::evalImpl() { +eld::Expected LoadAddr::evalImpl() { // As the section table is populated only during PostLayout, we have to // go the other way around to access the section. This is because size of // empty @@ -594,7 +601,7 @@ void OffsetOf::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs.write_hex(*MResult); } } -eld::Expected OffsetOf::evalImpl() { +eld::Expected OffsetOf::evalImpl() { // As the section table is populated only during PostLayout, we have to // go the other way around to access the section. This is because size of // empty @@ -605,7 +612,7 @@ eld::Expected OffsetOf::evalImpl() { // evaluate sub expression if (ThisSection->hasOffset()) return ThisSection->offset(); - return 0; + return UncertainValue(0, true); } void OffsetOf::getSymbols(std::vector &Symbols) {} @@ -630,11 +637,14 @@ void Ternary::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Ternary::evalImpl() { +eld::Expected Ternary::evalImpl() { auto Cond = ConditionExpression.eval(); if (!Cond) return Cond; - return Cond.value() ? LeftExpression.eval() : RightExpression.eval(); + auto Left = LeftExpression.eval(); + auto Right = RightExpression.eval(); + return UncertainValue(Cond->value() ? Left->value() : Right->value(), *Cond, + *Left, *Right); } void Ternary::getSymbols(std::vector &Symbols) { ConditionExpression.getSymbols(Symbols); @@ -676,7 +686,7 @@ void AlignExpr::dump(llvm::raw_ostream &Outs, bool WithValues) const { AlignmentExpression.dump(Outs, WithValues); Outs << ")"; } -eld::Expected AlignExpr::evalImpl() { +eld::Expected AlignExpr::evalImpl() { // evaluate sub expressions auto Expr = ExpressionToEvaluate.eval(); if (!Expr) @@ -684,8 +694,8 @@ eld::Expected AlignExpr::evalImpl() { auto Align = AlignmentExpression.eval(); if (!Align) return Align; - uint64_t Value = Expr.value(); - uint64_t AlignValue = Align.value(); + uint64_t Value = Expr->value(); + uint64_t AlignValue = Align->value(); if (!AlignValue) return Value; if (ThisModule.getConfig().showLinkerScriptWarnings() && @@ -693,7 +703,7 @@ eld::Expected AlignExpr::evalImpl() { ThisModule.getConfig().raise( Diag::warn_non_power_of_2_value_to_align_builtin) << getContext() << utility::toHex(AlignValue); - return llvm::alignTo(Value, AlignValue); + return UncertainValue(llvm::alignTo(Value, AlignValue), *Expr, *Align); } void AlignExpr::getSymbols(std::vector &Symbols) { @@ -719,7 +729,7 @@ void AlignOf::getSymbols(std::vector &Symbols) {} void AlignOf::getSymbolNames(std::unordered_set &SymbolTokens) {} -eld::Expected AlignOf::evalImpl() { +eld::Expected AlignOf::evalImpl() { // As the section table is populated only during PostLayout, we have to // go the other way around to access the section. This is because size of // empty @@ -743,7 +753,7 @@ void Absolute::dump(llvm::raw_ostream &Outs, bool WithValues) const { ExpressionToEvaluate.dump(Outs, WithValues); Outs << ")"; } -eld::Expected Absolute::evalImpl() { +eld::Expected Absolute::evalImpl() { return ExpressionToEvaluate.eval(); } void Absolute::getSymbols(std::vector &Symbols) { @@ -773,7 +783,7 @@ void ConditionGT::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionGT::evalImpl() { +eld::Expected ConditionGT::evalImpl() { auto Left = LeftExpression.eval(); if (!Left) return Left; @@ -814,7 +824,7 @@ void ConditionLT::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionLT::evalImpl() { +eld::Expected ConditionLT::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -856,7 +866,7 @@ void ConditionEQ::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionEQ::evalImpl() { +eld::Expected ConditionEQ::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -898,7 +908,7 @@ void ConditionGTE::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionGTE::evalImpl() { +eld::Expected ConditionGTE::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -940,7 +950,7 @@ void ConditionLTE::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionLTE::evalImpl() { +eld::Expected ConditionLTE::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -982,7 +992,7 @@ void ConditionNEQ::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected ConditionNEQ::evalImpl() { +eld::Expected ConditionNEQ::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1018,7 +1028,7 @@ void Complement::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << Name; ExpressionToEvaluate.dump(Outs, WithValues); } -eld::Expected Complement::evalImpl() { +eld::Expected Complement::evalImpl() { // evaluate sub expressions auto Expr = ExpressionToEvaluate.eval(); if (!Expr) @@ -1046,7 +1056,7 @@ void UnaryPlus::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << Name; ExpressionToEvaluate.dump(Outs, WithValues); } -eld::Expected UnaryPlus::evalImpl() { +eld::Expected UnaryPlus::evalImpl() { return ExpressionToEvaluate.eval(); } void UnaryPlus::getSymbols(std::vector &Symbols) { @@ -1069,7 +1079,7 @@ void UnaryMinus::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << "-"; ExpressionToEvaluate.dump(Outs, WithValues); } -eld::Expected UnaryMinus::evalImpl() { +eld::Expected UnaryMinus::evalImpl() { // evaluate sub expressions auto Expr = ExpressionToEvaluate.eval(); if (!Expr) @@ -1096,7 +1106,7 @@ void UnaryNot::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << Name; ExpressionToEvaluate.dump(Outs, WithValues); } -eld::Expected UnaryNot::evalImpl() { +eld::Expected UnaryNot::evalImpl() { // evaluate sub expressions auto Expr = ExpressionToEvaluate.eval(); if (!Expr) @@ -1118,7 +1128,7 @@ void Constant::dump(llvm::raw_ostream &Outs, bool WithValues) const { // format output for operator Outs << "CONSTANT(" << Name << ")"; } -eld::Expected Constant::evalImpl() { +eld::Expected Constant::evalImpl() { // evaluate sub expressions switch (type()) { case Expression::MAXPAGESIZE: @@ -1128,7 +1138,7 @@ eld::Expected Constant::evalImpl() { default: // this can't happen because all constants are part of the syntax ASSERT(0, "Unexpected constant"); - return {}; + return 0; } } void Constant::getSymbols(std::vector &Symbols) {} @@ -1147,7 +1157,7 @@ void SegmentStart::dump(llvm::raw_ostream &Outs, bool WithValues) const { ExpressionToEvaluate.dump(Outs, WithValues); Outs << ")"; } -eld::Expected SegmentStart::evalImpl() { +eld::Expected SegmentStart::evalImpl() { GeneralOptions::AddressMapType &AddressMap = ThisModule.getConfig().options().addressMap(); GeneralOptions::AddressMapType::const_iterator Addr; @@ -1196,7 +1206,7 @@ void AssertCmd::dump(llvm::raw_ostream &Outs, bool WithValues) const { ExpressionToEvaluate.dump(Outs, WithValues); Outs << ", \"" << AssertionMessage << "\")"; } -eld::Expected AssertCmd::evalImpl() { +eld::Expected AssertCmd::evalImpl() { auto Expr = ExpressionToEvaluate.eval(); if (!Expr) return Expr; @@ -1231,7 +1241,7 @@ void RightShift::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected RightShift::evalImpl() { +eld::Expected RightShift::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1275,7 +1285,7 @@ void LeftShift::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected LeftShift::evalImpl() { +eld::Expected LeftShift::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1318,7 +1328,7 @@ void BitwiseOr::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected BitwiseOr::evalImpl() { +eld::Expected BitwiseOr::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1361,7 +1371,7 @@ void BitwiseAnd::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected BitwiseAnd::evalImpl() { +eld::Expected BitwiseAnd::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1391,7 +1401,7 @@ void Defined::dump(llvm::raw_ostream &Outs, bool WithValues) const { // format output for operator Outs << "DEFINED(" << Name << ")"; } -eld::Expected Defined::evalImpl() { +eld::Expected Defined::evalImpl() { const LDSymbol *Symbol = ThisModule.getNamePool().findSymbol(Name); if (Symbol == nullptr) return 0; @@ -1428,7 +1438,7 @@ void DataSegmentAlign::dump(llvm::raw_ostream &Outs, bool WithValues) const { CommonPageSize.dump(Outs, WithValues); Outs << ")"; } -eld::Expected DataSegmentAlign::evalImpl() { +eld::Expected DataSegmentAlign::evalImpl() { auto MaxPageSize = this->MaxPageSize.eval(); if (!MaxPageSize) return MaxPageSize; @@ -1436,18 +1446,13 @@ eld::Expected DataSegmentAlign::evalImpl() { if (!CommonPageSize) return CommonPageSize; uint64_t Dot = ThisModule.getDotSymbol()->value(); - uint64_t Form1 = 0, Form2 = 0; - uint64_t DotAligned = Dot; + alignAddress(DotAligned, MaxPageSize->value()); - alignAddress(DotAligned, MaxPageSize.value()); - - Form1 = DotAligned + (Dot & (MaxPageSize.value() - 1)); - Form2 = DotAligned + (Dot & (MaxPageSize.value() - CommonPageSize.value())); - - if (Form1 <= Form2) - return Form1; - return Form2; + uint64_t Form1 = DotAligned + (Dot & (MaxPageSize->value() - 1)); + uint64_t Form2 = + DotAligned + (Dot & (MaxPageSize->value() - CommonPageSize->value())); + return UncertainValue(std::min(Form1, Form2), *MaxPageSize, *CommonPageSize); } void DataSegmentAlign::getSymbols(std::vector &Symbols) {} @@ -1470,7 +1475,7 @@ void DataSegmentRelRoEnd::dump(llvm::raw_ostream &Outs, bool WithValues) const { RightExpression.dump(Outs, WithValues); Outs << ")"; } -eld::Expected DataSegmentRelRoEnd::evalImpl() { +eld::Expected DataSegmentRelRoEnd::evalImpl() { auto CommonPageSize = this->CommonPageSize.eval(); if (!CommonPageSize) return CommonPageSize; @@ -1480,8 +1485,8 @@ eld::Expected DataSegmentRelRoEnd::evalImpl() { auto Expr2 = RightExpression.eval(); if (!Expr2) return Expr2; - uint64_t Value = Expr1.value() + Expr2.value(); - alignAddress(Value, CommonPageSize.value()); + auto Value = Expr1.value() + Expr2.value(); + alignAddress(Value.value(), CommonPageSize->value()); return Value; } void DataSegmentRelRoEnd::getSymbols(std::vector &Symbols) { @@ -1511,7 +1516,7 @@ void DataSegmentEnd::dump(llvm::raw_ostream &Outs, bool WithValues) const { ExpressionToEvaluate.dump(Outs, WithValues); Outs << ")"; } -eld::Expected DataSegmentEnd::evalImpl() { +eld::Expected DataSegmentEnd::evalImpl() { // evaluate sub expressions auto Expr = ExpressionToEvaluate.eval(); if (!Expr) @@ -1548,7 +1553,7 @@ void Max::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Max::evalImpl() { +eld::Expected Max::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1557,7 +1562,9 @@ eld::Expected Max::evalImpl() { if (!Right) return Right; - return Left.value() > Right.value() ? Left.value() : Right.value(); + return UncertainValue(Left->value() > Right->value() ? Left->value() + : Right->value(), + *Left, *Right); } void Max::getSymbols(std::vector &Symbols) { LeftExpression.getSymbols(Symbols); @@ -1590,7 +1597,7 @@ void Min::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected Min::evalImpl() { +eld::Expected Min::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1598,7 +1605,9 @@ eld::Expected Min::evalImpl() { auto Right = RightExpression.eval(); if (!Right) return Right; - return Left.value() < Right.value() ? Left.value() : Right.value(); + return UncertainValue(Left->value() < Right->value() ? Left->value() + : Right->value(), + *Left, *Right); } void Min::getSymbols(std::vector &Symbols) { LeftExpression.getSymbols(Symbols); @@ -1625,7 +1634,9 @@ void Fill::dump(llvm::raw_ostream &Outs, bool WithValues) const { ExpressionToEvaluate.dump(Outs, WithValues); Outs << ")"; } -eld::Expected Fill::evalImpl() { return ExpressionToEvaluate.eval(); } +eld::Expected Fill::evalImpl() { + return ExpressionToEvaluate.eval(); +} void Fill::getSymbols(std::vector &Symbols) { ExpressionToEvaluate.getSymbols(Symbols); @@ -1651,11 +1662,12 @@ void Log2Ceil::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << ")"; } -eld::Expected Log2Ceil::evalImpl() { +eld::Expected Log2Ceil::evalImpl() { auto Val = ExpressionToEvaluate.eval(); if (!Val) return Val; - return llvm::Log2_64_Ceil(std::max(Val.value(), UINT64_C(1))); + return UncertainValue(llvm::Log2_64_Ceil(std::max(Val->value(), UINT64_C(1))), + *Val); } void Log2Ceil::getSymbols(std::vector &Symbols) { @@ -1695,7 +1707,7 @@ void LogicalOp::dump(llvm::raw_ostream &Outs, bool WithValues) const { if (ExpressionHasParenthesis) Outs << ")"; } -eld::Expected LogicalOp::evalImpl() { +eld::Expected LogicalOp::evalImpl() { // evaluate sub expressions auto Left = LeftExpression.eval(); if (!Left) @@ -1737,13 +1749,12 @@ void QueryMemory::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << ")"; } -eld::Expected QueryMemory::evalImpl() { +eld::Expected QueryMemory::evalImpl() { auto Region = ThisModule.getScript().getMemoryRegion(Name); if (!Region) return std::move(Region.error()); - if (isOrigin()) - return Region.value()->getOrigin(); - return Region.value()->getLength(); + return UncertainValue(isOrigin() ? *Region.value()->getOrigin() + : *Region.value()->getLength()); } void QueryMemory::getSymbols(std::vector &Symbols) {} @@ -1761,7 +1772,7 @@ void NullExpression::dump(llvm::raw_ostream &Outs, bool WithValues) const { Outs << Name; } -eld::Expected NullExpression::evalImpl() { +eld::Expected NullExpression::evalImpl() { return std::make_unique( Diag::internal_error_null_expression, std::vector{}); } @@ -1769,4 +1780,4 @@ eld::Expected NullExpression::evalImpl() { void NullExpression::getSymbols(std::vector &Symbols) {} void NullExpression::getSymbolNames( - std::unordered_set &SymbolTokens) {} \ No newline at end of file + std::unordered_set &SymbolTokens) {} diff --git a/lib/SymbolResolver/LDSymbol.cpp b/lib/SymbolResolver/LDSymbol.cpp index b59fdb647..145d44ccf 100644 --- a/lib/SymbolResolver/LDSymbol.cpp +++ b/lib/SymbolResolver/LDSymbol.cpp @@ -32,7 +32,7 @@ static LDSymbol GNullSymbol; LDSymbol::LDSymbol(ResolveInfo *R, bool IsGc) : ThisResolveInfo(R), ThisFragRef(nullptr), ThisShndx(0), ThisSymIdx(0), ThisSymbolsIsScriptDefined(false), ThisSymbolHasScriptValue(false), - ThisSymbolGarbageCollected(IsGc) {} + ThisSymbolHasUncertainValue(false), ThisSymbolGarbageCollected(IsGc) {} LDSymbol::~LDSymbol() {} diff --git a/lib/Target/RISCV/RISCVLDBackend.cpp b/lib/Target/RISCV/RISCVLDBackend.cpp index 6a10e3efa..ee7ddce23 100644 --- a/lib/Target/RISCV/RISCVLDBackend.cpp +++ b/lib/Target/RISCV/RISCVLDBackend.cpp @@ -61,15 +61,25 @@ Relocator *RISCVLDBackend::getRelocator() const { return m_pRelocator; } -Relocation::Address RISCVLDBackend::getSymbolValuePLT(Relocation &R) { +Relocation::Address RISCVLDBackend::getSymbolValuePLT(Relocation &R, + bool &Uncertain) { ResolveInfo *rsym = R.symInfo(); if (rsym && (rsym->reserved() & Relocator::ReservePLT)) { - if (const Fragment *S = findEntryInPLT(rsym)) + if (const Fragment *S = findEntryInPLT(rsym)) { + Uncertain = false; return S->getAddr(config().getDiagEngine()); - if (const ResolveInfo *S = findAbsolutePLT(rsym)) + } + if (const ResolveInfo *S = findAbsolutePLT(rsym)) { + Uncertain = false; return S->value(); + } } - return getRelocator()->getSymValue(&R); + return getRelocator()->getSymValue(&R, Uncertain); +} + +Relocation::Address RISCVLDBackend::getSymbolValuePLT(Relocation &R) { + bool Ignored; + return getSymbolValuePLT(R, Ignored); } Relocation::Type RISCVLDBackend::getCopyRelType() const { @@ -241,11 +251,13 @@ bool RISCVLDBackend::doRelaxationCall(Relocation *reloc, bool DoCompressed) { bool canCompress = (rd == 0 || (rd == 1 && config().targets().is32Bits())); // test if it can fall into 21bits - Relocator::DWord S = getSymbolValuePLT(*reloc); + bool Uncertain; + Relocator::DWord S = getSymbolValuePLT(*reloc, Uncertain); Relocator::DWord A = reloc->addend(); Relocator::DWord P = reloc->place(m_Module); Relocator::DWord X = S + A - P; - bool canRelax = config().options().getRISCVRelax() && llvm::isInt<21>(X); + bool canRelax = + config().options().getRISCVRelax() && llvm::isInt<21>(X) && !Uncertain; if (!canRelax) { reportMissedRelaxation("RISCV_CALL", *region, offset, canCompress ? 6 : 4, @@ -313,15 +325,16 @@ bool RISCVLDBackend::doRelaxationQCCall(Relocation *reloc, bool DoCompressed) { uint64_t qc_e_jump = reloc->target() & 0xffffffffffff; bool isTailCall = (qc_e_jump & 0xf1f07f) == 0x00401f; - Relocator::DWord S = getSymbolValuePLT(*reloc); + bool Uncertain; + Relocator::DWord S = getSymbolValuePLT(*reloc, Uncertain); Relocator::DWord A = reloc->addend(); Relocator::DWord P = reloc->place(m_Module); Relocator::DWord X = S + A - P; - bool canRelaxXqci = - config().targets().is32Bits() && config().options().getRISCVRelaxXqci(); - bool canRelax = - config().options().getRISCVRelax() && canRelaxXqci && llvm::isInt<21>(X); + bool canRelax = config().options().getRISCVRelax() && + config().options().getRISCVRelaxXqci() && + config().targets().is32Bits() && llvm::isInt<21>(X) && + !Uncertain; bool canCompress = DoCompressed && llvm::isInt<12>(X); if (!canRelax) { @@ -382,20 +395,17 @@ bool RISCVLDBackend::doRelaxationLui(Relocation *reloc, Relocator::DWord G) { return false; size_t SymbolSize = reloc->symInfo()->outSymbol()->size(); - Relocator::DWord S = getSymbolValuePLT(*reloc); + bool Uncertain; + Relocator::DWord S = getSymbolValuePLT(*reloc, Uncertain); Relocator::DWord A = reloc->addend(); Relocator::DWord Value = S + A; uint64_t offset = reloc->targetRef()->offset(); Relocation::Type type = reloc->type(); - // Do not relax complete zeroes because they can be mistaken for - // not-yet-assigned values. This applies to both zero-page relaxation and GP - // relaxation when GP is close to zero. - // First, try zero-page relaxation. It's the cheapest and does not need GP. bool canRelaxZero = config().options().getRISCVRelax() && config().options().getRISCVZeroRelax() && - llvm::isInt<12>(Value) && S != 0; + llvm::isInt<12>(Value) && !Uncertain; // HI will be deleted, LO will be converted to use GP as base. // GP must be available and relocation must fit in 12 bits relative to GP. @@ -404,7 +414,7 @@ bool RISCVLDBackend::doRelaxationLui(Relocation *reloc, Relocator::DWord G) { config().options().getRISCVRelax() && config().options().getRISCVGPRelax() && !config().isCodeIndep() && G != 0 && fitsInGP(G, Value, frag, reloc->targetSection(), SymbolSize) && - S != 0; + !Uncertain; if (type == llvm::ELF::R_RISCV_HI20) { @@ -644,12 +654,7 @@ bool RISCVLDBackend::doRelaxationPC(Relocation *reloc, Relocator::DWord G) { if (!region) return false; - // Test if the symbol with size can fall in 12 bits. - size_t SymbolSize = reloc->symInfo()->outSymbol()->size(); - Relocator::DWord S = getSymbolValuePLT(*reloc); - Relocator::DWord A = reloc->addend(); - - Relocation::Type new_type = 0x0; + std::optional new_type; Relocation::Type type = reloc->type(); switch (type) { case llvm::ELF::R_RISCV_PCREL_LO12_I: @@ -662,6 +667,7 @@ bool RISCVLDBackend::doRelaxationPC(Relocation *reloc, Relocator::DWord G) { break; } + Relocation *SymbolReloc = reloc; if (new_type) { // Lookup reloc to get actual addend of HI. Relocation *HIReloc = m_PairedRelocs[reloc]; @@ -671,15 +677,21 @@ bool RISCVLDBackend::doRelaxationPC(Relocation *reloc, Relocator::DWord G) { return false; if (!HIReloc) ASSERT(0, "HIReloc not found! Internal Error!"); - S = getSymbolValuePLT(*HIReloc); - A = HIReloc->addend(); - SymbolSize = HIReloc->symInfo()->outSymbol()->size(); + SymbolReloc = HIReloc; } + // Test if the symbol with size can fall in 12 bits. + size_t SymbolSize = SymbolReloc->symInfo()->outSymbol()->size(); + bool Uncertain; + Relocator::DWord S = getSymbolValuePLT(*SymbolReloc, Uncertain); + Relocator::DWord A = SymbolReloc->addend(); + uint64_t offset = reloc->targetRef()->offset(); - bool canRelax = config().options().getRISCVRelax() && - config().options().getRISCVGPRelax() && G != 0 && - fitsInGP(G, S + A, frag, reloc->targetSection(), SymbolSize); + bool canRelax = + config().options().getRISCVRelax() && + config().options().getRISCVGPRelax() && G != 0 && + fitsInGP(G, S + A, frag, reloc->targetSection(), SymbolSize) && + !Uncertain; // HI will be deleted, Low will be converted to use gp as base. if (type == llvm::ELF::R_RISCV_PCREL_HI20) { @@ -701,7 +713,7 @@ bool RISCVLDBackend::doRelaxationPC(Relocation *reloc, Relocator::DWord G) { uint64_t instr = reloc->target(); uint64_t mask = 0x1F << 15; instr = (instr & ~mask) | (0x3 << 15); - reloc->setType(new_type); + reloc->setType(*new_type); reloc->setTargetData(instr); reloc->setAddend(A); return true; diff --git a/lib/Target/RISCV/RISCVLDBackend.h b/lib/Target/RISCV/RISCVLDBackend.h index da354d34b..54c34c7cf 100644 --- a/lib/Target/RISCV/RISCVLDBackend.h +++ b/lib/Target/RISCV/RISCVLDBackend.h @@ -176,6 +176,7 @@ class RISCVLDBackend : public GNULDBackend { } // Get the value of the symbol, using the PLT slot if one exists. + Relocation::Address getSymbolValuePLT(Relocation &R, bool &Uncertain); Relocation::Address getSymbolValuePLT(Relocation &R); private: diff --git a/lib/Target/Relocator.cpp b/lib/Target/Relocator.cpp index d12af0a48..111599ee7 100644 --- a/lib/Target/Relocator.cpp +++ b/lib/Target/Relocator.cpp @@ -289,8 +289,15 @@ bool Relocator::doDeMangle() const { return m_Config.options().shouldDemangle(); } -Relocation::Address Relocator::getSymValue(Relocation *R) { - if (R->symInfo() && R->symInfo()->isThreadLocal()) +Relocation::Address Relocator::getSymValue(Relocation *R, bool &Uncertain) { + if (R->symInfo() && R->symInfo()->isThreadLocal()) { + Uncertain = false; return getTarget().finalizeTLSSymbol(R->symInfo()->outSymbol()); - return R->symValue(m_Module); + } + return R->symValue(m_Module, Uncertain); +} + +Relocation::Address Relocator::getSymValue(Relocation *R) { + bool Ignored; + return getSymValue(R, Ignored); }