summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/DynamicFile.h
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/DynamicFile.h')
-rw-r--r--lld/lib/ReaderWriter/ELF/DynamicFile.h92
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
OpenPOWER on IntegriCloud