2015-07-25 05:03:07 +08:00
|
|
|
//===- SymbolTable.cpp ----------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-10-14 03:51:57 +08:00
|
|
|
//
|
|
|
|
// Symbol table is a bag of all known symbols. We put all symbols of
|
2016-01-06 04:47:37 +08:00
|
|
|
// all input files to the symbol table. The symbol table is basically
|
2015-10-14 03:51:57 +08:00
|
|
|
// a hash table with the logic to resolve symbol name conflicts using
|
|
|
|
// the symbol types.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
#include "SymbolTable.h"
|
2015-09-12 06:42:45 +08:00
|
|
|
#include "Config.h"
|
2016-06-29 10:46:51 +08:00
|
|
|
#include "LinkerScript.h"
|
2015-07-25 05:03:07 +08:00
|
|
|
#include "Symbols.h"
|
2017-11-06 12:33:58 +08:00
|
|
|
#include "SyntheticSections.h"
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
#include "lld/Common/ErrorHandler.h"
|
2017-11-29 04:39:17 +08:00
|
|
|
#include "lld/Common/Memory.h"
|
2017-11-28 10:15:26 +08:00
|
|
|
#include "lld/Common/Strings.h"
|
2016-11-18 03:57:43 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
2015-08-31 09:16:19 +08:00
|
|
|
using namespace llvm::object;
|
2015-09-23 02:19:46 +08:00
|
|
|
using namespace llvm::ELF;
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
using namespace lld;
|
2016-02-28 08:25:54 +08:00
|
|
|
using namespace lld::elf;
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
SymbolTable *elf::Symtab;
|
|
|
|
|
2017-10-16 05:43:09 +08:00
|
|
|
static InputFile *getFirstElf() {
|
|
|
|
if (!ObjectFiles.empty())
|
|
|
|
return ObjectFiles[0];
|
|
|
|
if (!SharedFiles.empty())
|
|
|
|
return SharedFiles[0];
|
2018-07-11 20:32:00 +08:00
|
|
|
return BitcodeFiles[0];
|
2017-10-16 05:43:09 +08:00
|
|
|
}
|
|
|
|
|
2016-01-06 04:47:37 +08:00
|
|
|
// All input object files must be for the same architecture
|
|
|
|
// (e.g. it does not make sense to link x86 object files with
|
|
|
|
// MIPS object files.) This function checks for that error.
|
2017-12-23 08:04:34 +08:00
|
|
|
static bool isCompatible(InputFile *F) {
|
|
|
|
if (!F->isElf() && !isa<BitcodeFile>(F))
|
2016-01-30 03:41:13 +08:00
|
|
|
return true;
|
2016-11-25 04:59:44 +08:00
|
|
|
|
2016-11-06 06:58:01 +08:00
|
|
|
if (F->EKind == Config->EKind && F->EMachine == Config->EMachine) {
|
|
|
|
if (Config->EMachine != EM_MIPS)
|
|
|
|
return true;
|
|
|
|
if (isMipsN32Abi(F) == Config->MipsN32Abi)
|
|
|
|
return true;
|
|
|
|
}
|
2016-11-25 04:59:44 +08:00
|
|
|
|
|
|
|
if (!Config->Emulation.empty())
|
|
|
|
error(toString(F) + " is incompatible with " + Config->Emulation);
|
|
|
|
else
|
2017-10-16 05:43:09 +08:00
|
|
|
error(toString(F) + " is incompatible with " + toString(getFirstElf()));
|
2016-01-30 03:41:13 +08:00
|
|
|
return false;
|
2015-12-17 07:31:22 +08:00
|
|
|
}
|
|
|
|
|
2016-01-06 04:47:37 +08:00
|
|
|
// Add symbols in File to the symbol table.
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
|
2017-12-23 08:04:34 +08:00
|
|
|
if (!isCompatible(File))
|
2016-01-30 03:41:13 +08:00
|
|
|
return;
|
2015-10-11 11:36:49 +08:00
|
|
|
|
2016-09-10 06:08:04 +08:00
|
|
|
// Binary file
|
2016-09-14 08:05:51 +08:00
|
|
|
if (auto *F = dyn_cast<BinaryFile>(File)) {
|
2017-09-19 17:20:54 +08:00
|
|
|
BinaryFiles.push_back(F);
|
2017-12-24 01:21:39 +08:00
|
|
|
F->parse();
|
2016-09-10 06:08:04 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-17 06:59:13 +08:00
|
|
|
// .a file
|
2016-09-14 08:05:51 +08:00
|
|
|
if (auto *F = dyn_cast<ArchiveFile>(File)) {
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
F->parse<ELFT>();
|
2015-09-05 06:28:10 +08:00
|
|
|
return;
|
|
|
|
}
|
2015-10-13 02:03:21 +08:00
|
|
|
|
2016-04-14 02:07:57 +08:00
|
|
|
// Lazy object file
|
2017-07-27 06:13:32 +08:00
|
|
|
if (auto *F = dyn_cast<LazyObjFile>(File)) {
|
2018-05-03 05:40:07 +08:00
|
|
|
LazyObjFiles.push_back(F);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
F->parse<ELFT>();
|
2016-04-14 02:07:57 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Config->Trace)
|
2017-02-22 07:22:56 +08:00
|
|
|
message(toString(File));
|
2016-04-14 02:07:57 +08:00
|
|
|
|
2015-12-17 06:59:13 +08:00
|
|
|
// .so file
|
2016-09-14 08:05:51 +08:00
|
|
|
if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
|
2015-12-17 06:59:13 +08:00
|
|
|
// DSOs are uniquified not by filename but by soname.
|
|
|
|
F->parseSoName();
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
if (errorCount() || !SoNames.insert(F->SoName).second)
|
2015-10-02 03:52:48 +08:00
|
|
|
return;
|
2017-09-19 17:20:54 +08:00
|
|
|
SharedFiles.push_back(F);
|
2016-01-06 09:56:36 +08:00
|
|
|
F->parseRest();
|
2015-12-17 06:59:13 +08:00
|
|
|
return;
|
2015-10-02 03:52:48 +08:00
|
|
|
}
|
2015-12-17 06:59:13 +08:00
|
|
|
|
2016-04-08 03:24:51 +08:00
|
|
|
// LLVM bitcode file
|
2016-09-14 08:05:51 +08:00
|
|
|
if (auto *F = dyn_cast<BitcodeFile>(File)) {
|
2017-09-19 17:20:54 +08:00
|
|
|
BitcodeFiles.push_back(F);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
F->parse<ELFT>(ComdatGroups);
|
2016-02-13 04:54:57 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-04-08 03:24:51 +08:00
|
|
|
// Regular object file
|
2017-09-19 17:20:54 +08:00
|
|
|
ObjectFiles.push_back(File);
|
|
|
|
cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2016-04-23 08:26:32 +08:00
|
|
|
// This function is where all the optimizations of link-time
|
|
|
|
// optimization happens. When LTO is in use, some input files are
|
|
|
|
// not in native object file format but in the LLVM bitcode format.
|
|
|
|
// This function compiles bitcode files into a few big native files
|
|
|
|
// using LLVM functions and replaces bitcode symbols with the results.
|
2018-01-09 07:18:16 +08:00
|
|
|
// Because all bitcode files that the program consists of are passed
|
2016-04-23 08:26:32 +08:00
|
|
|
// to the compiler at once, it can do whole-program optimization.
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
|
2017-09-19 17:20:54 +08:00
|
|
|
if (BitcodeFiles.empty())
|
2016-02-13 04:54:57 +08:00
|
|
|
return;
|
2016-03-23 04:52:10 +08:00
|
|
|
|
2016-09-14 08:05:51 +08:00
|
|
|
// Compile bitcode files and replace bitcode symbols.
|
2016-11-26 13:37:04 +08:00
|
|
|
LTO.reset(new BitcodeCompiler);
|
2017-09-19 17:20:54 +08:00
|
|
|
for (BitcodeFile *F : BitcodeFiles)
|
2017-02-01 18:26:03 +08:00
|
|
|
LTO->add(*F);
|
2016-04-16 06:38:10 +08:00
|
|
|
|
2016-11-26 13:37:04 +08:00
|
|
|
for (InputFile *File : LTO->compile()) {
|
2017-05-26 05:53:02 +08:00
|
|
|
DenseSet<CachedHashStringRef> DummyGroups;
|
2018-03-29 06:45:39 +08:00
|
|
|
auto *Obj = cast<ObjFile<ELFT>>(File);
|
|
|
|
Obj->parse(DummyGroups);
|
|
|
|
for (Symbol *Sym : Obj->getGlobalSymbols())
|
|
|
|
Sym->parseSymbolVersion();
|
2017-09-19 17:20:54 +08:00
|
|
|
ObjectFiles.push_back(File);
|
2016-02-13 04:54:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-06 12:35:31 +08:00
|
|
|
Defined *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility,
|
|
|
|
uint8_t Binding) {
|
2017-12-24 01:21:39 +08:00
|
|
|
Symbol *Sym =
|
|
|
|
addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr);
|
2017-11-06 12:35:31 +08:00
|
|
|
return cast<Defined>(Sym);
|
2015-09-26 02:56:53 +08:00
|
|
|
}
|
|
|
|
|
2016-07-18 01:50:09 +08:00
|
|
|
// Set a flag for --trace-symbol so that we can print out a log message
|
|
|
|
// if a new symbol with the same name is inserted into the symbol table.
|
2017-07-27 02:42:48 +08:00
|
|
|
void SymbolTable::trace(StringRef Name) {
|
2017-11-28 07:16:06 +08:00
|
|
|
SymMap.insert({CachedHashStringRef(Name), -1});
|
2016-07-18 01:50:09 +08:00
|
|
|
}
|
|
|
|
|
Change how we handle -wrap.
We have an issue with -wrap that the option doesn't work well when
renamed symbols get PLT entries. I'll explain what is the issue and
how this patch solves it.
For one -wrap option, we have three symbols: foo, wrap_foo and real_foo.
Currently, we use memcpy to overwrite wrapped symbols so that they get
the same contents. This works in most cases but doesn't when the relocation
processor sets some flags in the symbol. memcpy'ed symbols are just
aliases, so they always have to have the same contents, but the
relocation processor breaks that assumption.
r336609 is an attempt to fix the issue by memcpy'ing again after
processing relocations, so that symbols that are out of sync get the
same contents again. That works in most cases as well, but it breaks
ASan build in a mysterious way.
We could probably fix the issue by choosing symbol attributes that need
to be copied after they are updated. But it feels too complicated to me.
So, in this patch, I fixed it once and for all. With this patch, we no
longer memcpy symbols. All references to renamed symbols point to new
symbols after wrapSymbols() is done.
Differential Revision: https://reviews.llvm.org/D50569
llvm-svn: 340387
2018-08-22 15:02:26 +08:00
|
|
|
void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
|
|
|
|
// Swap symbols as instructed by -wrap.
|
|
|
|
int &Idx1 = Symtab->SymMap[CachedHashStringRef(Sym->getName())];
|
|
|
|
int &Idx2 = Symtab->SymMap[CachedHashStringRef(Real->getName())];
|
|
|
|
int &Idx3 = Symtab->SymMap[CachedHashStringRef(Wrap->getName())];
|
2016-01-08 01:20:07 +08:00
|
|
|
|
Change how we handle -wrap.
We have an issue with -wrap that the option doesn't work well when
renamed symbols get PLT entries. I'll explain what is the issue and
how this patch solves it.
For one -wrap option, we have three symbols: foo, wrap_foo and real_foo.
Currently, we use memcpy to overwrite wrapped symbols so that they get
the same contents. This works in most cases but doesn't when the relocation
processor sets some flags in the symbol. memcpy'ed symbols are just
aliases, so they always have to have the same contents, but the
relocation processor breaks that assumption.
r336609 is an attempt to fix the issue by memcpy'ing again after
processing relocations, so that symbols that are out of sync get the
same contents again. That works in most cases as well, but it breaks
ASan build in a mysterious way.
We could probably fix the issue by choosing symbol attributes that need
to be copied after they are updated. But it feels too complicated to me.
So, in this patch, I fixed it once and for all. With this patch, we no
longer memcpy symbols. All references to renamed symbols point to new
symbols after wrapSymbols() is done.
Differential Revision: https://reviews.llvm.org/D50569
llvm-svn: 340387
2018-08-22 15:02:26 +08:00
|
|
|
Idx2 = Idx1;
|
|
|
|
Idx1 = Idx3;
|
2017-11-05 07:09:43 +08:00
|
|
|
|
Change how we handle -wrap.
We have an issue with -wrap that the option doesn't work well when
renamed symbols get PLT entries. I'll explain what is the issue and
how this patch solves it.
For one -wrap option, we have three symbols: foo, wrap_foo and real_foo.
Currently, we use memcpy to overwrite wrapped symbols so that they get
the same contents. This works in most cases but doesn't when the relocation
processor sets some flags in the symbol. memcpy'ed symbols are just
aliases, so they always have to have the same contents, but the
relocation processor breaks that assumption.
r336609 is an attempt to fix the issue by memcpy'ing again after
processing relocations, so that symbols that are out of sync get the
same contents again. That works in most cases as well, but it breaks
ASan build in a mysterious way.
We could probably fix the issue by choosing symbol attributes that need
to be copied after they are updated. But it feels too complicated to me.
So, in this patch, I fixed it once and for all. With this patch, we no
longer memcpy symbols. All references to renamed symbols point to new
symbols after wrapSymbols() is done.
Differential Revision: https://reviews.llvm.org/D50569
llvm-svn: 340387
2018-08-22 15:02:26 +08:00
|
|
|
// Now renaming is complete. No one refers Real symbol. We could leave
|
|
|
|
// Real as-is, but if Real is written to the symbol table, that may
|
|
|
|
// contain irrelevant values. So, we copy all values from Sym to Real.
|
|
|
|
StringRef S = Real->getName();
|
|
|
|
memcpy(Real, Sym, sizeof(SymbolUnion));
|
|
|
|
Real->setName(S);
|
2017-04-26 18:40:02 +08:00
|
|
|
}
|
|
|
|
|
2016-04-23 02:42:48 +08:00
|
|
|
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
|
|
|
|
if (VA == STV_DEFAULT)
|
|
|
|
return VB;
|
|
|
|
if (VB == STV_DEFAULT)
|
|
|
|
return VA;
|
|
|
|
return std::min(VA, VB);
|
|
|
|
}
|
|
|
|
|
2016-01-09 06:01:33 +08:00
|
|
|
// Find an existing symbol or create and insert a new one.
|
2017-11-04 05:21:47 +08:00
|
|
|
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
|
2017-07-20 00:45:05 +08:00
|
|
|
// <name>@@<version> means the symbol is the default version. In that
|
|
|
|
// case <name>@@<version> will be used to resolve references to <name>.
|
2017-09-26 12:17:13 +08:00
|
|
|
//
|
|
|
|
// Since this is a hot path, the following string search code is
|
|
|
|
// optimized for speed. StringRef::find(char) is much faster than
|
|
|
|
// StringRef::find(StringRef).
|
|
|
|
size_t Pos = Name.find('@');
|
|
|
|
if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
|
2017-07-20 00:45:05 +08:00
|
|
|
Name = Name.take_front(Pos);
|
|
|
|
|
2017-11-28 07:16:06 +08:00
|
|
|
auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
|
2017-11-06 12:58:04 +08:00
|
|
|
int &SymIndex = P.first->second;
|
2016-07-18 01:50:09 +08:00
|
|
|
bool IsNew = P.second;
|
2017-11-06 12:58:04 +08:00
|
|
|
bool Traced = false;
|
2016-07-18 01:50:09 +08:00
|
|
|
|
2017-11-06 12:58:04 +08:00
|
|
|
if (SymIndex == -1) {
|
|
|
|
SymIndex = SymVector.size();
|
|
|
|
IsNew = Traced = true;
|
2016-07-18 09:35:00 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *Sym;
|
2016-07-18 01:50:09 +08:00
|
|
|
if (IsNew) {
|
2018-02-14 02:11:42 +08:00
|
|
|
Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
|
2016-04-23 04:21:26 +08:00
|
|
|
Sym->Visibility = STV_DEFAULT;
|
|
|
|
Sym->IsUsedInRegularObj = false;
|
|
|
|
Sym->ExportDynamic = false;
|
2017-09-25 08:57:18 +08:00
|
|
|
Sym->CanInline = true;
|
2017-11-06 12:58:04 +08:00
|
|
|
Sym->Traced = Traced;
|
2016-11-23 13:48:40 +08:00
|
|
|
Sym->VersionId = Config->DefaultSymbolVersion;
|
2016-04-15 04:42:43 +08:00
|
|
|
SymVector.push_back(Sym);
|
|
|
|
} else {
|
2017-11-06 12:58:04 +08:00
|
|
|
Sym = SymVector[SymIndex];
|
2016-04-15 04:42:43 +08:00
|
|
|
}
|
2016-07-18 01:50:09 +08:00
|
|
|
return {Sym, IsNew};
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find an existing symbol or create and insert a new one, then apply the given
|
|
|
|
// attributes.
|
2017-11-04 05:21:47 +08:00
|
|
|
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
|
|
|
|
uint8_t Visibility,
|
|
|
|
bool CanOmitFromDynSym,
|
|
|
|
InputFile *File) {
|
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
|
|
|
std::tie(S, WasInserted) = insert(Name);
|
|
|
|
|
|
|
|
// Merge in the new symbol's visibility.
|
|
|
|
S->Visibility = getMinVisibility(S->Visibility, Visibility);
|
2017-04-01 07:40:21 +08:00
|
|
|
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
|
|
|
|
S->ExportDynamic = true;
|
2017-04-01 07:40:21 +08:00
|
|
|
|
2017-10-30 00:46:39 +08:00
|
|
|
if (!File || File->kind() == InputFile::ObjKind)
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
S->IsUsedInRegularObj = true;
|
2017-04-01 07:40:21 +08:00
|
|
|
|
2018-10-10 04:16:16 +08:00
|
|
|
bool HasTlsAttr = !WasInserted && (!S->isLazy() || S->isTls());
|
|
|
|
if (HasTlsAttr && (Type == STT_TLS) != S->isTls())
|
2017-11-01 00:07:41 +08:00
|
|
|
error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
|
|
|
|
toString(S->File) + "\n>>> defined in " + toString(File));
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
|
|
|
|
return {S, WasInserted};
|
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
|
2017-11-17 09:37:50 +08:00
|
|
|
return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT,
|
2017-07-27 02:42:48 +08:00
|
|
|
/*Type*/ 0,
|
|
|
|
/*CanOmitFromDynSym*/ false, /*File*/ nullptr);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
|
2016-12-22 13:11:12 +08:00
|
|
|
static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
|
|
|
|
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
template <class ELFT>
|
2017-11-17 09:37:50 +08:00
|
|
|
Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
|
2017-11-04 05:21:47 +08:00
|
|
|
uint8_t StOther, uint8_t Type,
|
|
|
|
bool CanOmitFromDynSym, InputFile *File) {
|
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2017-04-05 04:03:34 +08:00
|
|
|
uint8_t Visibility = getVisibility(StOther);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
std::tie(S, WasInserted) =
|
2017-04-05 04:03:34 +08:00
|
|
|
insert(Name, Type, Visibility, CanOmitFromDynSym, File);
|
2018-04-04 06:39:04 +08:00
|
|
|
|
2017-04-05 04:03:34 +08:00
|
|
|
// An undefined symbol with non default visibility must be satisfied
|
|
|
|
// in the same DSO.
|
2017-11-01 00:07:41 +08:00
|
|
|
if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) {
|
2017-11-17 09:37:50 +08:00
|
|
|
replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
return S;
|
|
|
|
}
|
2018-04-04 06:39:04 +08:00
|
|
|
|
2017-11-28 09:04:51 +08:00
|
|
|
if (S->isShared() || S->isLazy() || (S->isUndefined() && Binding != STB_WEAK))
|
|
|
|
S->Binding = Binding;
|
2018-04-04 06:39:04 +08:00
|
|
|
|
|
|
|
if (!Config->GcSections && Binding != STB_WEAK)
|
2017-11-01 00:07:41 +08:00
|
|
|
if (auto *SS = dyn_cast<SharedSymbol>(S))
|
2018-04-04 06:39:04 +08:00
|
|
|
SS->getFile<ELFT>().IsNeeded = true;
|
|
|
|
|
2018-04-04 01:16:52 +08:00
|
|
|
if (S->isLazy()) {
|
2017-10-25 00:27:31 +08:00
|
|
|
// An undefined weak will not fetch archive members. See comment on Lazy in
|
|
|
|
// Symbols.h for the details.
|
Add --warn-backrefs to maintain compatibility with other linkers
I'm proposing a new command line flag, --warn-backrefs in this patch.
The flag and the feature proposed below don't exist in GNU linkers
nor the current lld.
--warn-backrefs is an option to detect reverse or cyclic dependencies
between static archives, and it can be used to keep your program
compatible with GNU linkers after you switch to lld. I'll explain the
feature and why you may find it useful below.
lld's symbol resolution semantics is more relaxed than traditional
Unix linkers. Therefore,
ld.lld foo.a bar.o
succeeds even if bar.o contains an undefined symbol that have to be
resolved by some object file in foo.a. Traditional Unix linkers
don't allow this kind of backward reference, as they visit each
file only once from left to right in the command line while
resolving all undefined symbol at the moment of visiting.
In the above case, since there's no undefined symbol when a linker
visits foo.a, no files are pulled out from foo.a, and because the
linker forgets about foo.a after visiting, it can't resolve
undefined symbols that could have been resolved otherwise.
That lld accepts more relaxed form means (besides it makes more
sense) that you can accidentally write a command line or a build
file that works only with lld, even if you have a plan to
distribute it to wider users who may be using GNU linkers. With
--check-library-dependency, you can detect a library order that
doesn't work with other Unix linkers.
The option is also useful to detect cyclic dependencies between
static archives. Again, lld accepts
ld.lld foo.a bar.a
even if foo.a and bar.a depend on each other. With --warn-backrefs
it is handled as an error.
Here is how the option works. We assign a group ID to each file. A
file with a smaller group ID can pull out object files from an
archive file with an equal or greater group ID. Otherwise, it is a
reverse dependency and an error.
A file outside --{start,end}-group gets a fresh ID when
instantiated. All files within the same --{start,end}-group get the
same group ID. E.g.
ld.lld A B --start-group C D --end-group E
A and B form group 0, C, D and their member object files form group
1, and E forms group 2. I think that you can see how this group
assignment rule simulates the traditional linker's semantics.
Differential Revision: https://reviews.llvm.org/D45195
llvm-svn: 329636
2018-04-10 07:05:48 +08:00
|
|
|
if (Binding == STB_WEAK) {
|
2018-04-04 01:16:52 +08:00
|
|
|
S->Type = Type;
|
Add --warn-backrefs to maintain compatibility with other linkers
I'm proposing a new command line flag, --warn-backrefs in this patch.
The flag and the feature proposed below don't exist in GNU linkers
nor the current lld.
--warn-backrefs is an option to detect reverse or cyclic dependencies
between static archives, and it can be used to keep your program
compatible with GNU linkers after you switch to lld. I'll explain the
feature and why you may find it useful below.
lld's symbol resolution semantics is more relaxed than traditional
Unix linkers. Therefore,
ld.lld foo.a bar.o
succeeds even if bar.o contains an undefined symbol that have to be
resolved by some object file in foo.a. Traditional Unix linkers
don't allow this kind of backward reference, as they visit each
file only once from left to right in the command line while
resolving all undefined symbol at the moment of visiting.
In the above case, since there's no undefined symbol when a linker
visits foo.a, no files are pulled out from foo.a, and because the
linker forgets about foo.a after visiting, it can't resolve
undefined symbols that could have been resolved otherwise.
That lld accepts more relaxed form means (besides it makes more
sense) that you can accidentally write a command line or a build
file that works only with lld, even if you have a plan to
distribute it to wider users who may be using GNU linkers. With
--check-library-dependency, you can detect a library order that
doesn't work with other Unix linkers.
The option is also useful to detect cyclic dependencies between
static archives. Again, lld accepts
ld.lld foo.a bar.a
even if foo.a and bar.a depend on each other. With --warn-backrefs
it is handled as an error.
Here is how the option works. We assign a group ID to each file. A
file with a smaller group ID can pull out object files from an
archive file with an equal or greater group ID. Otherwise, it is a
reverse dependency and an error.
A file outside --{start,end}-group gets a fresh ID when
instantiated. All files within the same --{start,end}-group get the
same group ID. E.g.
ld.lld A B --start-group C D --end-group E
A and B form group 0, C, D and their member object files form group
1, and E forms group 2. I think that you can see how this group
assignment rule simulates the traditional linker's semantics.
Differential Revision: https://reviews.llvm.org/D45195
llvm-svn: 329636
2018-04-10 07:05:48 +08:00
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2018-05-11 07:53:05 +08:00
|
|
|
// Do extra check for --warn-backrefs.
|
|
|
|
//
|
|
|
|
// --warn-backrefs is an option to prevent an undefined reference from
|
|
|
|
// fetching an archive member written earlier in the command line. It can be
|
|
|
|
// used to keep compatibility with GNU linkers to some degree.
|
|
|
|
// I'll explain the feature and why you may find it useful in this comment.
|
|
|
|
//
|
|
|
|
// lld's symbol resolution semantics is more relaxed than traditional Unix
|
|
|
|
// linkers. For example,
|
|
|
|
//
|
|
|
|
// ld.lld foo.a bar.o
|
|
|
|
//
|
|
|
|
// succeeds even if bar.o contains an undefined symbol that has to be
|
|
|
|
// resolved by some object file in foo.a. Traditional Unix linkers don't
|
|
|
|
// allow this kind of backward reference, as they visit each file only once
|
|
|
|
// from left to right in the command line while resolving all undefined
|
|
|
|
// symbols at the moment of visiting.
|
|
|
|
//
|
|
|
|
// In the above case, since there's no undefined symbol when a linker visits
|
|
|
|
// foo.a, no files are pulled out from foo.a, and because the linker forgets
|
|
|
|
// about foo.a after visiting, it can't resolve undefined symbols in bar.o
|
|
|
|
// that could have been resolved otherwise.
|
|
|
|
//
|
|
|
|
// That lld accepts more relaxed form means that (besides it'd make more
|
|
|
|
// sense) you can accidentally write a command line or a build file that
|
|
|
|
// works only with lld, even if you have a plan to distribute it to wider
|
|
|
|
// users who may be using GNU linkers. With --warn-backrefs, you can detect
|
|
|
|
// a library order that doesn't work with other Unix linkers.
|
|
|
|
//
|
|
|
|
// The option is also useful to detect cyclic dependencies between static
|
|
|
|
// archives. Again, lld accepts
|
|
|
|
//
|
|
|
|
// ld.lld foo.a bar.a
|
|
|
|
//
|
|
|
|
// even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
|
|
|
|
// handled as an error.
|
|
|
|
//
|
|
|
|
// Here is how the option works. We assign a group ID to each file. A file
|
|
|
|
// with a smaller group ID can pull out object files from an archive file
|
|
|
|
// with an equal or greater group ID. Otherwise, it is a reverse dependency
|
|
|
|
// and an error.
|
|
|
|
//
|
|
|
|
// A file outside --{start,end}-group gets a fresh ID when instantiated. All
|
|
|
|
// files within the same --{start,end}-group get the same group ID. E.g.
|
|
|
|
//
|
|
|
|
// ld.lld A B --start-group C D --end-group E
|
|
|
|
//
|
|
|
|
// A forms group 0. B form group 1. C and D (including their member object
|
|
|
|
// files) form group 2. E forms group 3. I think that you can see how this
|
|
|
|
// group assignment rule simulates the traditional linker's semantics.
|
|
|
|
bool Backref =
|
|
|
|
Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
|
Add --warn-backrefs to maintain compatibility with other linkers
I'm proposing a new command line flag, --warn-backrefs in this patch.
The flag and the feature proposed below don't exist in GNU linkers
nor the current lld.
--warn-backrefs is an option to detect reverse or cyclic dependencies
between static archives, and it can be used to keep your program
compatible with GNU linkers after you switch to lld. I'll explain the
feature and why you may find it useful below.
lld's symbol resolution semantics is more relaxed than traditional
Unix linkers. Therefore,
ld.lld foo.a bar.o
succeeds even if bar.o contains an undefined symbol that have to be
resolved by some object file in foo.a. Traditional Unix linkers
don't allow this kind of backward reference, as they visit each
file only once from left to right in the command line while
resolving all undefined symbol at the moment of visiting.
In the above case, since there's no undefined symbol when a linker
visits foo.a, no files are pulled out from foo.a, and because the
linker forgets about foo.a after visiting, it can't resolve
undefined symbols that could have been resolved otherwise.
That lld accepts more relaxed form means (besides it makes more
sense) that you can accidentally write a command line or a build
file that works only with lld, even if you have a plan to
distribute it to wider users who may be using GNU linkers. With
--check-library-dependency, you can detect a library order that
doesn't work with other Unix linkers.
The option is also useful to detect cyclic dependencies between
static archives. Again, lld accepts
ld.lld foo.a bar.a
even if foo.a and bar.a depend on each other. With --warn-backrefs
it is handled as an error.
Here is how the option works. We assign a group ID to each file. A
file with a smaller group ID can pull out object files from an
archive file with an equal or greater group ID. Otherwise, it is a
reverse dependency and an error.
A file outside --{start,end}-group gets a fresh ID when
instantiated. All files within the same --{start,end}-group get the
same group ID. E.g.
ld.lld A B --start-group C D --end-group E
A and B form group 0, C, D and their member object files form group
1, and E forms group 2. I think that you can see how this group
assignment rule simulates the traditional linker's semantics.
Differential Revision: https://reviews.llvm.org/D45195
llvm-svn: 329636
2018-04-10 07:05:48 +08:00
|
|
|
fetchLazy<ELFT>(S);
|
2018-05-22 02:12:46 +08:00
|
|
|
|
2018-05-11 07:53:05 +08:00
|
|
|
// We don't report backward references to weak symbols as they can be
|
2018-05-22 02:12:46 +08:00
|
|
|
// overridden later.
|
2018-05-11 07:53:05 +08:00
|
|
|
if (Backref && S->Binding != STB_WEAK)
|
|
|
|
warn("backward reference detected: " + Name + " in " + toString(File) +
|
|
|
|
" refers to " + toString(S->File));
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2017-07-20 00:45:05 +08:00
|
|
|
// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
|
|
|
|
// foo@@VER. We want to effectively ignore foo, so give precedence to
|
|
|
|
// foo@@VER.
|
|
|
|
// FIXME: If users can transition to using
|
|
|
|
// .symver foo,foo@@@VER
|
|
|
|
// we can delete this hack.
|
2017-11-04 05:21:47 +08:00
|
|
|
static int compareVersion(Symbol *S, StringRef Name) {
|
2017-07-20 05:49:01 +08:00
|
|
|
bool A = Name.contains("@@");
|
2017-11-01 00:07:41 +08:00
|
|
|
bool B = S->getName().contains("@@");
|
2017-07-20 05:49:01 +08:00
|
|
|
if (A && !B)
|
2017-07-20 00:45:05 +08:00
|
|
|
return 1;
|
2017-07-20 05:49:01 +08:00
|
|
|
if (!A && B)
|
2017-07-20 00:45:05 +08:00
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
// We have a new defined symbol with the specified binding. Return 1 if the new
|
|
|
|
// symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
|
|
|
|
// strong defined symbols.
|
2017-11-04 05:21:47 +08:00
|
|
|
static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
|
2017-07-20 00:45:05 +08:00
|
|
|
StringRef Name) {
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (WasInserted)
|
|
|
|
return 1;
|
2017-11-06 12:39:07 +08:00
|
|
|
if (!S->isDefined())
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
return 1;
|
2017-07-20 00:45:05 +08:00
|
|
|
if (int R = compareVersion(S, Name))
|
|
|
|
return R;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (Binding == STB_WEAK)
|
|
|
|
return -1;
|
|
|
|
if (S->isWeak())
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We have a new non-common defined symbol with the specified binding. Return 1
|
|
|
|
// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
|
|
|
|
// is a conflict. If the new symbol wins, also update the binding.
|
2017-11-04 05:21:47 +08:00
|
|
|
static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
|
|
|
|
bool IsAbsolute, uint64_t Value,
|
|
|
|
StringRef Name) {
|
2017-11-17 09:37:50 +08:00
|
|
|
if (int Cmp = compareDefined(S, WasInserted, Binding, Name))
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
return Cmp;
|
2017-11-06 12:35:31 +08:00
|
|
|
if (auto *R = dyn_cast<Defined>(S)) {
|
2017-11-06 12:33:58 +08:00
|
|
|
if (R->Section && isa<BssSection>(R->Section)) {
|
|
|
|
// Non-common symbols take precedence over common symbols.
|
|
|
|
if (Config->WarnCommon)
|
|
|
|
warn("common " + S->getName() + " is overridden");
|
|
|
|
return 1;
|
|
|
|
}
|
2016-12-02 10:58:21 +08:00
|
|
|
if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
|
|
|
|
R->Value == Value)
|
|
|
|
return -1;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
|
|
|
|
uint8_t Binding, uint8_t StOther, uint8_t Type,
|
2017-12-21 00:19:48 +08:00
|
|
|
InputFile &File) {
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2016-12-22 13:11:12 +08:00
|
|
|
std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
|
2017-12-21 00:19:48 +08:00
|
|
|
/*CanOmitFromDynSym*/ false, &File);
|
2018-04-04 06:39:12 +08:00
|
|
|
|
2017-07-20 00:45:05 +08:00
|
|
|
int Cmp = compareDefined(S, WasInserted, Binding, N);
|
2018-04-04 06:39:12 +08:00
|
|
|
if (Cmp < 0)
|
|
|
|
return S;
|
|
|
|
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (Cmp > 0) {
|
2017-11-06 12:33:58 +08:00
|
|
|
auto *Bss = make<BssSection>("COMMON", Size, Alignment);
|
2017-12-21 00:19:48 +08:00
|
|
|
Bss->File = &File;
|
2017-11-06 12:33:58 +08:00
|
|
|
Bss->Live = !Config->GcSections;
|
|
|
|
InputSections.push_back(Bss);
|
|
|
|
|
2017-12-21 00:19:48 +08:00
|
|
|
replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
|
2018-04-04 06:39:12 +08:00
|
|
|
return S;
|
|
|
|
}
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
|
2018-04-04 06:39:12 +08:00
|
|
|
auto *D = cast<Defined>(S);
|
|
|
|
auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
|
|
|
|
if (!Bss) {
|
|
|
|
// Non-common symbols take precedence over common symbols.
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (Config->WarnCommon)
|
2018-04-04 06:39:12 +08:00
|
|
|
warn("common " + S->getName() + " is overridden");
|
|
|
|
return S;
|
|
|
|
}
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
|
2018-04-04 06:39:12 +08:00
|
|
|
if (Config->WarnCommon)
|
|
|
|
warn("multiple common of " + D->getName());
|
|
|
|
|
|
|
|
Bss->Alignment = std::max(Bss->Alignment, Alignment);
|
|
|
|
if (Size > Bss->Size) {
|
|
|
|
D->File = Bss->File = &File;
|
|
|
|
D->Size = Bss->Size = Size;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
static void reportDuplicate(Symbol *Sym, InputFile *NewFile) {
|
2018-03-20 07:04:04 +08:00
|
|
|
if (!Config->AllowMultipleDefinition)
|
|
|
|
error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
|
|
|
|
toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
|
2016-11-09 00:26:32 +08:00
|
|
|
}
|
|
|
|
|
2018-01-31 16:32:35 +08:00
|
|
|
static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
|
|
|
|
InputSectionBase *ErrSec, uint64_t ErrOffset) {
|
2018-03-20 07:04:04 +08:00
|
|
|
if (Config->AllowMultipleDefinition)
|
|
|
|
return;
|
|
|
|
|
2017-12-01 02:02:04 +08:00
|
|
|
Defined *D = cast<Defined>(Sym);
|
|
|
|
if (!D->Section || !ErrSec) {
|
2018-01-31 16:32:35 +08:00
|
|
|
reportDuplicate(Sym, NewFile);
|
2016-11-09 00:26:32 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-01 07:40:21 +08:00
|
|
|
// Construct and print an error message in the form of:
|
|
|
|
//
|
|
|
|
// ld.lld: error: duplicate symbol: foo
|
|
|
|
// >>> defined at bar.c:30
|
|
|
|
// >>> bar.o (/home/alice/src/bar.o)
|
|
|
|
// >>> defined at baz.c:563
|
|
|
|
// >>> baz.o in archive libbaz.a
|
|
|
|
auto *Sec1 = cast<InputSectionBase>(D->Section);
|
2017-12-24 01:21:39 +08:00
|
|
|
std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
|
2017-10-27 11:13:54 +08:00
|
|
|
std::string Obj1 = Sec1->getObjMsg(D->Value);
|
2017-12-24 01:21:39 +08:00
|
|
|
std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
|
2017-10-27 11:13:54 +08:00
|
|
|
std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
|
2017-04-01 07:40:21 +08:00
|
|
|
|
|
|
|
std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
|
|
|
|
if (!Src1.empty())
|
|
|
|
Msg += Src1 + "\n>>> ";
|
|
|
|
Msg += Obj1 + "\n>>> defined at ";
|
|
|
|
if (!Src2.empty())
|
|
|
|
Msg += Src2 + "\n>>> ";
|
|
|
|
Msg += Obj2;
|
2018-03-20 07:04:04 +08:00
|
|
|
error(Msg);
|
2016-11-09 00:26:32 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
|
|
|
|
uint64_t Value, uint64_t Size, uint8_t Binding,
|
|
|
|
SectionBase *Section, InputFile *File) {
|
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2016-12-22 13:11:12 +08:00
|
|
|
std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
|
2016-11-15 16:07:14 +08:00
|
|
|
/*CanOmitFromDynSym*/ false, File);
|
2017-07-26 07:15:35 +08:00
|
|
|
int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
|
|
|
|
Value, Name);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (Cmp > 0)
|
2017-11-17 09:37:50 +08:00
|
|
|
replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size,
|
|
|
|
Section);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
else if (Cmp == 0)
|
2018-01-31 16:32:35 +08:00
|
|
|
reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
|
|
|
|
Value);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ELFT>
|
2017-12-21 00:28:19 +08:00
|
|
|
void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
|
2017-10-29 04:15:56 +08:00
|
|
|
const typename ELFT::Sym &Sym, uint32_t Alignment,
|
2017-12-12 09:45:49 +08:00
|
|
|
uint32_t VerdefIndex) {
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
// DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
|
|
|
|
// as the visibility, which will leave the visibility in the symbol table
|
|
|
|
// unchanged.
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2017-02-27 07:35:34 +08:00
|
|
|
std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
|
2017-12-21 00:28:19 +08:00
|
|
|
/*CanOmitFromDynSym*/ true, &File);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
// Make sure we preempt DSO symbols with default visibility.
|
2017-01-17 01:35:23 +08:00
|
|
|
if (Sym.getVisibility() == STV_DEFAULT)
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
S->ExportDynamic = true;
|
2017-02-27 07:35:34 +08:00
|
|
|
|
2017-04-05 04:03:34 +08:00
|
|
|
// An undefined symbol with non default visibility must be satisfied
|
|
|
|
// in the same DSO.
|
2018-01-17 03:02:46 +08:00
|
|
|
if (WasInserted ||
|
|
|
|
((S->isUndefined() || S->isLazy()) && S->Visibility == STV_DEFAULT)) {
|
2017-11-17 09:37:50 +08:00
|
|
|
uint8_t Binding = S->Binding;
|
2018-01-24 00:59:20 +08:00
|
|
|
bool WasUndefined = S->isUndefined();
|
2017-12-15 08:01:33 +08:00
|
|
|
replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
|
2017-11-28 09:04:51 +08:00
|
|
|
Sym.getType(), Sym.st_value, Sym.st_size,
|
2017-12-12 09:45:49 +08:00
|
|
|
Alignment, VerdefIndex);
|
2017-11-17 09:37:50 +08:00
|
|
|
if (!WasInserted) {
|
|
|
|
S->Binding = Binding;
|
2018-01-24 00:59:20 +08:00
|
|
|
if (!S->isWeak() && !Config->GcSections && WasUndefined)
|
2017-12-21 00:28:19 +08:00
|
|
|
File.IsNeeded = true;
|
2017-11-17 09:37:50 +08:00
|
|
|
}
|
2016-06-10 02:01:35 +08:00
|
|
|
}
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
|
|
|
|
uint8_t StOther, uint8_t Type,
|
2017-12-21 00:16:40 +08:00
|
|
|
bool CanOmitFromDynSym, BitcodeFile &F) {
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2016-08-31 04:15:03 +08:00
|
|
|
std::tie(S, WasInserted) =
|
2017-12-21 00:16:40 +08:00
|
|
|
insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);
|
2017-07-26 07:15:35 +08:00
|
|
|
int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
|
|
|
|
/*IsAbs*/ false, /*Value*/ 0, Name);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (Cmp > 0)
|
2017-12-21 00:16:40 +08:00
|
|
|
replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
else if (Cmp == 0)
|
2017-12-21 00:16:40 +08:00
|
|
|
reportDuplicate(S, &F);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
return S;
|
2015-09-05 06:28:10 +08:00
|
|
|
}
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *SymbolTable::find(StringRef Name) {
|
2017-11-28 07:16:06 +08:00
|
|
|
auto It = SymMap.find(CachedHashStringRef(Name));
|
|
|
|
if (It == SymMap.end())
|
2015-10-14 00:34:14 +08:00
|
|
|
return nullptr;
|
2017-11-06 12:58:04 +08:00
|
|
|
if (It->second == -1)
|
2016-07-18 09:35:00 +08:00
|
|
|
return nullptr;
|
2017-11-06 12:58:04 +08:00
|
|
|
return SymVector[It->second];
|
2015-10-14 00:34:14 +08:00
|
|
|
}
|
|
|
|
|
2018-10-10 03:54:32 +08:00
|
|
|
template <class ELFT>
|
|
|
|
void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &File,
|
|
|
|
const object::Archive::Symbol Sym) {
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *S;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
bool WasInserted;
|
2018-04-24 17:41:56 +08:00
|
|
|
std::tie(S, WasInserted) = Symtab->insert(Name);
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (WasInserted) {
|
2018-10-10 04:16:16 +08:00
|
|
|
replaceSymbol<LazyArchive>(S, File, STT_NOTYPE, Sym);
|
2018-02-17 04:23:54 +08:00
|
|
|
return;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
}
|
2017-11-01 00:07:41 +08:00
|
|
|
if (!S->isUndefined())
|
2018-02-17 04:23:54 +08:00
|
|
|
return;
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
|
2017-10-25 00:27:31 +08:00
|
|
|
// An undefined weak will not fetch archive members. See comment on Lazy in
|
|
|
|
// Symbols.h for the details.
|
ELF: New symbol table design.
This patch implements a new design for the symbol table that stores
SymbolBodies within a memory region of the Symbol object. Symbols are mutated
by constructing SymbolBodies in place over existing SymbolBodies, rather
than by mutating pointers. As mentioned in the initial proposal [1], this
memory layout helps reduce the cache miss rate by improving memory locality.
Performance numbers:
old(s) new(s)
Without debug info:
chrome 7.178 6.432 (-11.5%)
LLVMgold.so 0.505 0.502 (-0.5%)
clang 0.954 0.827 (-15.4%)
llvm-as 0.052 0.045 (-15.5%)
With debug info:
scylla 5.695 5.613 (-1.5%)
clang 14.396 14.143 (-1.8%)
Performance counter results show that the fewer required indirections is
indeed the cause of the improved performance. For example, when linking
chrome, stalled cycles decreases from 14,556,444,002 to 12,959,238,310, and
instructions per cycle increases from 0.78 to 0.83. We are also executing
many fewer instructions (15,516,401,933 down to 15,002,434,310), probably
because we spend less time allocating SymbolBodies.
The new mechanism by which symbols are added to the symbol table is by calling
add* functions on the SymbolTable.
In this patch, I handle local symbols by storing them inside "unparented"
SymbolBodies. This is suboptimal, but if we do want to try to avoid allocating
these SymbolBodies, we can probably do that separately.
I also removed a few members from the SymbolBody class that were only being
used to pass information from the input file to the symbol table.
This patch implements the new design for the ELF linker only. I intend to
prepare a similar patch for the COFF linker.
[1] http://lists.llvm.org/pipermail/llvm-dev/2016-April/098832.html
Differential Revision: http://reviews.llvm.org/D19752
llvm-svn: 268178
2016-05-01 12:55:03 +08:00
|
|
|
if (S->isWeak()) {
|
2018-10-10 03:54:32 +08:00
|
|
|
replaceSymbol<LazyArchive>(S, File, S->Type, Sym);
|
2017-11-17 09:37:50 +08:00
|
|
|
S->Binding = STB_WEAK;
|
2018-02-17 04:23:54 +08:00
|
|
|
return;
|
2015-10-06 22:33:58 +08:00
|
|
|
}
|
2018-04-24 17:41:56 +08:00
|
|
|
|
2018-10-10 03:54:32 +08:00
|
|
|
if (InputFile *F = File.fetch(Sym))
|
2018-04-24 17:41:56 +08:00
|
|
|
Symtab->addFile<ELFT>(F);
|
2015-09-05 06:28:10 +08:00
|
|
|
}
|
|
|
|
|
2015-12-17 07:23:14 +08:00
|
|
|
template <class ELFT>
|
2018-10-10 03:54:32 +08:00
|
|
|
void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &File) {
|
|
|
|
Symbol *S;
|
|
|
|
bool WasInserted;
|
|
|
|
std::tie(S, WasInserted) = Symtab->insert(Name);
|
|
|
|
if (WasInserted) {
|
2018-10-10 04:16:16 +08:00
|
|
|
replaceSymbol<LazyObject>(S, File, STT_NOTYPE, Name);
|
2018-10-10 03:54:32 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!S->isUndefined())
|
|
|
|
return;
|
2015-12-17 07:23:14 +08:00
|
|
|
|
2018-10-10 03:54:32 +08:00
|
|
|
// An undefined weak will not fetch archive members. See comment on Lazy in
|
|
|
|
// Symbols.h for the details.
|
|
|
|
if (S->isWeak()) {
|
|
|
|
replaceSymbol<LazyObject>(S, File, S->Type, Name);
|
|
|
|
S->Binding = STB_WEAK;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InputFile *F = File.fetch())
|
|
|
|
Symtab->addFile<ELFT>(F);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
2015-09-26 02:56:53 +08:00
|
|
|
|
2018-04-04 02:01:18 +08:00
|
|
|
template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
|
|
|
|
if (auto *S = dyn_cast<LazyArchive>(Sym)) {
|
|
|
|
if (InputFile *File = S->fetch())
|
|
|
|
addFile<ELFT>(File);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto *S = cast<LazyObject>(Sym);
|
|
|
|
if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
|
|
|
|
addFile<ELFT>(File);
|
2017-10-03 20:23:46 +08:00
|
|
|
}
|
|
|
|
|
2016-11-16 02:41:52 +08:00
|
|
|
// Initialize DemangledSyms with a map from demangled symbols to symbol
|
|
|
|
// objects. Used to handle "extern C++" directive in version scripts.
|
|
|
|
//
|
|
|
|
// The map will contain all demangled symbols. That can be very large,
|
|
|
|
// and in LLD we generally want to avoid do anything for each symbol.
|
|
|
|
// Then, why are we doing this? Here's why.
|
|
|
|
//
|
|
|
|
// Users can use "extern C++ {}" directive to match against demangled
|
|
|
|
// C++ symbols. For example, you can write a pattern such as
|
|
|
|
// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
|
|
|
|
// other than trying to match a pattern against all demangled symbols.
|
|
|
|
// So, if "extern C++" feature is used, we need to demangle all known
|
|
|
|
// symbols.
|
2017-11-04 05:21:47 +08:00
|
|
|
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
|
2016-12-22 13:31:52 +08:00
|
|
|
if (!DemangledSyms) {
|
|
|
|
DemangledSyms.emplace();
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *Sym : SymVector) {
|
2017-11-06 12:39:07 +08:00
|
|
|
if (!Sym->isDefined())
|
2016-12-22 17:54:32 +08:00
|
|
|
continue;
|
2017-11-28 10:15:26 +08:00
|
|
|
if (Optional<std::string> S = demangleItanium(Sym->getName()))
|
2017-11-01 00:07:41 +08:00
|
|
|
(*DemangledSyms)[*S].push_back(Sym);
|
2016-12-22 13:31:52 +08:00
|
|
|
else
|
2017-11-01 00:07:41 +08:00
|
|
|
(*DemangledSyms)[Sym->getName()].push_back(Sym);
|
2016-12-22 13:31:52 +08:00
|
|
|
}
|
2016-07-18 09:34:57 +08:00
|
|
|
}
|
2016-12-22 13:31:52 +08:00
|
|
|
return *DemangledSyms;
|
2016-07-16 20:26:39 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
|
2016-12-22 13:31:52 +08:00
|
|
|
if (Ver.IsExternCpp)
|
|
|
|
return getDemangledSyms().lookup(Ver.Name);
|
2017-11-04 05:21:47 +08:00
|
|
|
if (Symbol *B = find(Ver.Name))
|
2017-11-06 12:39:07 +08:00
|
|
|
if (B->isDefined())
|
2016-12-22 17:54:32 +08:00
|
|
|
return {B};
|
|
|
|
return {};
|
2016-12-08 23:56:33 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
|
|
|
|
std::vector<Symbol *> Res;
|
2016-12-21 10:27:14 +08:00
|
|
|
StringMatcher M(Ver.Name);
|
2016-12-09 00:26:20 +08:00
|
|
|
|
2016-12-09 00:02:48 +08:00
|
|
|
if (Ver.IsExternCpp) {
|
2016-12-22 13:31:52 +08:00
|
|
|
for (auto &P : getDemangledSyms())
|
2016-12-09 00:02:48 +08:00
|
|
|
if (M.match(P.first()))
|
2016-12-22 17:54:32 +08:00
|
|
|
Res.insert(Res.end(), P.second.begin(), P.second.end());
|
2016-12-09 00:02:48 +08:00
|
|
|
return Res;
|
|
|
|
}
|
2016-12-09 00:26:20 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *Sym : SymVector)
|
2017-11-06 12:39:07 +08:00
|
|
|
if (Sym->isDefined() && M.match(Sym->getName()))
|
2017-11-01 00:07:41 +08:00
|
|
|
Res.push_back(Sym);
|
2016-12-09 00:26:20 +08:00
|
|
|
return Res;
|
2016-12-08 23:56:33 +08:00
|
|
|
}
|
|
|
|
|
2016-09-14 04:51:30 +08:00
|
|
|
// If there's only one anonymous version definition in a version
|
2016-11-14 17:56:35 +08:00
|
|
|
// script file, the script does not actually define any symbol version,
|
2017-01-11 00:37:24 +08:00
|
|
|
// but just specifies symbols visibilities.
|
2017-07-27 02:42:48 +08:00
|
|
|
void SymbolTable::handleAnonymousVersion() {
|
2017-01-11 00:37:24 +08:00
|
|
|
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
|
|
|
assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
|
|
|
|
for (SymbolVersion &Ver : Config->VersionScriptGlobals)
|
|
|
|
assignWildcardVersion(Ver, VER_NDX_GLOBAL);
|
|
|
|
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
|
|
|
assignExactVersion(Ver, VER_NDX_LOCAL, "local");
|
|
|
|
for (SymbolVersion &Ver : Config->VersionScriptLocals)
|
|
|
|
assignWildcardVersion(Ver, VER_NDX_LOCAL);
|
2016-09-14 04:51:30 +08:00
|
|
|
}
|
|
|
|
|
2017-09-09 02:16:59 +08:00
|
|
|
// Handles -dynamic-list.
|
|
|
|
void SymbolTable::handleDynamicList() {
|
|
|
|
for (SymbolVersion &Ver : Config->DynamicList) {
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> Syms;
|
2017-09-09 02:16:59 +08:00
|
|
|
if (Ver.HasWildcard)
|
|
|
|
Syms = findAllByVersion(Ver);
|
2017-12-06 08:14:04 +08:00
|
|
|
else
|
|
|
|
Syms = findByVersion(Ver);
|
2017-09-09 02:16:59 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *B : Syms) {
|
2017-09-09 02:16:59 +08:00
|
|
|
if (!Config->Shared)
|
2017-11-01 00:07:41 +08:00
|
|
|
B->ExportDynamic = true;
|
|
|
|
else if (B->includeInDynsym())
|
2017-09-09 02:16:59 +08:00
|
|
|
B->IsPreemptible = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-17 10:09:42 +08:00
|
|
|
// Set symbol versions to symbols. This function handles patterns
|
|
|
|
// containing no wildcard characters.
|
2017-07-27 02:42:48 +08:00
|
|
|
void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
|
|
|
|
StringRef VersionName) {
|
2016-11-18 14:30:08 +08:00
|
|
|
if (Ver.HasWildcard)
|
2016-11-17 10:09:42 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Get a list of symbols which we need to assign the version to.
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> Syms = findByVersion(Ver);
|
2016-12-22 17:54:32 +08:00
|
|
|
if (Syms.empty()) {
|
2018-02-03 05:44:06 +08:00
|
|
|
if (!Config->UndefinedVersion)
|
2016-12-22 17:54:32 +08:00
|
|
|
error("version script assignment of '" + VersionName + "' to symbol '" +
|
|
|
|
Ver.Name + "' failed: symbol not defined");
|
|
|
|
return;
|
|
|
|
}
|
2016-11-17 10:09:42 +08:00
|
|
|
|
|
|
|
// Assign the version.
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *Sym : Syms) {
|
2017-07-12 21:54:42 +08:00
|
|
|
// Skip symbols containing version info because symbol versions
|
|
|
|
// specified by symbol names take precedence over version scripts.
|
|
|
|
// See parseSymbolVersion().
|
2017-11-01 00:07:41 +08:00
|
|
|
if (Sym->getName().contains('@'))
|
2017-07-12 21:54:42 +08:00
|
|
|
continue;
|
|
|
|
|
2018-03-07 01:05:12 +08:00
|
|
|
if (Sym->VersionId != Config->DefaultSymbolVersion &&
|
|
|
|
Sym->VersionId != VersionId)
|
|
|
|
error("duplicate symbol '" + Ver.Name + "' in version script");
|
2016-12-10 06:40:49 +08:00
|
|
|
Sym->VersionId = VersionId;
|
2016-11-17 10:09:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
|
2016-11-18 14:30:08 +08:00
|
|
|
if (!Ver.HasWildcard)
|
2016-11-16 02:41:52 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Exact matching takes precendence over fuzzy matching,
|
|
|
|
// so we set a version to a symbol only if no version has been assigned
|
|
|
|
// to the symbol. This behavior is compatible with GNU.
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *B : findAllByVersion(Ver))
|
2017-11-01 00:07:41 +08:00
|
|
|
if (B->VersionId == Config->DefaultSymbolVersion)
|
|
|
|
B->VersionId = VersionId;
|
2016-11-16 02:41:52 +08:00
|
|
|
}
|
|
|
|
|
2016-09-03 06:15:08 +08:00
|
|
|
// This function processes version scripts by updating VersionId
|
|
|
|
// member of symbols.
|
2017-07-27 02:42:48 +08:00
|
|
|
void SymbolTable::scanVersionScript() {
|
2016-09-14 04:51:30 +08:00
|
|
|
// Handle edge cases first.
|
2017-01-11 00:37:24 +08:00
|
|
|
handleAnonymousVersion();
|
2017-09-09 02:16:59 +08:00
|
|
|
handleDynamicList();
|
2016-06-20 19:55:12 +08:00
|
|
|
|
2016-09-03 06:15:08 +08:00
|
|
|
// Now we have version definitions, so we need to set version ids to symbols.
|
|
|
|
// Each version definition has a glob pattern, and all symbols that match
|
|
|
|
// with the pattern get that version.
|
|
|
|
|
|
|
|
// First, we assign versions to exact matching symbols,
|
|
|
|
// i.e. version definitions not containing any glob meta-characters.
|
2016-11-17 02:46:23 +08:00
|
|
|
for (VersionDefinition &V : Config->VersionDefinitions)
|
2016-11-18 03:57:45 +08:00
|
|
|
for (SymbolVersion &Ver : V.Globals)
|
|
|
|
assignExactVersion(Ver, V.Id, V.Name);
|
[ELF] - Fixed incorrect logic of version assignments when mixing wildcards with values matching.
Previously we had incorrect logic here. Imagine we would have the next script:
LIBSAMPLE_1.0
{
global:
a_2;
local:
*;
};
LIBSAMPLE_2.0
{
global:
a*;
};
According to previous logic it would assign version 1 to a_2 and then
would try to reassign it to version 2 because of applying wildcard a*.
And show a warning about that.
Generally Ian Lance Tailor wrote about next rules that should be applied:
(http://www.airs.com/blog/archives/300)
Here are the current rules for gold:
"If there is an exact match for the mangled name, we use it. If there is more than one exact match, we give a warning, and we use the first tag in the script which matches. If a symbol has an exact match as both global and local for the same version tag, we give an error.
Otherwise, we look for an extern C++ or an extern Java exact match. If we find an exact match, we use it. If there is more than one exact match, we give a warning, and we use the first tag in the script which matches. If a symbol has an exact match as both global and local for the same version tag, we give an error.
Otherwise, we look through the wildcard patterns, ignoring “*” patterns. We look through the version tags in reverse order. For each version tag, we look through the global patterns and then the local patterns. We use the first match we find (i.e., the last matching version tag in the file).
Otherwise, we use the “*” pattern if there is one. We give a warning if there are multiple “*” patterns."
Patch makes wildcard matching to be in revered order and to follow after the regular naming matching.
Differential revision: http://reviews.llvm.org/D21894
llvm-svn: 274739
2016-07-07 15:45:27 +08:00
|
|
|
|
2016-09-03 06:15:08 +08:00
|
|
|
// Next, we assign versions to fuzzy matching symbols,
|
|
|
|
// i.e. version definitions containing glob meta-characters.
|
|
|
|
// Note that because the last match takes precedence over previous matches,
|
|
|
|
// we iterate over the definitions in the reverse order.
|
2016-11-18 03:57:43 +08:00
|
|
|
for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
|
|
|
|
for (SymbolVersion &Ver : V.Globals)
|
|
|
|
assignWildcardVersion(Ver, V.Id);
|
2017-07-12 21:54:42 +08:00
|
|
|
|
|
|
|
// Symbol themselves might know their versions because symbols
|
|
|
|
// can contain versions in the form of <name>@<version>.
|
|
|
|
// Let them parse and update their names to exclude version suffix.
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *Sym : SymVector)
|
2017-11-01 00:07:41 +08:00
|
|
|
Sym->parseSymbolVersion();
|
2016-04-23 04:21:26 +08:00
|
|
|
}
|
|
|
|
|
2018-01-09 13:35:29 +08:00
|
|
|
template void SymbolTable::addFile<ELF32LE>(InputFile *);
|
|
|
|
template void SymbolTable::addFile<ELF32BE>(InputFile *);
|
|
|
|
template void SymbolTable::addFile<ELF64LE>(InputFile *);
|
|
|
|
template void SymbolTable::addFile<ELF64BE>(InputFile *);
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef);
|
|
|
|
|
2017-11-17 09:37:50 +08:00
|
|
|
template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
|
|
|
|
uint8_t, bool, InputFile *);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
|
|
|
|
uint8_t, bool, InputFile *);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t,
|
|
|
|
uint8_t, bool, InputFile *);
|
|
|
|
template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t,
|
|
|
|
uint8_t, bool, InputFile *);
|
2017-07-27 05:37:11 +08:00
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
template void SymbolTable::addCombinedLTOObject<ELF32LE>();
|
|
|
|
template void SymbolTable::addCombinedLTOObject<ELF32BE>();
|
|
|
|
template void SymbolTable::addCombinedLTOObject<ELF64LE>();
|
|
|
|
template void SymbolTable::addCombinedLTOObject<ELF64BE>();
|
|
|
|
|
2018-02-17 04:23:54 +08:00
|
|
|
template void
|
2017-12-21 01:48:28 +08:00
|
|
|
SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const object::Archive::Symbol);
|
2018-02-17 04:23:54 +08:00
|
|
|
template void
|
2017-12-21 01:48:28 +08:00
|
|
|
SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const object::Archive::Symbol);
|
2018-02-17 04:23:54 +08:00
|
|
|
template void
|
2017-12-21 01:48:28 +08:00
|
|
|
SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const object::Archive::Symbol);
|
2018-02-17 04:23:54 +08:00
|
|
|
template void
|
2017-12-21 01:48:28 +08:00
|
|
|
SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const object::Archive::Symbol);
|
|
|
|
|
2017-07-27 06:13:32 +08:00
|
|
|
template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &);
|
|
|
|
template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &);
|
|
|
|
template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
|
|
|
|
template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
|
2017-07-27 02:42:48 +08:00
|
|
|
|
2018-04-04 02:59:31 +08:00
|
|
|
template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
|
|
|
|
template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
|
|
|
|
template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
|
|
|
|
template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
|
|
|
|
|
2017-12-21 00:28:19 +08:00
|
|
|
template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const typename ELF32LE::Sym &,
|
2017-12-12 09:45:49 +08:00
|
|
|
uint32_t Alignment, uint32_t);
|
2017-12-21 00:28:19 +08:00
|
|
|
template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const typename ELF32BE::Sym &,
|
2017-12-12 09:45:49 +08:00
|
|
|
uint32_t Alignment, uint32_t);
|
2017-12-21 00:28:19 +08:00
|
|
|
template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const typename ELF64LE::Sym &,
|
2017-12-12 09:45:49 +08:00
|
|
|
uint32_t Alignment, uint32_t);
|
2017-12-21 00:28:19 +08:00
|
|
|
template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
|
2017-07-27 02:42:48 +08:00
|
|
|
const typename ELF64BE::Sym &,
|
2017-12-12 09:45:49 +08:00
|
|
|
uint32_t Alignment, uint32_t);
|