From: Lang Hames Date: Fri, 16 Jan 2015 23:13:56 +0000 (+0000) Subject: [RuntimeDyld] Track symbol visibility in RuntimeDyld. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6bfd398022a03301f2c86d38143706a0423e7258;p=platform%2Fupstream%2Fllvm.git [RuntimeDyld] Track symbol visibility in RuntimeDyld. RuntimeDyld symbol info previously consisted of just a Section/Offset pair. This patch replaces that pair type with a SymbolInfo class that also tracks symbol visibility. A new method, RuntimeDyld::getExportedSymbolLoadAddress, is introduced which only returns a non-zero result for exported symbols. For non-exported or non-existant symbols this method will return zero. The RuntimeDyld::getSymbolAddress method retains its current behavior, returning non-zero results for all symbols regardless of visibility. No in-tree clients of RuntimeDyld are changed. The newly introduced functionality will be used by the Orc APIs. No test case: Since this patch doesn't modify the behavior for any in-tree clients we don't have a good tool to test this with yet. Once Orc is in we can use it to write regression tests that test these changes. llvm-svn: 226341 --- diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h index 799fc34..720429e 100644 --- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -81,10 +81,14 @@ public: /// and resolve relocatons based on where they put it). void *getSymbolAddress(StringRef Name) const; - /// Get the address of the target copy of the symbol. This is the address - /// used for relocation. + /// 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; + /// 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; + /// Resolve the relocations for all symbols we currently know about. void resolveRelocations(); diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 304014e..b0f44b1 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -200,9 +200,14 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { bool IsCode = SI->isText(); unsigned SectionID = findOrEmitSection(Obj, *SI, IsCode, LocalSections); - DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset) - << " flags: " << Flags << " SID: " << SectionID); - GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); + DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name + << " SID: " << SectionID << " Offset: " + << format("%p", (uintptr_t)SectOffset) + << " flags: " << Flags << "\n"); + SymbolInfo::Visibility Vis = + (Flags & SymbolRef::SF_Exported) ? + SymbolInfo::Default : SymbolInfo::Hidden; + GlobalSymbolTable[Name] = {SectionID, SectOffset, Vis}; } } DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"); @@ -444,7 +449,7 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst, void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, - SymbolTableMap &SymbolTable) { + RTDyldSymbolTable &SymbolTable) { // Allocate memory for the section unsigned SectionID = Sections.size(); uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *), @@ -473,7 +478,11 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, DEBUG(dbgs() << "Allocating common symbol " << Name << " address " << format("%p\n", Addr)); } - SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); + uint32_t Flags = it->first.getFlags(); + SymbolInfo::Visibility Vis = + (Flags & SymbolRef::SF_Exported) ? + SymbolInfo::Default : SymbolInfo::Hidden; + SymbolTable[Name.data()] = {SectionID, Offset, Vis}; Offset += Size; Addr += Size; } @@ -589,14 +598,15 @@ void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE, // Relocation by symbol. If the symbol is found in the global symbol table, // create an appropriate section relocation. Otherwise, add it to // ExternalSymbolRelocations. - SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName); + RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(SymbolName); if (Loc == GlobalSymbolTable.end()) { ExternalSymbolRelocations[SymbolName].push_back(RE); } else { // Copy the RE since we want to modify its addend. RelocationEntry RECopy = RE; - RECopy.Addend += Loc->second.second; - Relocations[Loc->second.first].push_back(RECopy); + const auto &SymInfo = Loc->second; + RECopy.Addend += SymInfo.getOffset(); + Relocations[SymInfo.getSectionID()].push_back(RECopy); } } @@ -721,7 +731,7 @@ void RuntimeDyldImpl::resolveExternalSymbols() { resolveRelocationList(Relocs, 0); } else { uint64_t Addr = 0; - SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); + RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name); if (Loc == GlobalSymbolTable.end()) { // This is an external symbol, try to get its address from // MemoryManager. @@ -736,8 +746,9 @@ void RuntimeDyldImpl::resolveExternalSymbols() { } else { // We found the symbol in our global table. It was probably in a // Module that we loaded previously. - SymbolLoc SymLoc = Loc->second; - Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second; + const auto &SymInfo = Loc->second; + Addr = getSectionLoadAddress(SymInfo.getSectionID()) + + SymInfo.getOffset(); } // FIXME: Implement error handling that doesn't kill the host program! @@ -834,6 +845,12 @@ uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const { return Dyld->getSymbolLoadAddress(Name); } +uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const { + if (!Dyld) + return 0; + return Dyld->getExportedSymbolLoadAddress(Name); +} + void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); } void RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) { diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index f3e5c77..309a9b4 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -850,14 +850,16 @@ std::pair RuntimeDyldCheckerImpl::getStubAddrFor( StringRef RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const { - RuntimeDyldImpl::SymbolTableMap::const_iterator pos = + RTDyldSymbolTable::const_iterator pos = getRTDyld().GlobalSymbolTable.find(Name); if (pos == getRTDyld().GlobalSymbolTable.end()) return StringRef(); - RuntimeDyldImpl::SymbolLoc Loc = pos->second; - uint8_t *SectionAddr = getRTDyld().getSectionAddress(Loc.first); - return StringRef(reinterpret_cast(SectionAddr) + Loc.second, - getRTDyld().Sections[Loc.first].Size - Loc.second); + const auto &SymInfo = pos->second; + uint8_t *SectionAddr = getRTDyld().getSectionAddress(SymInfo.getSectionID()); + return StringRef(reinterpret_cast(SectionAddr) + + SymInfo.getOffset(), + getRTDyld().Sections[SymInfo.getSectionID()].Size - + SymInfo.getOffset()); } void RuntimeDyldCheckerImpl::registerSection( @@ -887,9 +889,10 @@ void RuntimeDyldCheckerImpl::registerStubMap( // If this is a (Section, Offset) pair, do a reverse lookup in the // global symbol table to find the name. for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) { - if (GSTEntry.second.first == StubMapEntry.first.SectionID && - GSTEntry.second.second == - static_cast(StubMapEntry.first.Offset)) { + const auto &SymInfo = GSTEntry.second; + if (SymInfo.getSectionID() == StubMapEntry.first.SectionID && + SymInfo.getOffset() == + static_cast(StubMapEntry.first.Offset)) { SymbolName = GSTEntry.first(); break; } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 2664a10..0f3ca0f 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -920,15 +920,16 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( SymbolRef::Type SymType = SymbolRef::ST_Unknown; // Search for the symbol in the global symbol table - SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end(); + RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end(); if (Symbol != Obj.symbol_end()) { gsi = GlobalSymbolTable.find(TargetName.data()); Symbol->getType(SymType); } if (gsi != GlobalSymbolTable.end()) { - Value.SectionID = gsi->second.first; - Value.Offset = gsi->second.second; - Value.Addend = gsi->second.second + Addend; + const auto &SymInfo = gsi->second; + Value.SectionID = SymInfo.getSectionID(); + Value.Offset = SymInfo.getOffset(); + Value.Addend = SymInfo.getOffset() + Addend; } else { switch (SymType) { case SymbolRef::ST_Debug: { diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 2f3e3a8..c985eb3 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -156,6 +156,28 @@ public: } }; +/// @brief Symbol info for RuntimeDyld. +class SymbolInfo { +public: + typedef enum { Hidden = 0, Default = 1 } Visibility; + + SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {} + + SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis) + : Offset(Offset), SectionID(SectionID), Vis(Vis) {} + + 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; +}; + +typedef StringMap RTDyldSymbolTable; + class RuntimeDyldImpl { friend class RuntimeDyld::LoadedObjectInfo; friend class RuntimeDyldCheckerImpl; @@ -178,11 +200,8 @@ protected: // references it. typedef std::map ObjSectionToIDMap; - // A global symbol table for symbols from all loaded modules. Maps the - // symbol name to a (SectionID, offset in section) pair. - typedef std::pair SymbolLoc; - typedef StringMap SymbolTableMap; - SymbolTableMap GlobalSymbolTable; + // A global symbol table for symbols from all loaded modules. + RTDyldSymbolTable GlobalSymbolTable; // Pair representing the size and alignment requirement for a common symbol. typedef std::pair CommonSymbolInfo; @@ -289,7 +308,7 @@ protected: /// symbol table. void emitCommonSymbols(const ObjectFile &Obj, const CommonSymbolMap &CommonSymbols, - uint64_t TotalSize, SymbolTableMap &SymbolTable); + uint64_t TotalSize, RTDyldSymbolTable &SymbolTable); /// \brief Emits section data from the object file to the MemoryManager. /// \param IsCode if it's true then allocateCodeSection() will be @@ -374,21 +393,31 @@ public: uint8_t* getSymbolAddress(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. - SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); + RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); if (pos == GlobalSymbolTable.end()) return nullptr; - SymbolLoc Loc = pos->second; - return getSectionAddress(Loc.first) + Loc.second; + const auto &SymInfo = pos->second; + return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); } uint64_t getSymbolLoadAddress(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. - SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); + RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); if (pos == GlobalSymbolTable.end()) return 0; - SymbolLoc Loc = pos->second; - return getSectionLoadAddress(Loc.first) + Loc.second; + 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(); } void resolveRelocations(); diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 21893d2..2d39662 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -64,11 +64,12 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( symbol_iterator Symbol = RI->getSymbol(); StringRef TargetName; Symbol->getName(TargetName); - SymbolTableMap::const_iterator SI = + RTDyldSymbolTable::const_iterator SI = GlobalSymbolTable.find(TargetName.data()); if (SI != GlobalSymbolTable.end()) { - Value.SectionID = SI->second.first; - Value.Offset = SI->second.second + RE.Addend; + const auto &SymInfo = SI->second; + Value.SectionID = SymInfo.getSectionID(); + Value.Offset = SymInfo.getOffset() + RE.Addend; } else { Value.SymbolName = TargetName.data(); Value.Offset = RE.Addend;