blob: f70ba37605f085f9b3fb0ee5c72e7a86dae0e455 [file] [log] [blame]
Rui Ueyama411c63602015-05-28 19:09:30 +00001//===- SymbolTable.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Config.h"
11#include "Driver.h"
12#include "SymbolTable.h"
13#include "lld/Core/Error.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/Support/Debug.h"
16#include "llvm/Support/raw_ostream.h"
17
Rui Ueyamad68ff342015-05-31 03:57:30 +000018using namespace llvm;
19
Rui Ueyama411c63602015-05-28 19:09:30 +000020namespace lld {
21namespace coff {
22
23SymbolTable::SymbolTable() {
Rui Ueyama5cff6852015-05-31 03:34:08 +000024 addSymbol(new DefinedAbsolute("__ImageBase", Config->ImageBase));
25 if (!Config->EntryName.empty())
26 addSymbol(new Undefined(Config->EntryName));
Rui Ueyama411c63602015-05-28 19:09:30 +000027}
28
29std::error_code SymbolTable::addFile(std::unique_ptr<InputFile> File) {
30 if (auto EC = File->parse())
31 return EC;
32 InputFile *FileP = File.release();
33 if (auto *P = dyn_cast<ObjectFile>(FileP))
34 return addObject(P);
35 if (auto *P = dyn_cast<ArchiveFile>(FileP))
36 return addArchive(P);
37 return addImport(cast<ImportFile>(FileP));
38}
39
40std::error_code SymbolTable::addObject(ObjectFile *File) {
41 ObjectFiles.emplace_back(File);
42 for (SymbolBody *Body : File->getSymbols())
43 if (Body->isExternal())
44 if (auto EC = resolve(Body))
45 return EC;
46
47 // If an object file contains .drectve section, read it and add
48 // files listed in the section.
49 StringRef Dir = File->getDirectives();
50 if (!Dir.empty()) {
51 std::vector<std::unique_ptr<InputFile>> Libs;
52 if (auto EC = parseDirectives(Dir, &Libs, &StringAlloc))
53 return EC;
54 for (std::unique_ptr<InputFile> &Lib : Libs)
55 addFile(std::move(Lib));
56 }
57 return std::error_code();
58}
59
60std::error_code SymbolTable::addArchive(ArchiveFile *File) {
61 ArchiveFiles.emplace_back(File);
62 for (SymbolBody *Body : File->getSymbols())
63 if (auto EC = resolve(Body))
64 return EC;
65 return std::error_code();
66}
67
68std::error_code SymbolTable::addImport(ImportFile *File) {
69 ImportFiles.emplace_back(File);
70 for (SymbolBody *Body : File->getSymbols())
71 if (auto EC = resolve(Body))
72 return EC;
73 return std::error_code();
74}
75
76bool SymbolTable::reportRemainingUndefines() {
77 bool Ret = false;
78 for (auto &I : Symtab) {
79 Symbol *Sym = I.second;
80 auto *Undef = dyn_cast<Undefined>(Sym->Body);
81 if (!Undef)
82 continue;
83 if (SymbolBody *Alias = Undef->getWeakAlias()) {
84 Sym->Body = Alias->getReplacement();
85 if (!isa<Defined>(Sym->Body)) {
86 // Aliases are yet another symbols pointed by other symbols
87 // that could also remain undefined.
88 llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
89 Ret = true;
90 }
91 continue;
92 }
93 llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
94 Ret = true;
95 }
96 return Ret;
97}
98
99// This function resolves conflicts if there's an existing symbol with
100// the same name. Decisions are made based on symbol type.
101std::error_code SymbolTable::resolve(SymbolBody *New) {
102 // Find an existing Symbol or create and insert a new one.
103 StringRef Name = New->getName();
104 Symbol *&Sym = Symtab[Name];
105 if (!Sym) {
106 Sym = new (Alloc) Symbol(New);
107 New->setBackref(Sym);
108 return std::error_code();
109 }
110 New->setBackref(Sym);
111
112 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
113 // equivalent (conflicting), or more preferable, respectively.
114 SymbolBody *Existing = Sym->Body;
115 int comp = Existing->compare(New);
116 if (comp < 0)
117 Sym->Body = New;
118 if (comp == 0)
119 return make_dynamic_error_code(Twine("duplicate symbol: ") + Name);
120
121 // If we have an Undefined symbol for a Lazy symbol, we need
122 // to read an archive member to replace the Lazy symbol with
123 // a Defined symbol.
124 if (isa<Undefined>(Existing) || isa<Undefined>(New))
125 if (auto *B = dyn_cast<Lazy>(Sym->Body))
126 return addMemberFile(B);
127 return std::error_code();
128}
129
130// Reads an archive member file pointed by a given symbol.
131std::error_code SymbolTable::addMemberFile(Lazy *Body) {
132 auto FileOrErr = Body->getMember();
133 if (auto EC = FileOrErr.getError())
134 return EC;
135 std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
136
137 // getMember returns an empty buffer if the member was already
138 // read from the library.
139 if (!File)
140 return std::error_code();
141 if (Config->Verbose)
142 llvm::dbgs() << "Loaded " << File->getShortName() << " for "
143 << Body->getName() << "\n";
144 return addFile(std::move(File));
145}
146
147std::vector<Chunk *> SymbolTable::getChunks() {
148 std::vector<Chunk *> Res;
149 for (std::unique_ptr<ObjectFile> &File : ObjectFiles) {
150 std::vector<Chunk *> &V = File->getChunks();
151 Res.insert(Res.end(), V.begin(), V.end());
152 }
153 return Res;
154}
155
Rui Ueyama5cff6852015-05-31 03:34:08 +0000156Defined *SymbolTable::find(StringRef Name) {
Rui Ueyama411c63602015-05-28 19:09:30 +0000157 auto It = Symtab.find(Name);
158 if (It == Symtab.end())
159 return nullptr;
Rui Ueyama5cff6852015-05-31 03:34:08 +0000160 if (auto *Def = dyn_cast<Defined>(It->second->Body))
161 return Def;
162 return nullptr;
163}
164
165// Link default entry point name.
166ErrorOr<StringRef> SymbolTable::findDefaultEntry() {
167 static const char *Entries[][2] = {
168 {"mainCRTStartup", "mainCRTStartup"},
169 {"wmainCRTStartup", "wmainCRTStartup"},
170 {"WinMainCRTStartup", "WinMainCRTStartup"},
171 {"wWinMainCRTStartup", "wWinMainCRTStartup"},
172 {"main", "mainCRTStartup"},
173 {"wmain", "wmainCRTStartup"},
174 {"WinMain", "WinMainCRTStartup"},
175 {"wWinMain", "wWinMainCRTStartup"},
176 };
Rui Ueyamad68ff342015-05-31 03:57:30 +0000177 for (size_t I = 0; I < array_lengthof(Entries); ++I) {
Rui Ueyama5cff6852015-05-31 03:34:08 +0000178 if (!find(Entries[I][0]))
179 continue;
180 if (auto EC = addSymbol(new Undefined(Entries[I][1])))
181 return EC;
182 return StringRef(Entries[I][1]);
183 }
184 return make_dynamic_error_code("entry point must be defined");
185}
186
187std::error_code SymbolTable::addSymbol(SymbolBody *Body) {
188 OwningSymbols.push_back(std::unique_ptr<SymbolBody>(Body));
189 return resolve(Body);
Rui Ueyama411c63602015-05-28 19:09:30 +0000190}
191
192void SymbolTable::dump() {
193 for (auto &P : Symtab) {
194 Symbol *Ref = P.second;
195 if (auto *Body = dyn_cast<Defined>(Ref->Body))
196 llvm::dbgs() << Twine::utohexstr(Config->ImageBase + Body->getRVA())
197 << " " << Body->getName() << "\n";
198 }
199}
200
201} // namespace coff
202} // namespace lld