2015-05-29 03:09:30 +08:00
|
|
|
//===- SymbolTable.h ------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// 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-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;
|
|
|
|
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:
|
2015-06-24 07:56:39 +08:00
|
|
|
void addFile(std::unique_ptr<InputFile> File);
|
2015-07-10 03:54:13 +08:00
|
|
|
std::vector<std::unique_ptr<InputFile>> &getFiles() { return Files; }
|
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
|
|
|
std::error_code step();
|
2015-06-24 07:56:39 +08:00
|
|
|
std::error_code 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.
|
|
|
|
bool 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-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-06-02 04:10:10 +08:00
|
|
|
// Build a COFF object representing the combined contents of BitcodeFiles
|
|
|
|
// and add it to the symbol table. Called after all files are added and
|
|
|
|
// before the writer writes results to a file.
|
|
|
|
std::error_code addCombinedLTOObject();
|
|
|
|
|
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:
|
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
|
|
|
std::error_code readArchives();
|
|
|
|
std::error_code readObjects();
|
|
|
|
|
2015-07-01 03:35:21 +08:00
|
|
|
std::error_code addSymbol(SymbolBody *New);
|
|
|
|
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-05-29 03:09:30 +08:00
|
|
|
std::error_code addMemberFile(Lazy *Body);
|
2015-06-10 01:52:17 +08:00
|
|
|
ErrorOr<ObjectFile *> createLTOObject(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
|
|
|
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<std::unique_ptr<InputFile>> Files;
|
2015-07-01 03:35:21 +08:00
|
|
|
std::vector<ArchiveFile *> ArchiveQueue;
|
|
|
|
std::vector<InputFile *> ObjectQueue;
|
|
|
|
|
2015-06-24 07:56:39 +08:00
|
|
|
std::vector<BitcodeFile *> BitcodeFiles;
|
2015-06-10 01:52:17 +08:00
|
|
|
std::unique_ptr<MemoryBuffer> LTOMB;
|
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
|