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"
|
2015-06-27 10:05:40 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/DenseMapInfo.h"
|
2015-05-29 03:09:30 +08:00
|
|
|
#include "llvm/Support/Allocator.h"
|
2015-06-27 02:58:24 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2015-09-20 11:11:16 +08:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
// <future> depends on <eh.h> for __uncaught_exception.
|
|
|
|
#include <eh.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <future>
|
|
|
|
|
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;
|
|
|
|
class Defined;
|
|
|
|
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
|
|
|
|
// to replace the lazy symbol. The logic is implemented in resolve().
|
|
|
|
class SymbolTable {
|
|
|
|
public:
|
2016-12-09 02:49:04 +08:00
|
|
|
void addFile(std::unique_ptr<InputFile> File);
|
|
|
|
std::vector<std::unique_ptr<InputFile>> &getFiles() { return Files; }
|
2015-08-06 22:58:50 +08:00
|
|
|
void step();
|
|
|
|
void run();
|
2015-07-02 10:38:59 +08:00
|
|
|
bool queueEmpty();
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2015-07-04 13:28:41 +08:00
|
|
|
// Print an error message on undefined symbols. If Resolve is true, try to
|
|
|
|
// resolve any undefined symbols and update the symbol table accordingly.
|
2015-08-06 22:58:50 +08:00
|
|
|
void reportRemainingUndefines(bool Resolve);
|
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.
|
|
|
|
void mangleMaybe(Undefined *U);
|
2015-07-14 10:58:13 +08:00
|
|
|
StringRef findMangle(StringRef Name);
|
2015-06-29 06:16:41 +08:00
|
|
|
|
2015-06-27 02:58:24 +08:00
|
|
|
// Print a layout map to OS.
|
|
|
|
void printMap(llvm::raw_ostream &OS);
|
|
|
|
|
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();
|
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.
|
2015-07-02 08:04:14 +08:00
|
|
|
Undefined *addUndefined(StringRef Name);
|
2015-07-25 07:51:14 +08:00
|
|
|
DefinedRelative *addRelative(StringRef Name, uint64_t VA);
|
|
|
|
DefinedAbsolute *addAbsolute(StringRef Name, uint64_t VA);
|
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:
|
2015-08-06 22:58:50 +08:00
|
|
|
void readArchives();
|
|
|
|
void readObjects();
|
COFF: Infer entry point as early as possible, but not too early.
On Windows, we have four different main functions, {w,}{main,WinMain}.
The linker has to choose a corresponding entry point function among
{w,}{main,WinMain}CRTStartup. These entry point functions are defined
in the standard library. The linker resolves one of them by looking at
which main function is defined and adding a corresponding undefined
symbol to the symbol table.
Object files containing entry point functions conflicts each other.
For example, we cannot resolve both mainCRTStartup and WinMainCRTStartup
because other symbols defined in the files conflict.
Previously, we inferred CRT function name at the very end of name
resolution. I found that that is sometimes too late. If the linker
already linked one of these four archive member objects, it's too late
to change the decision.
The right thing to do here is to infer entry point name after adding
all symbols from command line files and before adding any other files
(which are specified by directive sections). This patch does that.
llvm-svn: 241236
2015-07-02 11:15:15 +08:00
|
|
|
|
2015-08-06 22:58:50 +08:00
|
|
|
void addSymbol(SymbolBody *New);
|
2015-07-01 03:35:21 +08:00
|
|
|
void addLazy(Lazy *New, std::vector<Symbol *> *Accum);
|
2015-07-03 06:52:33 +08:00
|
|
|
Symbol *insert(SymbolBody *New);
|
2015-07-14 10:58:13 +08:00
|
|
|
StringRef findByPrefix(StringRef Prefix);
|
2015-07-01 03:35:21 +08:00
|
|
|
|
2015-08-06 22:58:50 +08:00
|
|
|
void addMemberFile(Lazy *Body);
|
2015-08-29 06:16:09 +08:00
|
|
|
void addCombinedLTOObject(ObjectFile *Obj);
|
|
|
|
std::vector<ObjectFile *> createLTOObjects(llvm::LTOCodeGenerator *CG);
|
2015-05-29 03:09:30 +08:00
|
|
|
|
2015-06-27 10:05:40 +08:00
|
|
|
llvm::DenseMap<StringRef, Symbol *> Symtab;
|
2015-07-01 03:35:21 +08:00
|
|
|
|
2016-12-09 02:49:04 +08:00
|
|
|
std::vector<std::unique_ptr<InputFile>> Files;
|
2015-09-20 11:11:16 +08:00
|
|
|
std::vector<std::future<ArchiveFile *>> ArchiveQueue;
|
|
|
|
std::vector<std::future<InputFile *>> ObjectQueue;
|
2015-07-01 03:35:21 +08:00
|
|
|
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<BitcodeFile *> BitcodeFiles;
|
2016-04-10 07:00:31 +08:00
|
|
|
std::vector<SmallString<0>> Objs;
|
2015-05-29 03:09:30 +08:00
|
|
|
llvm::BumpPtrAllocator Alloc;
|
|
|
|
};
|
|
|
|
|
2015-06-13 05:37:55 +08:00
|
|
|
} // namespace coff
|
2015-05-29 03:09:30 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|