[llvm] r207711 - Provide a version of getSymbolOffset that returns false on error.

Rafael Espindola rafael.espindola at gmail.com
Wed Apr 30 14:51:13 PDT 2014


Author: rafael
Date: Wed Apr 30 16:51:13 2014
New Revision: 207711

URL: http://llvm.org/viewvc/llvm-project?rev=207711&view=rev
Log:
Provide a version of getSymbolOffset that returns false on error.

This simplifies ELFObjectWriter::SymbolValue a bit more. This new version
will also be used in the COFF writer to fix pr19147.

Modified:
    llvm/trunk/include/llvm/MC/MCAsmLayout.h
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCAssembler.cpp

Modified: llvm/trunk/include/llvm/MC/MCAsmLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmLayout.h?rev=207711&r1=207710&r2=207711&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Wed Apr 30 16:51:13 2014
@@ -102,6 +102,10 @@ public:
 
   /// \brief Get the offset of the given symbol, as computed in the current
   /// layout.
+  /// \result True on success.
+  bool getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const;
+
+  /// \brief Variant that reports a fatal error if the offset is not computable.
   uint64_t getSymbolOffset(const MCSymbolData *SD) const;
 
   /// @}

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=207711&r1=207710&r2=207711&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed Apr 30 16:51:13 2014
@@ -486,34 +486,16 @@ void ELFObjectWriter::WriteHeader(const
     Write16(ShstrtabIndex);
 }
 
-uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
+uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
                                       const MCAsmLayout &Layout) {
-  MCSymbolData *Data = &OrigData;
-  if (Data->isCommon() && Data->isExternal())
-    return Data->getCommonAlignment();
+  if (Data.isCommon() && Data.isExternal())
+    return Data.getCommonAlignment();
 
-  const MCSymbol *Symbol = &Data->getSymbol();
-  MCAssembler &Asm = Layout.getAssembler();
-  bool IsThumb = Asm.isThumbFunc(Symbol);
-
-  // Given how we implement symver, we can end up with an symbol reference
-  // to an undefined symbol. Walk past it first.
-  if (Symbol->isVariable()) {
-    const MCExpr *Expr = Symbol->getVariableValue();
-    if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
-      if (Ref->getKind() == MCSymbolRefExpr::VK_None) {
-        Symbol = &Ref->getSymbol();
-        Data = &Asm.getOrCreateSymbolData(*Symbol);
-      }
-    }
-  }
-
-  if (!Symbol->isVariable() && !Data->getFragment())
+  uint64_t Res;
+  if (!Layout.getSymbolOffset(&Data, Res))
     return 0;
 
-  uint64_t Res = Layout.getSymbolOffset(Data);
-
-  if (IsThumb)
+  if (Layout.getAssembler().isThumbFunc(&Data.getSymbol()))
     Res |= 1;
 
   return Res;

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=207711&r1=207710&r2=207711&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Wed Apr 30 16:51:13 2014
@@ -118,37 +118,66 @@ uint64_t MCAsmLayout::getFragmentOffset(
 }
 
 // Simple getSymbolOffset helper for the non-varibale case.
-static uint64_t getLabelOffset(const MCAsmLayout &Layout,
-                               const MCSymbolData &SD) {
-  if (!SD.getFragment())
-    report_fatal_error("unable to evaluate offset to undefined symbol '" +
-                       SD.getSymbol().getName() + "'");
-  return Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
+static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD,
+                           bool ReportError, uint64_t &Val) {
+  if (!SD.getFragment()) {
+    if (ReportError)
+      report_fatal_error("unable to evaluate offset to undefined symbol '" +
+                         SD.getSymbol().getName() + "'");
+    return false;
+  }
+  Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
+  return true;
 }
 
-uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
+static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
+                                const MCSymbolData *SD, bool ReportError,
+                                uint64_t &Val) {
   const MCSymbol &S = SD->getSymbol();
 
   if (!S.isVariable())
-    return getLabelOffset(*this, *SD);
+    return getLabelOffset(Layout, *SD, ReportError, Val);
 
   // If SD is a variable, evaluate it.
   MCValue Target;
-  if (!S.getVariableValue()->EvaluateAsValue(Target, this))
+  if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
     report_fatal_error("unable to evaluate offset for variable '" +
                        S.getName() + "'");
 
   uint64_t Offset = Target.getConstant();
 
+  const MCAssembler &Asm = Layout.getAssembler();
+
   const MCSymbolRefExpr *A = Target.getSymA();
-  if (A)
-    Offset += getLabelOffset(*this, Assembler.getSymbolData(A->getSymbol()));
+  if (A) {
+    uint64_t ValA;
+    if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError,
+                        ValA))
+      return false;
+    Offset += ValA;
+  }
 
   const MCSymbolRefExpr *B = Target.getSymB();
-  if (B)
-    Offset -= getLabelOffset(*this, Assembler.getSymbolData(B->getSymbol()));
+  if (B) {
+    uint64_t ValB;
+    if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError,
+                        ValB))
+      return false;
+    Offset -= ValB;
+  }
+
+  Val = Offset;
+  return true;
+}
 
-  return Offset;
+bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const {
+  return getSymbolOffsetImpl(*this, SD, false, Val);
+}
+
+uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
+  uint64_t Val;
+  getSymbolOffsetImpl(*this, SD, true, Val);
+  return Val;
 }
 
 uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {





More information about the llvm-commits mailing list