2015-08-14 22:12:54 +08:00
|
|
|
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
|
2015-07-25 05:03:07 +08:00
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLD_ELF_SYMBOL_TABLE_H
|
|
|
|
#define LLD_ELF_SYMBOL_TABLE_H
|
|
|
|
|
|
|
|
#include "InputFiles.h"
|
2016-03-23 04:52:10 +08:00
|
|
|
#include "LTO.h"
|
2018-03-01 01:38:19 +08:00
|
|
|
#include "lld/Common/Strings.h"
|
2016-10-19 01:50:36 +08:00
|
|
|
#include "llvm/ADT/CachedHashString.h"
|
2016-04-15 04:42:43 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
namespace lld {
|
2016-02-28 08:25:54 +08:00
|
|
|
namespace elf {
|
2017-12-10 00:56:18 +08:00
|
|
|
class Defined;
|
|
|
|
class SectionBase;
|
2017-06-30 08:34:35 +08:00
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
// SymbolTable is a bucket of all known symbols, including defined,
|
|
|
|
// undefined, or lazy symbols (the last one is symbols in archive
|
|
|
|
// files whose archive members are not yet loaded).
|
|
|
|
//
|
|
|
|
// We put all symbols of all files to a SymbolTable, and the
|
|
|
|
// SymbolTable selects the "best" symbols if there are name
|
|
|
|
// conflicts. For example, obviously, a defined symbol is better than
|
|
|
|
// an undefined symbol. Or, if there's a conflict between a lazy and a
|
|
|
|
// undefined, it'll read an archive member to read a real definition
|
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
|
|
|
// to replace the lazy symbol. The logic is implemented in the
|
|
|
|
// add*() functions, which are called by input files as they are parsed. There
|
|
|
|
// is one add* function per symbol type.
|
2017-07-27 02:42:48 +08:00
|
|
|
class SymbolTable {
|
2015-07-25 05:03:07 +08:00
|
|
|
public:
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT> void addFile(InputFile *File);
|
|
|
|
template <class ELFT> void addCombinedLTOObject();
|
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 wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap);
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
ArrayRef<Symbol *> getSymbols() const { return SymVector; }
|
2015-09-09 03:43:27 +08:00
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT>
|
2017-11-17 09:37:50 +08:00
|
|
|
Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther,
|
|
|
|
uint8_t Type, bool CanOmitFromDynSym, InputFile *File);
|
2018-10-12 04:34:29 +08:00
|
|
|
|
2018-10-12 04:43:01 +08:00
|
|
|
Symbol *addDefined(StringRef Name, uint8_t StOther, uint8_t Type,
|
2017-11-04 05:21:47 +08:00
|
|
|
uint64_t Value, uint64_t Size, uint8_t Binding,
|
|
|
|
SectionBase *Section, InputFile *File);
|
2016-11-10 07:37:40 +08:00
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT>
|
2017-12-21 00:28:19 +08:00
|
|
|
void addShared(StringRef Name, SharedFile<ELFT> &F,
|
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
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
template <class ELFT>
|
2018-02-17 04:23:54 +08:00
|
|
|
void addLazyArchive(StringRef Name, ArchiveFile &F,
|
|
|
|
const llvm::object::Archive::Symbol S);
|
2017-09-30 20:41:34 +08:00
|
|
|
|
2017-07-27 06:13:32 +08:00
|
|
|
template <class ELFT> void addLazyObject(StringRef Name, LazyObjFile &Obj);
|
2017-07-27 02:42:48 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
|
2017-12-21 00:16:40 +08:00
|
|
|
uint8_t Type, bool CanOmitFromDynSym, BitcodeFile &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
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *addCommon(StringRef Name, 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);
|
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
|
|
|
std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
|
|
|
|
uint8_t Visibility, bool CanOmitFromDynSym,
|
|
|
|
InputFile *File);
|
2017-02-22 06:32:51 +08:00
|
|
|
|
2018-04-04 02:01:18 +08:00
|
|
|
template <class ELFT> void fetchLazy(Symbol *Sym);
|
2018-04-04 01:16:52 +08:00
|
|
|
|
2016-04-23 04:21:26 +08:00
|
|
|
void scanVersionScript();
|
2016-06-23 15:00:17 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
Symbol *find(StringRef Name);
|
2016-07-18 01:50:09 +08:00
|
|
|
|
|
|
|
void trace(StringRef Name);
|
2015-10-02 05:22:26 +08:00
|
|
|
|
2017-09-09 02:16:59 +08:00
|
|
|
void handleDynamicList();
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
private:
|
2018-10-11 06:49:29 +08:00
|
|
|
std::pair<Symbol *, bool> insertName(StringRef Name);
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> findByVersion(SymbolVersion Ver);
|
|
|
|
std::vector<Symbol *> findAllByVersion(SymbolVersion Ver);
|
2016-11-16 02:41:52 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
llvm::StringMap<std::vector<Symbol *>> &getDemangledSyms();
|
2016-09-14 04:51:30 +08:00
|
|
|
void handleAnonymousVersion();
|
2016-11-17 11:39:21 +08:00
|
|
|
void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
|
2016-11-17 10:09:42 +08:00
|
|
|
StringRef VersionName);
|
2016-11-17 11:39:21 +08:00
|
|
|
void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
|
2016-07-16 20:26:39 +08:00
|
|
|
|
2015-09-18 02:26:25 +08:00
|
|
|
// The order the global symbols are in is not defined. We can use an arbitrary
|
|
|
|
// order, but it has to be reproducible. That is true even when cross linking.
|
|
|
|
// The default hashing of StringRef produces different results on 32 and 64
|
2016-04-15 04:42:43 +08:00
|
|
|
// bit systems so we use a map to a vector. That is arbitrary, deterministic
|
|
|
|
// but a bit inefficient.
|
2015-09-18 02:26:25 +08:00
|
|
|
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
|
|
|
|
// once symbol resolution is finished.
|
2017-11-28 07:16:06 +08:00
|
|
|
llvm::DenseMap<llvm::CachedHashStringRef, int> SymMap;
|
2017-11-04 05:21:47 +08:00
|
|
|
std::vector<Symbol *> SymVector;
|
2015-09-04 02:56:20 +08:00
|
|
|
|
2016-01-09 06:14:15 +08:00
|
|
|
// Comdat groups define "link once" sections. If two comdat groups have the
|
|
|
|
// same name, only one of them is linked, and the other is ignored. This set
|
|
|
|
// is used to uniquify them.
|
2017-05-26 05:53:02 +08:00
|
|
|
llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
|
2015-10-10 03:25:07 +08:00
|
|
|
|
2016-01-09 06:14:15 +08:00
|
|
|
// Set of .so files to not link the same shared object file more than once.
|
2016-01-09 06:17:42 +08:00
|
|
|
llvm::DenseSet<StringRef> SoNames;
|
2016-03-23 04:52:10 +08:00
|
|
|
|
2016-11-16 02:41:52 +08:00
|
|
|
// A map from demangled symbol names to their symbol objects.
|
|
|
|
// This mapping is 1:N because two symbols with different versions
|
|
|
|
// can have the same name. We use this map to handle "extern C++ {}"
|
|
|
|
// directive in version scripts.
|
2017-11-04 05:21:47 +08:00
|
|
|
llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
|
2016-11-16 02:41:52 +08:00
|
|
|
|
|
|
|
// For LTO.
|
2016-11-26 13:37:04 +08:00
|
|
|
std::unique_ptr<BitcodeCompiler> LTO;
|
2015-07-25 05:03:07 +08:00
|
|
|
};
|
|
|
|
|
2017-07-27 02:42:48 +08:00
|
|
|
extern SymbolTable *Symtab;
|
2016-02-28 08:25:54 +08:00
|
|
|
} // namespace elf
|
2015-07-25 05:03:07 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|