diff --git a/llvm/include/llvm/MC/MCAsmLayout.h b/llvm/include/llvm/MC/MCAsmLayout.h index 6a61776e9947db33fb1a6fcd469280f212be4023..ca09d92edad0c160eb3147e17954f30d7094a38f 100644 --- a/llvm/include/llvm/MC/MCAsmLayout.h +++ b/llvm/include/llvm/MC/MCAsmLayout.h @@ -91,10 +91,10 @@ public: /// \brief Get the offset of the given symbol, as computed in the current /// layout. /// \return True on success. - bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const; + bool getSymbolOffset(const MCSymbol &S, uint64_t &Val, bool &valid) const; /// \brief Variant that reports a fatal error if the offset is not computable. - uint64_t getSymbolOffset(const MCSymbol &S) const; + uint64_t getSymbolOffset(const MCSymbol &S, bool &valid) const; /// \brief If this symbol is equivalent to A + Constant, return A. const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const; diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 8262a6a266068fd44d57d4888bf1b1fc29149a06..0de700c9d81a2e939ca200e0eb9a279577c1944e 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -365,7 +365,8 @@ uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, return Sym.getCommonAlignment(); uint64_t Res; - if (!Layout.getSymbolOffset(Sym, Res)) + bool valid; + if (!Layout.getSymbolOffset(Sym, Res, valid)) return 0; if (Layout.getAssembler().isThumbFunc(&Sym)) @@ -657,7 +658,8 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, return; } - uint64_t SymBOffset = Layout.getSymbolOffset(SymB); + bool valid; + uint64_t SymBOffset = Layout.getSymbolOffset(SymB, valid); uint64_t K = SymBOffset - FixupOffset; IsPCRel = true; C -= K; @@ -680,8 +682,10 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel); bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); - if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) - C += Layout.getSymbolOffset(*SymA); + if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) { + bool valid; + C += Layout.getSymbolOffset(*SymA, valid); + } uint64_t Addend = 0; if (hasRelocationAddend()) { diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index bc825c23f773ac70c4b9edd4402e6133eebecee7..799bf58f1dc1cda21bf470aca10cd3f5b62681d4 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -194,17 +194,28 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, if (const MCSymbolRefExpr *A = Target.getSymA()) { const MCSymbol &Sym = A->getSymbol(); - if (Sym.isDefined()) - Value += Layout.getSymbolOffset(Sym); - else { + bool valid; + if (Sym.isDefined()) { + Value += Layout.getSymbolOffset(Sym, valid); + if (!valid) { + KsError = KS_ERR_ASM_FIXUP_INVALID; + return false; + } + } else { KsError = KS_ERR_ASM_SYMBOL_MISSING; return false; } } if (const MCSymbolRefExpr *B = Target.getSymB()) { const MCSymbol &Sym = B->getSymbol(); - if (Sym.isDefined()) - Value -= Layout.getSymbolOffset(Sym); + bool valid; + if (Sym.isDefined()) { + Value -= Layout.getSymbolOffset(Sym, valid); + if (!valid) { + KsError = KS_ERR_ASM_FIXUP_INVALID; + return false; + } + } } bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags & @@ -289,7 +300,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, int64_t TargetLocation = Value.getConstant(); if (const MCSymbolRefExpr *A = Value.getSymA()) { uint64_t Val; - if (!Layout.getSymbolOffset(A->getSymbol(), Val)) { + if (!Layout.getSymbolOffset(A->getSymbol(), Val, valid)) { //report_fatal_error("expected absolute expression"); valid = false; return 0; diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index d3686f54db12646a5eccb3ce5b4fb2c25402922f..dc53e2a71ddea779d7b2081435fa07fabe8d927f 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -500,8 +500,9 @@ static void AttemptToFoldSymbolOffsetDifference( return; // Eagerly evaluate. - Addend += Layout->getSymbolOffset(A->getSymbol()) - - Layout->getSymbolOffset(B->getSymbol()); + bool valid1, valid2; + Addend += Layout->getSymbolOffset(A->getSymbol(), valid1) - + Layout->getSymbolOffset(B->getSymbol(), valid2); if (Addrs && (&SecA != &SecB)) Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB)); diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp index 2a6cd06b4902d6dcee2d169a6a62428162395572..dc37a30c09bbb7d25211d369fae05d738393d8f4 100644 --- a/llvm/lib/MC/MCFragment.cpp +++ b/llvm/lib/MC/MCFragment.cpp @@ -115,15 +115,20 @@ static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, } static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, - bool ReportError, uint64_t &Val) { + bool ReportError, uint64_t &Val, bool &valid) +{ + valid = true; if (!S.isVariable()) return getLabelOffset(Layout, S, ReportError, Val); // If SD is a variable, evaluate it. MCValue Target; - if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) - report_fatal_error("unable to evaluate offset for variable '" + - S.getName() + "'"); + if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) { + //report_fatal_error("unable to evaluate offset for variable '" + + // S.getName() + "'"); + valid = false; + return false; + } uint64_t Offset = Target.getConstant(); @@ -147,13 +152,15 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, return true; } -bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { - return getSymbolOffsetImpl(*this, S, false, Val); +bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val, bool &valid) const +{ + return getSymbolOffsetImpl(*this, S, false, Val, valid); } -uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const { +uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S, bool &valid) const +{ uint64_t Val; - getSymbolOffsetImpl(*this, S, true, Val); + getSymbolOffsetImpl(*this, S, true, Val, valid); return Val; }