[Orc][MCJIT][RuntimeDyld] Add symbol flags to symbols in RuntimeDyld. Thread the
authorLang Hames <lhames@gmail.com>
Mon, 9 Mar 2015 23:44:13 +0000 (23:44 +0000)
committerLang Hames <lhames@gmail.com>
Mon, 9 Mar 2015 23:44:13 +0000 (23:44 +0000)
new types through MCJIT and Orc.

In particular, add a 'weak' flag. When plumbed through RTDyldMemoryManager, this
will allow us to distinguish between weak and strong definitions and find the
right ones during symbol resolution.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231724 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/Orc/JITSymbol.h
include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
include/llvm/ExecutionEngine/RuntimeDyld.h
include/llvm/ExecutionEngine/RuntimeDyldChecker.h
lib/ExecutionEngine/MCJIT/MCJIT.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
tools/llvm-rtdyld/llvm-rtdyld.cpp

index a670222..7c3ad56 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
 #define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
 
+#include "llvm/ExecutionEngine/JITSymbolFlags.h"
 #include "llvm/Support/DataTypes.h"
 #include <cassert>
 #include <functional>
@@ -25,17 +26,19 @@ namespace orc {
 typedef uint64_t TargetAddress;
 
 /// @brief Represents a symbol in the JIT.
-class JITSymbol {
-public:
+class JITSymbol : public JITSymbolBase {
+public:  
+
   typedef std::function<TargetAddress()> GetAddressFtor;
 
   /// @brief Create a 'null' symbol that represents failure to find a symbol
   ///        definition.
-  JITSymbol(std::nullptr_t) : CachedAddr(0) {}
+  JITSymbol(std::nullptr_t)
+      : JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {}
 
   /// @brief Create a symbol for a definition with a known address.
-  JITSymbol(TargetAddress Addr)
-    : CachedAddr(Addr) {}
+  JITSymbol(TargetAddress Addr, JITSymbolFlags Flags)
+    : JITSymbolBase(Flags), CachedAddr(Addr) {}
 
   /// @brief Create a symbol for a definition that doesn't have a known address
   ///        yet.
@@ -46,8 +49,8 @@ public:
   /// definition without actually materializing the definition up front. The
   /// user can materialize the definition at any time by calling the getAddress
   /// method.
-  JITSymbol(GetAddressFtor GetAddress)
-    : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
+  JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
+      : JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {}
 
   /// @brief Returns true if the symbol exists, false otherwise.
   explicit operator bool() const { return CachedAddr || GetAddress; }
@@ -64,8 +67,8 @@ public:
   }
 
 private:
-  TargetAddress CachedAddr;
   GetAddressFtor GetAddress;
+  TargetAddress CachedAddr;
 };
 
 } // End namespace orc.
index 9472221..2b5db08 100644 (file)
@@ -45,23 +45,25 @@ private:
     JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
       switch (EmitState) {
       case NotEmitted:
-        if (provides(Name, ExportedSymbolsOnly)) {
+        if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
           // Create a std::string version of Name to capture here - the argument
           // (a StringRef) may go away before the lambda is executed.
           // FIXME: Use capture-init when we move to C++14. 
-          std::string PName = Name;
-          return JITSymbol(
-              [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
-                if (this->EmitState == Emitting)
-                  return 0;
-                else if (this->EmitState == NotEmitted) {
-                  this->EmitState = Emitting;
-                  Handle = this->emitToBaseLayer(B);
-                  this->EmitState = Emitted;
-                }
-                return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
-                          .getAddress();
-              });
+          auto PName = Name;
+          JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
+          auto GetAddress = 
+            [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
+              if (this->EmitState == Emitting)
+                return 0;
+              else if (this->EmitState == NotEmitted) {
+                this->EmitState = Emitting;
+                Handle = this->emitToBaseLayer(B);
+                this->EmitState = Emitted;
+              }
+              auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
+              return Sym.getAddress();
+          };
+          return JITSymbol(std::move(GetAddress), Flags);
         } else
           return nullptr;
       case Emitting:
@@ -98,7 +100,8 @@ private:
            std::unique_ptr<RTDyldMemoryManager> MM);
 
   protected:
-    virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
+    virtual const GlobalValue* searchGVs(StringRef Name,
+                                         bool ExportedSymbolsOnly) const = 0;
     virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
 
   private:
