diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ELFStaticSymtabGenerator.h b/llvm/include/llvm/ExecutionEngine/Orc/ELFStaticSymtabGenerator.h new file mode 100644 index 0000000000000..0010babb72aff --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/ELFStaticSymtabGenerator.h @@ -0,0 +1,26 @@ +#ifndef LLVM_EXECUTIONENGINE_ORC_ELFSTATICSYMTABGENERATOR_H +#define LLVM_EXECUTIONENGINE_ORC_ELFSTATICSYMTABGENERATOR_H + +#include "llvm/ADT/FunctionExtras.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Mangling.h" + +namespace llvm { +namespace orc { + +class ELFStaticSymtabGenerator : public DefinitionGenerator { +public: + ELFStaticSymtabGenerator(ExecutionSession &ES); + + Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, + JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &Symbols) override; +private: + ExecutionSession &ES; + std::map StaticSymbols; +}; + +} // end namespace orc +} // end namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_ELFSTATICSYMTABGENERATOR_H diff --git a/llvm/lib/ExecutionEngine/Orc/ELFStaticSymtabGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/ELFStaticSymtabGenerator.cpp new file mode 100644 index 0000000000000..8df6c3763facd --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/ELFStaticSymtabGenerator.cpp @@ -0,0 +1,78 @@ +#include "llvm/Object/ObjectFile.h" +#include "llvm/ExecutionEngine/Orc/ELFStaticSymtabGenerator.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" +#include "llvm/ExecutionEngine/Orc/DebugUtils.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Error.h" + +#define DEBUG_TYPE "orc" + +namespace llvm { +namespace orc { + +ELFStaticSymtabGenerator::ELFStaticSymtabGenerator(ExecutionSession &ES) : ES(ES) { + auto MBOrErr = MemoryBuffer::getFile("/proc/self/exe"); + if (!MBOrErr) { + return; + } + std::unique_ptr MB = std::move(MBOrErr.get()); + auto ObjOrErr = object::ObjectFile::createObjectFile(MB->getMemBufferRef()); + if (!ObjOrErr) { + consumeError(ObjOrErr.takeError()); + return; + } + auto *Obj = ObjOrErr->get(); + + for (const auto &Sym : Obj->symbols()) { + Expected NameOrErr = Sym.getName(); + if (!NameOrErr) { + consumeError(NameOrErr.takeError()); + continue; + } + StringRef Name = *NameOrErr; + + // Retrieve the symbol flags. + Expected FlagsOrErr = Sym.getFlags(); + if (!FlagsOrErr) { + consumeError(FlagsOrErr.takeError()); + continue; + } + uint32_t Flags = *FlagsOrErr; + + // Only add symbols that are defined. + if (!(Flags & object::BasicSymbolRef::SF_Undefined)) { + Expected AddrOrErr = Sym.getAddress(); + if (!AddrOrErr) { + consumeError(AddrOrErr.takeError()); + continue; + } + JITTargetAddress Addr = *AddrOrErr; + // Intern the symbol name using the ExecutionSession's symbol pool. + SymbolStringPtr SSP = ES.getSymbolStringPool()->intern(Name); + StaticSymbols[SSP] = Addr; + } + } +} + +Error ELFStaticSymtabGenerator::tryToGenerate(LookupState &LS, LookupKind K, + JITDylib &JD, + JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &Symbols) { + + SymbolMap NewSymbols; + for (auto &KV : Symbols) { + SymbolStringPtr Name = KV.first; + if (auto It = StaticSymbols.find(Name); It != StaticSymbols.end()) { + JITEvaluatedSymbol Sym(It->second, JITSymbolFlags::Exported); + NewSymbols[Name] = ExecutorSymbolDef(ExecutorAddr(It->second), JITSymbolFlags::Exported); + } + } + // If any symbols were found, add them to the JITDylib. + if (!NewSymbols.empty()) + return JD.define(absoluteSymbols(std::move(NewSymbols))); + return Error::success(); +} + +} // end namespace orc +} // end namespace llvm +