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"
|
2015-09-18 02:26:25 +08:00
|
|
|
#include "llvm/ADT/MapVector.h"
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
namespace lld {
|
2016-02-28 08:25:54 +08:00
|
|
|
namespace elf {
|
2015-12-17 07:23:14 +08:00
|
|
|
class Lazy;
|
|
|
|
template <class ELFT> class OutputSectionBase;
|
2015-12-23 07:00:50 +08:00
|
|
|
struct Symbol;
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2016-04-15 03:17:16 +08:00
|
|
|
struct SymName {
|
|
|
|
SymName(StringRef Name) : Name(Name) {
|
|
|
|
Hash = llvm::DenseMapInfo<StringRef>::getHashValue(Name);
|
|
|
|
}
|
|
|
|
SymName(StringRef Name, unsigned Hash) : Name(Name), Hash(Hash) {}
|
|
|
|
StringRef Name;
|
|
|
|
unsigned Hash;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
template <> struct DenseMapInfo<lld::elf::SymName> {
|
|
|
|
static lld::elf::SymName getEmptyKey() {
|
|
|
|
StringRef N = DenseMapInfo<StringRef>::getEmptyKey();
|
|
|
|
return {N, 0};
|
|
|
|
}
|
|
|
|
static lld::elf::SymName getTombstoneKey() {
|
|
|
|
StringRef N = DenseMapInfo<StringRef>::getTombstoneKey();
|
|
|
|
return {N, 0};
|
|
|
|
}
|
|
|
|
static unsigned getHashValue(lld::elf::SymName Name) { return Name.Hash; }
|
|
|
|
static bool isEqual(lld::elf::SymName A, lld::elf::SymName B) {
|
|
|
|
return A.Name == B.Name;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace lld {
|
|
|
|
namespace elf {
|
|
|
|
|
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
|
|
|
|
// to replace the lazy symbol. The logic is implemented in resolve().
|
2015-10-10 05:07:25 +08:00
|
|
|
template <class ELFT> class SymbolTable {
|
2016-03-15 07:16:09 +08:00
|
|
|
typedef typename ELFT::Sym Elf_Sym;
|
|
|
|
typedef typename ELFT::uint uintX_t;
|
2016-01-09 05:53:28 +08:00
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
public:
|
|
|
|
void addFile(std::unique_ptr<InputFile> File);
|
2016-02-13 04:54:57 +08:00
|
|
|
void addCombinedLtoObject();
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2016-04-15 03:17:16 +08:00
|
|
|
const llvm::MapVector<SymName, Symbol *> &getSymbols() const {
|
2015-08-14 21:07:05 +08:00
|
|
|
return Symtab;
|
|
|
|
}
|
|
|
|
|
2015-10-10 05:07:25 +08:00
|
|
|
const std::vector<std::unique_ptr<ObjectFile<ELFT>>> &getObjectFiles() const {
|
2015-09-04 02:56:20 +08:00
|
|
|
return ObjectFiles;
|
|
|
|
}
|
|
|
|
|
2015-10-10 05:07:25 +08:00
|
|
|
const std::vector<std::unique_ptr<SharedFile<ELFT>>> &getSharedFiles() const {
|
2015-09-09 03:43:27 +08:00
|
|
|
return SharedFiles;
|
|
|
|
}
|
|
|
|
|
2015-10-10 05:12:40 +08:00
|
|
|
SymbolBody *addUndefined(StringRef Name);
|
|
|
|
SymbolBody *addUndefinedOpt(StringRef Name);
|
2016-04-04 22:04:16 +08:00
|
|
|
DefinedRegular<ELFT> *addAbsolute(StringRef Name,
|
|
|
|
uint8_t Visibility = llvm::ELF::STV_HIDDEN);
|
2016-01-09 05:53:28 +08:00
|
|
|
SymbolBody *addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section,
|
2016-04-14 00:57:28 +08:00
|
|
|
uintX_t Value);
|
2016-04-04 22:04:16 +08:00
|
|
|
DefinedRegular<ELFT> *addIgnored(StringRef Name,
|
|
|
|
uint8_t Visibility = llvm::ELF::STV_HIDDEN);
|
2016-01-09 05:53:28 +08:00
|
|
|
|
2015-10-14 02:10:33 +08:00
|
|
|
void scanShlibUndefined();
|
2016-04-14 02:51:11 +08:00
|
|
|
void scanDynamicList();
|
ELF2: Implement --gc-sections.
Section garbage collection is a feature to remove unused sections
from outputs. Unused sections are sections that cannot be reachable
from known GC-root symbols or sections. Naturally the feature is
implemented as a mark-sweep garbage collector.
In this patch, I added Live bit to InputSectionBase. If and only
if Live bit is on, the section will be written to the output.
Starting from GC-root symbols or sections, a new function, markLive(),
visits all reachable sections and sets their Live bits. Writer then
ignores sections whose Live bit is off, so that such sections are
excluded from the output.
This change has small negative impact on performance if you use
the feature because making sections means more work. The time to
link Clang changes from 0.356s to 0.386s, or +8%.
It reduces Clang size from 57,764,984 bytes to 55,296,600 bytes.
That is 4.3% reduction.
http://reviews.llvm.org/D13950
llvm-svn: 251043
2015-10-23 02:49:53 +08:00
|
|
|
SymbolBody *find(StringRef Name);
|
2016-01-08 01:20:07 +08:00
|
|
|
void wrap(StringRef Name);
|
2016-02-27 05:49:38 +08:00
|
|
|
InputFile *findFile(SymbolBody *B);
|
2015-10-02 05:22:26 +08:00
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
private:
|
2015-09-05 06:28:10 +08:00
|
|
|
Symbol *insert(SymbolBody *New);
|
|
|
|
void addLazy(Lazy *New);
|
2016-04-06 21:22:41 +08:00
|
|
|
void addMemberFile(SymbolBody *Undef, Lazy *L);
|
2016-04-05 03:22:51 +08:00
|
|
|
void resolve(SymbolBody *Body);
|
2015-12-17 06:26:45 +08:00
|
|
|
std::string conflictMsg(SymbolBody *Old, SymbolBody *New);
|
2015-07-25 05:03:07 +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
|
|
|
|
// bit systems so we use a MapVector. That is arbitrary, deterministic but
|
|
|
|
// a bit inefficient.
|
|
|
|
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
|
|
|
|
// once symbol resolution is finished.
|
2016-04-15 03:17:16 +08:00
|
|
|
llvm::MapVector<SymName, Symbol *> Symtab;
|
2015-07-25 05:03:07 +08:00
|
|
|
llvm::BumpPtrAllocator Alloc;
|
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.
|
2016-01-06 10:06:33 +08:00
|
|
|
llvm::DenseSet<StringRef> ComdatGroups;
|
2015-10-10 03:25:07 +08:00
|
|
|
|
2016-01-09 06:20:00 +08:00
|
|
|
// The symbol table owns all file objects.
|
|
|
|
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
|
2015-10-10 05:07:25 +08:00
|
|
|
std::vector<std::unique_ptr<ObjectFile<ELFT>>> ObjectFiles;
|
2016-04-08 03:24:51 +08:00
|
|
|
std::vector<std::unique_ptr<LazyObjectFile>> LazyObjectFiles;
|
2015-10-10 05:07:25 +08:00
|
|
|
std::vector<std::unique_ptr<SharedFile<ELFT>>> SharedFiles;
|
2016-02-13 04:54:57 +08:00
|
|
|
std::vector<std::unique_ptr<BitcodeFile>> BitcodeFiles;
|
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
|
|
|
|
|
|
|
std::unique_ptr<BitcodeCompiler> Lto;
|
2015-07-25 05:03:07 +08:00
|
|
|
};
|
|
|
|
|
2016-02-28 08:25:54 +08:00
|
|
|
} // namespace elf
|
2015-07-25 05:03:07 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|