@@ -115,46 +118,48 @@ private:
 
   protected:
 
-    BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
-      // We don't need the mangled names set any more: Once we've emitted this
-      // to the base layer we'll just look for symbols there.
-      MangledNames.reset();
-      return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
-    }
-
-    bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
+    const GlobalValue* searchGVs(StringRef Name,
+                                 bool ExportedSymbolsOnly) const override {
       // FIXME: We could clean all this up if we had a way to reliably demangle
       //        names: We could just demangle name and search, rather than
       //        mangling everything else.
 
       // If we have already built the mangled name set then just search it.
-      if (MangledNames) {
-        auto VI = MangledNames->find(Name);
-        if (VI == MangledNames->end())
-          return false;
-        return !ExportedSymbolsOnly || VI->second;
+      if (MangledSymbols) {
+        auto VI = MangledSymbols->find(Name);
+        if (VI == MangledSymbols->end())
+          return nullptr;
+        auto GV = VI->second;
+        if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
+          return GV;
+        return nullptr;
       }
 
       // If we haven't built the mangled name set yet, try to build it. As an
       // optimization this will leave MangledNames set to nullptr if we find
       // Name in the process of building the set.
-      buildMangledNames(Name, ExportedSymbolsOnly);
-      if (!MangledNames)
-        return true;
-      return false;
+      return buildMangledSymbols(Name, ExportedSymbolsOnly);
+    }
+
+    BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
+      // We don't need the mangled names set any more: Once we've emitted this
+      // to the base layer we'll just look for symbols there.
+      MangledSymbols.reset();
+      return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
     }
 
   private:
     // If the mangled name of the given GlobalValue matches the given search
     // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
-    // just return 'true'. Otherwise, add the mangled name to the Names map and
-    // return 'false'.
-    bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
-                        const Mangler &Mang, StringRef SearchName,
-                        bool ExportedSymbolsOnly) const {
+    // return the symbol. Otherwise, add the mangled name to the Names map and
+    // return nullptr.
+    const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
+                                      const GlobalValue &GV,
+                                      const Mangler &Mang, StringRef SearchName,
+                                      bool ExportedSymbolsOnly) const {
       // Modules don't "provide" decls or common symbols.
       if (GV.isDeclaration() || GV.hasCommonLinkage())
-        return false;
+        return nullptr;
 
       // Mangle the GV name.
       std::string MangledName;
@@ -167,39 +172,42 @@ private:
       // bail out early.
       if (MangledName == SearchName)
         if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
-          return true;
+          return &GV;
 
       // Otherwise add this to the map for later.
-      Names[MangledName] = GV.hasDefaultVisibility();
-      return false;
+      Names[MangledName] = &GV;
+      return nullptr;
     }
 
-    // Build the MangledNames map. Bails out early (with MangledNames left set
+    // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
     // to nullptr) if the given SearchName is found while building the map.
-    void buildMangledNames(StringRef SearchName,
-                           bool ExportedSymbolsOnly) const {
-      assert(!MangledNames && "Mangled names map already exists?");
+    const GlobalValue* buildMangledSymbols(StringRef SearchName,
+                                           bool ExportedSymbolsOnly) const {
+      assert(!MangledSymbols && "Mangled symbols map already exists?");
 
-      auto Names = llvm::make_unique<StringMap<bool>>();
+      auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
 
       for (const auto &M : Ms) {
         Mangler Mang(&M->getDataLayout());
 
-        for (const auto &GV : M->globals())
-          if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
-            return;
+        for (const auto &V : M->globals())
+          if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
+                                       ExportedSymbolsOnly))
+            return GV;
 
         for (const auto &F : *M)
-          if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
-            return;
+          if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
+                                       ExportedSymbolsOnly))
+            return GV;
       }
 
-      MangledNames = std::move(Names);
+      MangledSymbols = std::move(Symbols);
+      return nullptr;
     }
 
     ModuleSetT Ms;
     std::unique_ptr<RTDyldMemoryManager> MM;
-    mutable std::unique_ptr<StringMap<bool>> MangledNames;
+    mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
   };
 
   typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
index 36af0fe..9838991 100644 (file)
@@ -51,10 +51,8 @@ protected:
       return RTDyld->loadObject(Obj);
     }
 
