De-template parseFile() and SymbolTable's add-family functions.

Differential Revision: https://reviews.llvm.org/D61896

llvm-svn: 360844
This commit is contained in:
Rui Ueyama 2019-05-16 03:45:13 +00:00
parent bf6df042a5
commit 943cd00580
5 changed files with 55 additions and 75 deletions

View File

@ -1295,7 +1295,7 @@ static void excludeLibs(opt::InputArgList &Args) {
}
// 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;
@ -1305,10 +1305,10 @@ template <class ELFT> static void handleUndefined(StringRef Name) {
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;
@ -1320,7 +1320,7 @@ template <class ELFT> static void handleLibcall(StringRef Name) {
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.
@ -1426,7 +1426,7 @@ static void findKeepUniqueSections(opt::InputArgList &Args) {
}
template <class ELFT> static Symbol *addUndefined(StringRef Name) {
return Symtab->addUndefined<ELFT>(
return Symtab->addUndefined(
Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
}
@ -1551,7 +1551,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// 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.
@ -1569,10 +1569,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// 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
@ -1593,7 +1593,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// 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())

View File

@ -109,8 +109,7 @@ static bool isCompatible(InputFile *File) {
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.
@ -128,7 +127,7 @@ template <class ELFT> void elf::parseFile(InputFile *File) {
// .a file
if (auto *F = dyn_cast<ArchiveFile>(File)) {
F->parse<ELFT>();
F->parse();
return;
}
@ -160,6 +159,26 @@ template <class ELFT> void elf::parseFile(InputFile *File) {
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);
@ -892,8 +911,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
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 +
@ -909,7 +927,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
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});
@ -920,9 +938,9 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
: 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.
@ -1123,7 +1141,7 @@ template <class ELFT> void SharedFile::parse() {
}
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;
@ -1262,7 +1280,7 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
Undefined New(&F, Name, Binding, Visibility, Type);
if (CanOmitFromDynSym)
New.ExportDynamic = false;
return Symtab->addUndefined<ELFT>(New);
return Symtab->addUndefined(New);
}
if (ObjSym.isCommon())
@ -1404,7 +1422,7 @@ template <class ELFT> void LazyObjFile::parse() {
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;
}
@ -1429,7 +1447,7 @@ template <class ELFT> void LazyObjFile::parse() {
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;
@ -1445,16 +1463,6 @@ std::string elf::replaceThinLTOSuffix(StringRef Path) {
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> &);

View File

@ -55,7 +55,7 @@ extern std::unique_ptr<llvm::TarWriter> Tar;
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 {
@ -323,7 +323,7 @@ class ArchiveFile : public 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

View File

@ -145,7 +145,7 @@ void SymbolTable::mergeProperties(Symbol *Old, const Symbol &New) {
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);
@ -225,7 +225,7 @@ template <class ELFT> Symbol *SymbolTable::addUndefined(const Undefined &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.
@ -429,7 +429,7 @@ Symbol *SymbolTable::find(StringRef Name) {
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);
@ -452,27 +452,23 @@ template <class ELFT, class LazyT> void SymbolTable::addLazy(const LazyT &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
@ -636,27 +632,7 @@ void SymbolTable::scanVersionScript() {
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 *);

View File

@ -45,22 +45,18 @@ public:
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();
@ -74,7 +70,7 @@ public:
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);