2015-08-14 22:12:54 +08:00
|
|
|
//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
|
2015-05-29 03:09:30 +08:00
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLD_COFF_SYMBOL_TABLE_H
|
|
|
|
#define LLD_COFF_SYMBOL_TABLE_H
|
|
|
|
|
|
|
|
#include "InputFiles.h"
|
2017-02-03 07:58:14 +08:00
|
|
|
#include "LTO.h"
|
2016-12-12 06:15:30 +08:00
|
|
|
#include "llvm/ADT/CachedHashString.h"
|
2015-06-27 10:05:40 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/DenseMapInfo.h"
|
2015-06-27 02:58:24 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2015-06-10 01:52:17 +08:00
|
|
|
namespace llvm {
|
|
|
|
struct LTOCodeGenerator;
|
|
|
|
}
|
|
|
|
|
2015-05-29 03:09:30 +08:00
|
|
|
namespace lld {
|
|
|
|
namespace coff {
|
|
|
|
|
2015-06-30 02:50:11 +08:00
|
|
|
class Chunk;
|
2016-12-10 05:55:24 +08:00
|
|
|
class CommonChunk;
|
2015-06-30 02:50:11 +08:00
|
|
|
class Defined;
|
2016-12-09 04:20:22 +08:00
|
|
|
class DefinedAbsolute;
|
|
|
|
class DefinedRelative;
|
2015-06-30 02:50:11 +08:00
|
|
|
class Lazy;
|
2016-11-22 01:22:35 +08:00
|
|
|
class SectionChunk;
|
2015-06-30 02:50:11 +08:00
|
|
|
class SymbolBody;
|
|
|
|
struct Symbol;
|
|
|
|
|
2015-05-29 03:09:30 +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
|
2016-12-10 05:55:24 +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.
|
2015-05-29 03:09:30 +08:00
|
|
|
class SymbolTable {
|
|
|
|
public:
|
2016-12-09 04:20:22 +08:00
|
|
|
void addFile(InputFile *File);
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2016-12-10 05:55:24 +08:00
|
|
|
// Try to resolve any undefined symbols and update the symbol table
|
|
|
|
// accordingly, then print an error message for any remaining undefined
|
|
|
|
// symbols.
|
|
|
|
void reportRemainingUndefines();
|
2015-05-29 03:09:30 +08:00
|
|
|
|
|
|
|
// Returns a list of chunks of selected symbols.
|
|
|
|
std::vector<Chunk *> getChunks();
|
|
|
|
|
2015-07-02 11:59:04 +08:00
|
|
|
// Returns a symbol for a given name. Returns a nullptr if not found.
|
|
|
|
Symbol *find(StringRef Name);
|
2015-07-29 06:56:02 +08:00
|
|
|
Symbol *findUnderscore(StringRef Name);
|
2015-05-31 11:34:08 +08:00
|
|
|
|
2015-07-02 08:04:14 +08:00
|
|
|
// Occasionally we have to resolve an undefined symbol to its
|
|
|
|
// mangled symbol. This function tries to find a mangled name
|
|
|
|
// for U from the symbol table, and if found, set the symbol as
|
|
|
|
// a weak alias for U.
|
2016-12-10 05:55:24 +08:00
|
|
|
void mangleMaybe(SymbolBody *B);
|
2015-07-14 10:58:13 +08:00
|
|
|
StringRef findMangle(StringRef Name);
|
2015-06-29 06:16:41 +08:00
|
|
|
|
2015-08-29 06:16:09 +08:00
|
|
|
// Build a set of COFF objects representing the combined contents of
|
|
|
|
// BitcodeFiles and add them to the symbol table. Called after all files are
|
|
|
|
// added and before the writer writes results to a file.
|
|
|
|
void addCombinedLTOObjects();
|
2017-02-07 04:47:55 +08:00
|
|
|
std::vector<StringRef> compileBitcodeFiles();
|
2015-06-02 04:10:10 +08:00
|
|
|
|
2015-05-29 03:09:30 +08:00
|
|
|
// The writer needs to handle DLL import libraries specially in
|
|
|
|
// order to create the import descriptor table.
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<ImportFile *> ImportFiles;
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2015-05-30 05:47:36 +08:00
|
|
|
// The writer needs to infer the machine type from the object files.
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<ObjectFile *> ObjectFiles;
|
2015-05-30 05:47:36 +08:00
|
|
|
|
2015-06-01 03:55:40 +08:00
|
|
|
// Creates an Undefined symbol for a given name.
|
2016-12-10 05:55:24 +08:00
|
|
|
SymbolBody *addUndefined(StringRef Name);
|
|
|
|
|
[COFF] Improve synthetic symbol handling
Summary:
The main change is that we can have SECREL and SECTION relocations
against ___safe_se_handler_table, which is important for handling the
debug info in the MSVCRT.
Previously we were using DefinedRelative for __safe_se_handler_table and
__ImageBase, and after we implement CFGuard, we plan to extend it to
handle __guard_fids_table, __guard_longjmp_table, and more. However,
DefinedRelative is really only suitable for implementing __ImageBase,
because it lacks a Chunk, which you need in order to figure out the
output section index and output section offset when resolving SECREl and
SECTION relocations.
This change renames DefinedRelative to DefinedSynthetic and gives it a
Chunk. One wart is that __ImageBase doesn't have a chunk. It points to
the PE header, effectively. We could split DefinedRelative and
DefinedSynthetic if we think that's cleaner and creates fewer special
cases.
I also added safeseh.s, which checks that we don't emit a safe seh table
entries pointing to garbage collected handlers and that we don't emit a
table at all when there are no handlers.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: inglorion, pcc, llvm-commits, aprantl
Differential Revision: https://reviews.llvm.org/D34577
llvm-svn: 306293
2017-06-26 23:39:52 +08:00
|
|
|
Symbol *addSynthetic(StringRef N, Chunk *C);
|
2016-12-10 05:55:24 +08:00
|
|
|
Symbol *addAbsolute(StringRef N, uint64_t VA);
|
|
|
|
|
|
|
|
Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
|
|
|
|
void addLazy(ArchiveFile *F, const Archive::Symbol Sym);
|
|
|
|
Symbol *addAbsolute(StringRef N, COFFSymbolRef S);
|
2017-02-03 07:58:14 +08:00
|
|
|
Symbol *addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
|
|
|
|
const llvm::object::coff_symbol_generic *S = nullptr,
|
|
|
|
SectionChunk *C = nullptr);
|
|
|
|
Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
|
|
|
|
const llvm::object::coff_symbol_generic *S = nullptr,
|
|
|
|
CommonChunk *C = nullptr);
|
2016-12-10 05:55:24 +08:00
|
|
|
Symbol *addImportData(StringRef N, ImportFile *F);
|
|
|
|
Symbol *addImportThunk(StringRef Name, DefinedImportData *S,
|
|
|
|
uint16_t Machine);
|
|
|
|
|
|
|
|
void reportDuplicate(Symbol *Existing, InputFile *NewFile);
|
2015-06-01 03:55:40 +08:00
|
|
|
|
2015-06-25 11:31:47 +08:00
|
|
|
// A list of chunks which to be added to .rdata.
|
|
|
|
std::vector<Chunk *> LocalImportChunks;
|
|
|
|
|
2015-05-29 03:09:30 +08:00
|
|
|
private:
|
2016-12-10 05:55:24 +08:00
|
|
|
std::pair<Symbol *, bool> insert(StringRef Name);
|
2015-07-14 10:58:13 +08:00
|
|
|
StringRef findByPrefix(StringRef Prefix);
|
2015-07-01 03:35:21 +08:00
|
|
|
|
2016-12-12 06:15:30 +08:00
|
|
|
llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> Symtab;
|
2015-07-01 03:35:21 +08:00
|
|
|
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<BitcodeFile *> BitcodeFiles;
|
2017-02-03 07:58:14 +08:00
|
|
|
std::unique_ptr<BitcodeCompiler> LTO;
|
2015-05-29 03:09:30 +08:00
|
|
|
};
|
|
|
|
|
2016-12-10 05:55:24 +08:00
|
|
|
extern SymbolTable *Symtab;
|
|
|
|
|
2015-06-13 05:37:55 +08:00
|
|
|
} // namespace coff
|
2015-05-29 03:09:30 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|