ELF: Implement --start-lib and --end-lib
start-lib and end-lib are options to link object files in the same
semantics as archive files. If an object is in start-lib and end-lib,
the object is linked only when the file is needed to resolve
undefined symbols. That means, if an object is in start-lib and end-lib,
it behaves as if it were in an archive file.
In this patch, I introduced a new notion, LazyObjectFile. That is
analogous to Archive file type, but that works for a single object
file instead of for an archive file.
http://reviews.llvm.org/D18814
llvm-svn: 265710
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3d23fde..6eb2dc6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -564,6 +564,66 @@
return createELFFile<SharedFile>(MB);
}
+void LazyObjectFile::parse() {
+ for (StringRef Sym : getSymbols())
+ LazySymbols.emplace_back(Sym, this->MB);
+}
+
+template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() {
+ typedef typename ELFT::Shdr Elf_Shdr;
+ typedef typename ELFT::Sym Elf_Sym;
+ typedef typename ELFT::SymRange Elf_Sym_Range;
+
+ const ELFFile<ELFT> Obj = createELFObj<ELFT>(this->MB);
+ for (const Elf_Shdr &Sec : Obj.sections()) {
+ if (Sec.sh_type != SHT_SYMTAB)
+ continue;
+ Elf_Sym_Range Syms = Obj.symbols(&Sec);
+ uint32_t FirstNonLocal = Sec.sh_info;
+ StringRef StringTable = check(Obj.getStringTableForSymtab(Sec));
+ std::vector<StringRef> V;
+ for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal))
+ V.push_back(check(Sym.getName(StringTable)));
+ return V;
+ }
+ return {};
+}
+
+std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() {
+ LLVMContext Context;
+ std::unique_ptr<IRObjectFile> Obj =
+ check(IRObjectFile::create(this->MB, Context));
+ std::vector<StringRef> V;
+ for (const BasicSymbolRef &Sym : Obj->symbols()) {
+ if (BitcodeFile::shouldSkip(Sym))
+ continue;
+ SmallString<64> Name;
+ raw_svector_ostream OS(Name);
+ Sym.printName(OS);
+ V.push_back(Saver.save(StringRef(Name)));
+ }
+ return V;
+}
+
+// Returns a vector of globally-visible symbol names.
+std::vector<StringRef> LazyObjectFile::getSymbols() {
+ using namespace sys::fs;
+
+ StringRef Buf = this->MB.getBuffer();
+ if (identify_magic(Buf) == file_magic::bitcode)
+ return getBitcodeSymbols();
+
+ std::pair<unsigned char, unsigned char> Type = getElfArchType(Buf);
+ if (Type.first == ELF::ELFCLASS32) {
+ if (Type.second == ELF::ELFDATA2LSB)
+ return getElfSymbols<ELF32LE>();
+ return getElfSymbols<ELF32BE>();
+ }
+ if (Type.second == ELF::ELFDATA2LSB)
+ return getElfSymbols<ELF64LE>();
+ return getElfSymbols<ELF64BE>();
+}
+
template class elf::ELFFileBase<ELF32LE>;
template class elf::ELFFileBase<ELF32BE>;
template class elf::ELFFileBase<ELF64LE>;