-    TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
-      if (ExportedSymbolsOnly)
-        return RTDyld->getExportedSymbolLoadAddress(Name);
-      return RTDyld->getSymbolLoadAddress(Name);
+    RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
+      return RTDyld->getSymbol(Name);
     }
 
     bool NeedsFinalization() const { return (State == Raw); }
@@ -214,28 +212,32 @@ public:
   ///         given object set.
   JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
                          bool ExportedSymbolsOnly) {
-    if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
-      if (!H->NeedsFinalization()) {
-        // If this instance has already been finalized then we can just return
-        // the address.
-        return JITSymbol(Addr);
-      } else {
-        // If this instance needs finalization return a functor that will do it.
-        // The functor still needs to double-check whether finalization is
-        // required, in case someone else finalizes this set before the functor
-        // is called.
-        return JITSymbol(
-          [this, Addr, H]() {
-            if (H->NeedsFinalization()) {
-              H->Finalize();
-              if (NotifyFinalized)
-                NotifyFinalized(H);
-            }
-            return Addr;
-          });
+    if (auto Sym = H->getSymbol(Name)) {
+      if (Sym.isExported() || !ExportedSymbolsOnly) {
+        auto Addr = Sym.getAddress();
+        auto Flags = Sym.getFlags();
+        if (!H->NeedsFinalization()) {
+          // If this instance has already been finalized then we can just return
+          // the address.
+          return JITSymbol(Addr, Flags);
+        } else {
+          // If this instance needs finalization return a functor that will do
+          // it. The functor still needs to double-check whether finalization is
+          // required, in case someone else finalizes this set before the
+          // functor is called.
+          auto GetAddress = 
+            [this, Addr, H]() {
+              if (H->NeedsFinalization()) {
+                H->Finalize();
+                if (NotifyFinalized)
+                  NotifyFinalized(H);
+              }
+              return Addr;
+            };
+          return JITSymbol(std::move(GetAddress), Flags);
+        }
       }
     }
-
     return nullptr;
   }
 
index 08cfa39..fe0ccda 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
 
+#include "JITSymbolFlags.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/Support/Memory.h"
@@ -28,7 +29,7 @@ namespace object {
 
 class RuntimeDyldImpl;
 class RuntimeDyldCheckerImpl;
-
 class RuntimeDyld {
   friend class RuntimeDyldCheckerImpl;
 
@@ -47,6 +48,18 @@ protected:
   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
 public:
 
+  /// \brief Information about a named symbol.
+  class SymbolInfo : public JITSymbolBase {
+  public:
+    SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {}
+    SymbolInfo(uint64_t Address, JITSymbolFlags Flags)
+      : JITSymbolBase(Flags), Address(Address) {}
+    explicit operator bool() const { return Address != 0; }
+    uint64_t getAddress() const { return Address; }
+  private:
+    uint64_t Address;
+  };
+
   /// \brief Information about the loaded object.
   class LoadedObjectInfo {
     friend class RuntimeDyldImpl;
@@ -79,15 +92,11 @@ public:
   /// Get the address of our local copy of the symbol. This may or may not
   /// be the address used for relocation (clients can copy the data around
   /// and resolve relocatons based on where they put it).
-  void *getSymbolAddress(StringRef Name) const;
-
-  /// Get the address of the target copy of the symbol (works for both exported
-  /// and non-exported symbols). This is the address used for relocation.
-  uint64_t getSymbolLoadAddress(StringRef Name) const;
+  void *getSymbolLocalAddress(StringRef Name) const;
 
-  /// Get the address of the target copy of the symbol (works for exported
-  /// symbols only). This is the address used for relocation.
-  uint64_t getExportedSymbolLoadAddress(StringRef Name) const;
+  /// Get the target address and flags for the named symbol.
+  /// This address is the one used for relocation.
+  SymbolInfo getSymbol(StringRef Name) const;
 
   /// Resolve the relocations for all symbols we currently know about.
   void resolveRelocations();
index 23936a6..31ce151 100644 (file)
@@ -86,12 +86,12 @@ public:
   /// \brief Returns the address of the requested section (or an error message
   ///        in the second element of the pair if the address cannot be found).
   ///
-  /// if 'LinkerAddress' is true, this returns the address of the section
-  /// within the linker's memory. If 'LinkerAddress' is false it returns the
+  /// if 'LocalAddress' is true, this returns the address of the section
+  /// within the linker's memory. If 'LocalAddress' is false it returns the
   /// address within the target process (i.e. the load address).
   std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
                                                   StringRef SectionName,
-                                                  bool LinkerAddress);
+                                                  bool LocalAddress);
 
 private:
   std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
index 527941b..20b8553 100644 (file)
@@ -257,7 +257,7 @@ uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
   Mangler Mang(TM->getDataLayout());
   SmallString<128> FullName;
   Mang.getNameWithPrefix(FullName, Name);
-  return Dyld.getSymbolLoadAddress(FullName);
+  return Dyld.getSymbol(FullName).getAddress();
 }
 
 Module *MCJIT::findModuleForSymbol(const std::string &Name,
@@ -383,7 +383,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
   //
   // This is the accessor for the target address, so make sure to check the
   // load address of the symbol, not the local address.
-  return (void*)Dyld.getSymbolLoadAddress(Name);
+  return (void*)Dyld.getSymbol(Name).getAddress();
 }
 
 void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
index 0560a1b..a0ed7cf 100644 (file)
@@ -197,10 +197,13 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
                      << " SID: " << SectionID << " Offset: "
                      << format("%p", (uintptr_t)SectOffset)
                      << " flags: " << Flags << "\n");
