diff options
| -rw-r--r-- | lld/ELF/Driver.cpp | 6 | ||||
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 42 | ||||
| -rw-r--r-- | lld/ELF/InputFiles.h | 12 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 4 |
5 files changed, 35 insertions, 31 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 93924e4554c..2d1a935a66e 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -184,8 +184,6 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { error("attempted static link of dynamic object " + Path); return; } - Files.push_back(createSharedFile(MBRef)); - // DSOs usually have DT_SONAME tags in their ELF headers, and the // sonames are used to identify DSOs. But if they are missing, // they are identified by filenames. We don't know whether the new @@ -196,8 +194,8 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) { // If a file was specified by -lfoo, the directory part is not // significant, as a user did not specify it. This behavior is // compatible with GNU. - Files.back()->DefaultSoName = - WithLOption ? sys::path::filename(Path) : Path; + Files.push_back(createSharedFile( + MBRef, WithLOption ? sys::path::filename(Path) : Path)); return; default: if (InLib) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index d651fbcad25..d99f71eb4aa 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -608,8 +608,9 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) { } template <class ELFT> -SharedFile<ELFT>::SharedFile(MemoryBufferRef M) - : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} +SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName) + : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName), + AsNeeded(Config->AsNeeded) {} template <class ELFT> const typename ELFT::Shdr * @@ -619,12 +620,6 @@ SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const { toString(this)); } -template <class ELFT> StringRef SharedFile<ELFT>::getSoName() const { - if (SoName.empty()) - return this->DefaultSoName; - return SoName; -} - // Partially parse the shared object file so that we can call // getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { @@ -867,8 +862,23 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) { Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this)); } +// Small bit of template meta programming to handle the SharedFile constructor +// being the only one with a DefaultSoName parameter. +template <template <class> class T, class E> +typename std::enable_if<std::is_same<T<E>, SharedFile<E>>::value, + InputFile *>::type +createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) { + return make<T<E>>(MB, DefaultSoName); +} +template <template <class> class T, class E> +typename std::enable_if<!std::is_same<T<E>, SharedFile<E>>::value, + InputFile *>::type +createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) { + return make<T<E>>(MB); +} + template <template <class> class T> -static InputFile *createELFFile(MemoryBufferRef MB) { +static InputFile *createELFFile(MemoryBufferRef MB, StringRef DefaultSoName) { unsigned char Size; unsigned char Endian; std::tie(Size, Endian) = getElfArchType(MB.getBuffer()); @@ -882,13 +892,13 @@ static InputFile *createELFFile(MemoryBufferRef MB) { InputFile *Obj; if (Size == ELFCLASS32 && Endian == ELFDATA2LSB) - Obj = make<T<ELF32LE>>(MB); + Obj = createELFAux<T, ELF32LE>(MB, DefaultSoName); else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB) - Obj = make<T<ELF32BE>>(MB); + Obj = createELFAux<T, ELF32BE>(MB, DefaultSoName); else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB) - Obj = make<T<ELF64LE>>(MB); + Obj = createELFAux<T, ELF64LE>(MB, DefaultSoName); else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB) - Obj = make<T<ELF64BE>>(MB); + Obj = createELFAux<T, ELF64BE>(MB, DefaultSoName); else fatal(MB.getBufferIdentifier() + ": invalid file class"); @@ -933,13 +943,13 @@ InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, uint64_t OffsetInArchive) { InputFile *F = isBitcode(MB) ? make<BitcodeFile>(MB, ArchiveName, OffsetInArchive) - : createELFFile<ObjectFile>(MB); + : createELFFile<ObjectFile>(MB, ""); F->ArchiveName = ArchiveName; return F; } -InputFile *elf::createSharedFile(MemoryBufferRef MB) { - return createELFFile<SharedFile>(MB); +InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) { + return createELFFile<SharedFile>(MB, DefaultSoName); } MemoryBufferRef LazyObjectFile::getBuffer() { diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 40a8b23c5ef..4552270316d 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -93,10 +93,6 @@ public: uint16_t EMachine = llvm::ELF::EM_NONE; uint8_t OSABI = 0; - // For SharedKind inputs, the string to use in DT_NEEDED when the library - // has no soname. - std::string DefaultSoName; - // Cache for toString(). Only toString() should use this member. mutable std::string ToStringCache; @@ -283,12 +279,12 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { typedef typename ELFT::Versym Elf_Versym; std::vector<StringRef> Undefs; - StringRef SoName; const Elf_Shdr *VersymSec = nullptr; const Elf_Shdr *VerdefSec = nullptr; public: - StringRef getSoName() const; + std::string SoName; + const Elf_Shdr *getSection(const Elf_Sym &Sym) const; llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } @@ -296,7 +292,7 @@ public: return F->kind() == Base::SharedKind; } - explicit SharedFile(MemoryBufferRef M); + SharedFile(MemoryBufferRef M, StringRef DefaultSoName); void parseSoName(); void parseRest(); @@ -329,7 +325,7 @@ public: InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", uint64_t OffsetInArchive = 0); -InputFile *createSharedFile(MemoryBufferRef MB); +InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); } // namespace elf } // namespace lld diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 42b4fdc26fa..a22f35e7b77 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -81,7 +81,7 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) { if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) { // DSOs are uniquified not by filename but by soname. F->parseSoName(); - if (ErrorCount || !SoNames.insert(F->getSoName()).second) + if (ErrorCount || !SoNames.insert(F->SoName).second) return; SharedFiles.push_back(F); F->parseRest(); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 7009d3d34f6..e1f81940bb5 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1027,7 +1027,7 @@ template <class ELFT> void DynamicSection<ELFT>::addEntries() { In<ELFT>::DynStrTab->addString(Config->RPath)}); for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles()) if (F->isNeeded()) - add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())}); + add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->SoName)}); if (!Config->SoName.empty()) add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)}); @@ -2042,7 +2042,7 @@ void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) { // to create one by adding it to our needed list and creating a dynstr entry // for the soname. if (File->VerdefMap.empty()) - Needed.push_back({File, In<ELFT>::DynStrTab->addString(File->getSoName())}); + Needed.push_back({File, In<ELFT>::DynStrTab->addString(File->SoName)}); typename SharedFile<ELFT>::NeededVer &NV = File->VerdefMap[Ver]; // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef, // prepare to create one by allocating a version identifier and creating a |

