diff options
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/DynamicFile.h')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/DynamicFile.h | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DynamicFile.h b/lld/lib/ReaderWriter/ELF/DynamicFile.h index 55b257e906e..73211c7d308 100644 --- a/lld/lib/ReaderWriter/ELF/DynamicFile.h +++ b/lld/lib/ReaderWriter/ELF/DynamicFile.h @@ -55,8 +55,51 @@ public: *this, name, _soname, sym->second._symbol); } + std::error_code doParse() override { + std::error_code ec; + _objFile.reset( + new llvm::object::ELFFile<ELFT>(_mb.release()->getBuffer(), ec)); + if (ec) + return ec; + + llvm::object::ELFFile<ELFT> &obj = *_objFile; + + _soname = obj.getLoadName(); + if (_soname.empty()) + _soname = llvm::sys::path::filename(path()); + + // Create a map from names to dynamic symbol table entries. + // TODO: This should use the object file's build in hash table instead if + // it exists. + for (auto i = obj.begin_dynamic_symbols(), e = obj.end_dynamic_symbols(); + i != e; ++i) { + auto name = obj.getSymbolName(i); + if ((ec = name.getError())) + return ec; + + // TODO: Add absolute symbols + if (i->st_shndx == llvm::ELF::SHN_ABS) + continue; + + if (i->st_shndx == llvm::ELF::SHN_UNDEF) { + if (!_useShlibUndefines) + continue; + // Create an undefined atom. + if (!name->empty()) { + auto *newAtom = new (_alloc) ELFUndefinedAtom<ELFT>(*this, *name, &*i); + _undefinedAtoms._atoms.push_back(newAtom); + } + continue; + } + _nameToSym[*name]._symbol = &*i; + } + return std::error_code(); + } + private: - DynamicFile(StringRef name) : SharedLibraryFile(name) {} + DynamicFile(std::unique_ptr<MemoryBuffer> mb, bool useShlibUndefines) + : SharedLibraryFile(mb->getBufferIdentifier()), + _mb(std::move(mb)), _useShlibUndefines(useShlibUndefines) {} mutable llvm::BumpPtrAllocator _alloc; std::unique_ptr<llvm::object::ELFFile<ELFT>> _objFile; @@ -73,6 +116,8 @@ private: const SharedLibraryAtom *_atom; }; + std::unique_ptr<MemoryBuffer> _mb; + bool _useShlibUndefines; mutable std::unordered_map<StringRef, SymAtomPair> _nameToSym; }; @@ -80,49 +125,8 @@ template <class ELFT> ErrorOr<std::unique_ptr<DynamicFile<ELFT>>> DynamicFile<ELFT>::create(std::unique_ptr<llvm::MemoryBuffer> mb, bool useShlibUndefines) { - std::unique_ptr<DynamicFile> file(new DynamicFile(mb->getBufferIdentifier())); - - std::error_code ec; - file->_objFile.reset( - new llvm::object::ELFFile<ELFT>(mb.release()->getBuffer(), ec)); - - if (ec) - return ec; - - llvm::object::ELFFile<ELFT> &obj = *file->_objFile; - - file->_soname = obj.getLoadName(); - if (file->_soname.empty()) - file->_soname = llvm::sys::path::filename(file->path()); - - // Create a map from names to dynamic symbol table entries. - // TODO: This should use the object file's build in hash table instead if - // it exists. - for (auto i = obj.begin_dynamic_symbols(), e = obj.end_dynamic_symbols(); - i != e; ++i) { - auto name = obj.getSymbolName(i); - if ((ec = name.getError())) - return ec; - - // TODO: Add absolute symbols - if (i->st_shndx == llvm::ELF::SHN_ABS) - continue; - - if (i->st_shndx == llvm::ELF::SHN_UNDEF) { - if (!useShlibUndefines) - continue; - // Create an undefined atom. - if (!name->empty()) { - auto *newAtom = - new (file->_alloc) ELFUndefinedAtom<ELFT>(*file.get(), *name, &*i); - file->_undefinedAtoms._atoms.push_back(newAtom); - } - continue; - } - file->_nameToSym[*name]._symbol = &*i; - } - - return std::move(file); + return std::unique_ptr<DynamicFile>( + new DynamicFile(std::move(mb), useShlibUndefines)); } } // end namespace elf |