-        SymbolInfo::Visibility Vis =
-          (Flags & SymbolRef::SF_Exported) ?
-            SymbolInfo::Default : SymbolInfo::Hidden;
-        GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
+        JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
+        if (Flags & SymbolRef::SF_Weak)
+          RTDyldSymFlags |= JITSymbolFlags::Weak;
+        if (Flags & SymbolRef::SF_Exported)
+          RTDyldSymFlags |= JITSymbolFlags::Exported;
+        GlobalSymbolTable[Name] =
+          SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
       }
     }
   }
@@ -525,12 +528,15 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
       Offset += AlignOffset;
     }
     uint32_t Flags = Sym.getFlags();
-    SymbolInfo::Visibility Vis =
-      (Flags & SymbolRef::SF_Exported) ?
-        SymbolInfo::Default : SymbolInfo::Hidden;
+    JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
+    if (Flags & SymbolRef::SF_Weak)
+      RTDyldSymFlags |= JITSymbolFlags::Weak;
+    if (Flags & SymbolRef::SF_Exported)
+      RTDyldSymFlags |= JITSymbolFlags::Exported;
     DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
                  << format("%p", Addr) << "\n");
-    GlobalSymbolTable[Name] = SymbolInfo(SectionID, Offset, Vis);
+    GlobalSymbolTable[Name] =
+      SymbolTableEntry(SectionID, Offset, RTDyldSymFlags);
     Offset += Size;
     Addr += Size;
   }
@@ -894,22 +900,16 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
   return Dyld->loadObject(Obj);
 }
 
-void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
+void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const {
   if (!Dyld)
     return nullptr;
-  return Dyld->getSymbolAddress(Name);
+  return Dyld->getSymbolLocalAddress(Name);
 }
 
-uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const {
+RuntimeDyld::SymbolInfo RuntimeDyld::getSymbol(StringRef Name) const {
   if (!Dyld)
-    return 0;
-  return Dyld->getSymbolLoadAddress(Name);
-}
-
-uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const {
-  if (!Dyld)
-    return 0;
-  return Dyld->getExportedSymbolLoadAddress(Name);
+    return nullptr;
+  return Dyld->getSymbol(Name);
 }
 
 void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
index 976a434..c991408 100644 (file)
@@ -310,7 +310,7 @@ private:
           "");
 
     uint64_t SymbolAddr = PCtx.IsInsideLoad
-                              ? Checker.getSymbolLinkerAddr(Symbol)
+                              ? Checker.getSymbolLocalAddr(Symbol)
                               : Checker.getSymbolRemoteAddr(Symbol);
     uint64_t NextPC = SymbolAddr + InstSize;
 
@@ -437,7 +437,7 @@ private:
     // The value for the symbol depends on the context we're evaluating in:
     // Inside a load this is the address in the linker's memory, outside a
     // load it's the address in the target processes memory.
