}
// Force Sym to be entered in the output. Used for -u or equivalent.
-template <class ELFT> static void handleUndefined(StringRef Name) {
+static void handleUndefined(StringRef Name) {
Symbol *Sym = Symtab->find(Name);
if (!Sym)
return;
Sym->IsUsedInRegularObj = true;
if (Sym->isLazy())
- Symtab->fetchLazy<ELFT>(Sym);
+ Symtab->fetchLazy(Sym);
}
-template <class ELFT> static void handleLibcall(StringRef Name) {
+static void handleLibcall(StringRef Name) {
Symbol *Sym = Symtab->find(Name);
if (!Sym || !Sym->isLazy())
return;
MB = cast<LazyArchive>(Sym)->getMemberBuffer();
if (isBitcode(MB))
- Symtab->fetchLazy<ELFT>(Sym);
+ Symtab->fetchLazy(Sym);
}
// Replaces common symbols with defined symbols reside in .bss sections.
}
template <class ELFT> static Symbol *addUndefined(StringRef Name) {
- return Symtab->addUndefined<ELFT>(
+ return Symtab->addUndefined(
Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
}
// Add all files to the symbol table. This will add almost all
// symbols that we need to the symbol table.
for (InputFile *F : Files)
- parseFile<ELFT>(F);
+ parseFile(F);
// Now that we have every file, we can decide if we will need a
// dynamic symbol table.
// Handle the `--undefined <sym>` options.
for (StringRef S : Config->Undefined)
- handleUndefined<ELFT>(S);
+ handleUndefined(S);
// If an entry symbol is in a static archive, pull out that file now.
- handleUndefined<ELFT>(Config->Entry);
+ handleUndefined(Config->Entry);
// If any of our inputs are bitcode files, the LTO code generator may create
// references to certain library functions that might not be explicit in the
// object file to the link.
if (!BitcodeFiles.empty())
for (const char *S : LibcallRoutineNames)
- handleLibcall<ELFT>(S);
+ handleLibcall(S);
// Return if there were name resolution errors.
if (errorCount())
return false;
}
-// Add symbols in File to the symbol table.
-template <class ELFT> void elf::parseFile(InputFile *File) {
+template <class ELFT> static void doParseFile(InputFile *File) {
// Comdat groups define "link once" sections. If two comdat groups have the
// same name, only one of them is linked, and the other is ignored. This set
// is used to uniquify them.
// .a file
if (auto *F = dyn_cast<ArchiveFile>(File)) {
- F->parse<ELFT>();
+ F->parse();
return;
}
cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
}
+// Add symbols in File to the symbol table.
+void elf::parseFile(InputFile *File) {
+ switch (Config->EKind) {
+ case ELF32LEKind:
+ doParseFile<ELF32LE>(File);
+ return;
+ case ELF32BEKind:
+ doParseFile<ELF32BE>(File);
+ return;
+ case ELF64LEKind:
+ doParseFile<ELF64LE>(File);
+ return;
+ case ELF64BEKind:
+ doParseFile<ELF64BE>(File);
+ return;
+ default:
+ llvm_unreachable("unknown ELFT");
+ }
+}
+
// Concatenates arguments to construct a string representing an error location.
static std::string createFileLineMsg(StringRef Path, unsigned Line) {
std::string Filename = path::filename(Path);
switch (Sym->st_shndx) {
case SHN_UNDEF:
- return Symtab->addUndefined<ELFT>(
- Undefined{this, Name, Binding, StOther, Type});
+ return Symtab->addUndefined(Undefined{this, Name, Binding, StOther, Type});
case SHN_COMMON:
if (Value == 0 || Value >= UINT32_MAX)
fatal(toString(this) + ": common symbol '" + Name +
case STB_WEAK:
case STB_GNU_UNIQUE:
if (Sec == &InputSection::Discarded)
- return Symtab->addUndefined<ELFT>(
+ return Symtab->addUndefined(
Undefined{this, Name, Binding, StOther, Type});
return Symtab->addDefined(
Defined{this, Name, Binding, StOther, Type, Value, Size, Sec});
: InputFile(ArchiveKind, File->getMemoryBufferRef()),
File(std::move(File)) {}
-template <class ELFT> void ArchiveFile::parse() {
+void ArchiveFile::parse() {
for (const Archive::Symbol &Sym : File->symbols())
- Symtab->addLazyArchive<ELFT>(LazyArchive{*this, Sym});
+ Symtab->addLazyArchive(LazyArchive{*this, Sym});
}
// Returns a buffer pointing to a member file containing a given symbol.
}
if (Sym.isUndefined()) {
- Symbol *S = Symtab->addUndefined<ELFT>(
+ Symbol *S = Symtab->addUndefined(
Undefined{this, Name, Sym.getBinding(), Sym.st_other, Sym.getType()});
S->ExportDynamic = true;
continue;
Undefined New(&F, Name, Binding, Visibility, Type);
if (CanOmitFromDynSym)
New.ExportDynamic = false;
- return Symtab->addUndefined<ELFT>(New);
+ return Symtab->addUndefined(New);
}
if (ObjSym.isCommon())
for (const lto::InputFile::Symbol &Sym : Obj->symbols()) {
if (Sym.isUndefined())
continue;
- Symtab->addLazyObject<ELFT>(LazyObject{*this, Saver.save(Sym.getName())});
+ Symtab->addLazyObject(LazyObject{*this, Saver.save(Sym.getName())});
}
return;
}
for (const typename ELFT::Sym &Sym : Syms.slice(FirstGlobal)) {
if (Sym.st_shndx == SHN_UNDEF)
continue;
- Symtab->addLazyObject<ELFT>(
+ Symtab->addLazyObject(
LazyObject{*this, CHECK(Sym.getName(StringTable), this)});
}
return;
return Path;
}
-template void elf::parseFile<ELF32LE>(InputFile *);
-template void elf::parseFile<ELF32BE>(InputFile *);
-template void elf::parseFile<ELF64LE>(InputFile *);
-template void elf::parseFile<ELF64BE>(InputFile *);
-
-template void ArchiveFile::parse<ELF32LE>();
-template void ArchiveFile::parse<ELF32BE>();
-template void ArchiveFile::parse<ELF64LE>();
-template void ArchiveFile::parse<ELF64BE>();
-
template void BitcodeFile::parse<ELF32LE>(DenseSet<CachedHashStringRef> &);
template void BitcodeFile::parse<ELF32BE>(DenseSet<CachedHashStringRef> &);
template void BitcodeFile::parse<ELF64LE>(DenseSet<CachedHashStringRef> &);
llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
// Add symbols in File to the symbol table.
-template <class ELFT> void parseFile(InputFile *File);
+void parseFile(InputFile *File);
// The root class of input files.
class InputFile {
public:
explicit ArchiveFile(std::unique_ptr<Archive> &&File);
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
- template <class ELFT> void parse();
+ void parse();
// Pulls out an object file that contains a definition for Sym and
// returns it. If the same file was instantiated before, this
Old->Visibility = getMinVisibility(Old->Visibility, New.Visibility);
}
-template <class ELFT> Symbol *SymbolTable::addUndefined(const Undefined &New) {
+Symbol *SymbolTable::addUndefined(const Undefined &New) {
Symbol *Old = insert(New);
mergeProperties(Old, New);
// group assignment rule simulates the traditional linker's semantics.
bool Backref = Config->WarnBackrefs && New.File &&
Old->File->GroupId < New.File->GroupId;
- fetchLazy<ELFT>(Old);
+ fetchLazy(Old);
// We don't report backward references to weak symbols as they can be
// overridden later.
return SymVector[It->second];
}
-template <class ELFT, class LazyT> void SymbolTable::addLazy(const LazyT &New) {
+template <class LazyT> void SymbolTable::addLazy(const LazyT &New) {
Symbol *Old = insert(New);
mergeProperties(Old, New);
}
if (InputFile *F = New.fetch())
- parseFile<ELFT>(F);
+ parseFile(F);
}
-template <class ELFT> void SymbolTable::addLazyArchive(const LazyArchive &New) {
- addLazy<ELFT>(New);
-}
+void SymbolTable::addLazyArchive(const LazyArchive &New) { addLazy(New); }
-template <class ELFT> void SymbolTable::addLazyObject(const LazyObject &New) {
- addLazy<ELFT>(New);
-}
+void SymbolTable::addLazyObject(const LazyObject &New) { addLazy(New); }
-template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
+void SymbolTable::fetchLazy(Symbol *Sym) {
if (auto *S = dyn_cast<LazyArchive>(Sym)) {
if (InputFile *File = S->fetch())
- parseFile<ELFT>(File);
+ parseFile(File);
return;
}
auto *S = cast<LazyObject>(Sym);
if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
- parseFile<ELFT>(File);
+ parseFile(File);
}
// Initialize DemangledSyms with a map from demangled symbols to symbol
Sym->parseSymbolVersion();
}
-template Symbol *SymbolTable::addUndefined<ELF32LE>(const Undefined &);
-template Symbol *SymbolTable::addUndefined<ELF32BE>(const Undefined &);
-template Symbol *SymbolTable::addUndefined<ELF64LE>(const Undefined &);
-template Symbol *SymbolTable::addUndefined<ELF64BE>(const Undefined &);
-
template void SymbolTable::addCombinedLTOObject<ELF32LE>();
template void SymbolTable::addCombinedLTOObject<ELF32BE>();
template void SymbolTable::addCombinedLTOObject<ELF64LE>();
template void SymbolTable::addCombinedLTOObject<ELF64BE>();
-
-template void SymbolTable::addLazyArchive<ELF32LE>(const LazyArchive &);
-template void SymbolTable::addLazyArchive<ELF32BE>(const LazyArchive &);
-template void SymbolTable::addLazyArchive<ELF64LE>(const LazyArchive &);
-template void SymbolTable::addLazyArchive<ELF64BE>(const LazyArchive &);
-
-template void SymbolTable::addLazyObject<ELF32LE>(const LazyObject &);
-template void SymbolTable::addLazyObject<ELF32BE>(const LazyObject &);
-template void SymbolTable::addLazyObject<ELF64LE>(const LazyObject &);
-template void SymbolTable::addLazyObject<ELF64BE>(const LazyObject &);
-
-template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
-template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
-template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
-template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
ArrayRef<Symbol *> getSymbols() const { return SymVector; }
- template <class ELFT> Symbol *addUndefined(const Undefined &New);
-
+ Symbol *addUndefined(const Undefined &New);
Symbol *addDefined(const Defined &New);
-
void addShared(const SharedSymbol &New);
-
- template <class ELFT> void addLazyArchive(const LazyArchive &New);
- template <class ELFT> void addLazyObject(const LazyObject &New);
-
+ void addLazyArchive(const LazyArchive &New);
+ void addLazyObject(const LazyObject &New);
Symbol *addBitcode(const Defined &New);
Symbol *addCommon(const CommonSymbol &New);
Symbol *insert(const Symbol &New);
void mergeProperties(Symbol *Old, const Symbol &New);
- template <class ELFT> void fetchLazy(Symbol *Sym);
+ void fetchLazy(Symbol *Sym);
void scanVersionScript();
llvm::DenseMap<StringRef, SharedFile *> SoNames;
private:
- template <class ELFT, class LazyT> void addLazy(const LazyT &New);
+ template <class LazyT> void addLazy(const LazyT &New);
std::vector<Symbol *> findByVersion(SymbolVersion Ver);
std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);