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
// 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)
}
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 *
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() {
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());
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");
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() {
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;
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; }
return F->kind() == Base::SharedKind;
}
- explicit SharedFile(MemoryBufferRef M);
+ SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
void parseSoName();
void parseRest();
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
uint64_t OffsetInArchive = 0);
-InputFile *createSharedFile(MemoryBufferRef MB);
+InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
} // namespace elf
} // namespace lld
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)});
// 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