-    uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLinkerAddr(Symbol)
+    uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
                                        : Checker.getSymbolRemoteAddr(Symbol);
 
     // Looks like a plain symbol reference.
@@ -727,17 +727,17 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
 }
 
 bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
-  return getRTDyld().getSymbolAddress(Symbol) != nullptr;
+  return getRTDyld().getSymbolLocalAddress(Symbol) != nullptr;
 }
 
-uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const {
+uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
   return static_cast<uint64_t>(
-      reinterpret_cast<uintptr_t>(getRTDyld().getSymbolAddress(Symbol)));
+      reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
 }
 
 uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
-  if (uint64_t InternalSymbolAddr = getRTDyld().getSymbolLoadAddress(Symbol))
-      return InternalSymbolAddr;
+  if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
+    return InternalSymbol.getAddress();
   return getRTDyld().MemMgr->getSymbolAddress(Symbol);
 }
 
@@ -929,6 +929,6 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
 
 std::pair<uint64_t, std::string>
 RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
-                                   bool LinkerAddress) {
-  return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
+                                   bool LocalAddress) {
+  return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
 }
index de20c1e..e8d299a 100644 (file)
@@ -42,7 +42,7 @@ private:
   RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
 
   bool isSymbolValid(StringRef Symbol) const;
-  uint64_t getSymbolLinkerAddr(StringRef Symbol) const;
+  uint64_t getSymbolLocalAddr(StringRef Symbol) const;
   uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
   uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
 
index 20c63f1..05060dd 100644 (file)
@@ -164,27 +164,24 @@ public:
   }
 };
 
-/// @brief Symbol info for RuntimeDyld.
-class SymbolInfo {
+/// @brief Symbol info for RuntimeDyld. 
+class SymbolTableEntry : public JITSymbolBase {
 public:
-  typedef enum { Hidden = 0, Default = 1 } Visibility;
+  SymbolTableEntry()
+    : JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
 
-  SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {}
-
-  SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis)
-    : Offset(Offset), SectionID(SectionID), Vis(Vis) {}
+  SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
+    : JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {}
 
   unsigned getSectionID() const { return SectionID; }
   uint64_t getOffset() const { return Offset; }
-  Visibility getVisibility() const { return Vis; }
 
 private:
   uint64_t Offset;
-  unsigned SectionID : 31;
-  Visibility Vis : 1;
+  unsigned SectionID;
 };
 
-typedef StringMap<SymbolInfo> RTDyldSymbolTable;
+typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
 
 class RuntimeDyldImpl {
   friend class RuntimeDyld::LoadedObjectInfo;
@@ -394,7 +391,7 @@ public:
   virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
   loadObject(const object::ObjectFile &Obj) = 0;
 
-  uint8_t* getSymbolAddress(StringRef Name) const {
+  uint8_t* getSymbolLocalAddress(StringRef Name) const {
     // FIXME: Just look up as a function for now. Overly simple of course.
     // Work in progress.
     RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
@@ -404,24 +401,16 @@ public:
     return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
   }
 
-  uint64_t getSymbolLoadAddress(StringRef Name) const {
+  RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
     // FIXME: Just look up as a function for now. Overly simple of course.
     // Work in progress.
     RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
     if (pos == GlobalSymbolTable.end())
-      return 0;
-    const auto &SymInfo = pos->second;
-    return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
-  }
-
-  uint64_t getExportedSymbolLoadAddress(StringRef Name) const {
-    RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
-    if (pos == GlobalSymbolTable.end())
-      return 0;
-    const auto &SymInfo = pos->second;
-    if (SymInfo.getVisibility() == SymbolInfo::Hidden)
-      return 0;
-    return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
+      return nullptr;
+    const auto &SymEntry = pos->second;
+    uint64_t TargetAddr =
+      getSectionLoadAddress(SymEntry.getSectionID()) + SymEntry.getOffset();
+    return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags());
   }
 
   void resolveRelocations();
index 508318c..9462015 100644 (file)
@@ -298,7 +298,7 @@ static int executeInput() {
   // FIXME: Error out if there are unresolved relocations.
 
   // Get the address of the entry point (_main by default).
-  void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
+  void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
   if (!MainAddress)
     return Error("no definition for '" + EntryPoint + "'");