blob: 11c9e06a41e033975ea566cb899daf15a44ebc20 [file] [log] [blame]
Michael J. Spencer773a8fb2011-12-18 08:27:59 +00001//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===//
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 "lld/Core/SymbolTable.h"
Nick Kledzik6bc04c62012-02-22 21:56:59 +000011#include "lld/Core/AbsoluteAtom.h"
Michael J. Spencer4586fbc2013-01-22 20:49:42 +000012#include "lld/Core/Atom.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000013#include "lld/Core/DefinedAtom.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000014#include "lld/Core/File.h"
Michael J. Spencere6203a52012-04-03 18:39:40 +000015#include "lld/Core/LLVM.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000016#include "lld/Core/Resolver.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000017#include "lld/Core/SharedLibraryAtom.h"
Rui Ueyama0ca149f2013-08-06 22:31:59 +000018#include "lld/Core/LinkingContext.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000019#include "lld/Core/UndefinedAtom.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000020
Nick Kledzikbfedfc12012-01-09 20:18:15 +000021#include "llvm/ADT/ArrayRef.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000022#include "llvm/ADT/DenseMapInfo.h"
Michael J. Spencer67f25272013-03-20 22:18:22 +000023#include "llvm/ADT/Hashing.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000024#include "llvm/Support/ErrorHandling.h"
Nick Kledzikbb963df2012-04-18 21:55:06 +000025#include "llvm/Support/raw_ostream.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000026
27#include <algorithm>
28#include <cassert>
Michael J. Spencercfd029f2012-03-28 19:04:02 +000029#include <cstdlib>
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000030#include <vector>
31
32namespace lld {
Rui Ueyama0ca149f2013-08-06 22:31:59 +000033SymbolTable::SymbolTable(const LinkingContext &context) : _context(context) {}
Nick Kledzik38eec3d2011-12-22 02:38:01 +000034
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000035void SymbolTable::add(const UndefinedAtom &atom) { addByName(atom); }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000036
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000037void SymbolTable::add(const SharedLibraryAtom &atom) { addByName(atom); }
Michael J. Spencer765792d2012-04-03 18:40:27 +000038
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000039void SymbolTable::add(const AbsoluteAtom &atom) { addByName(atom); }
Nick Kledzik6bc04c62012-02-22 21:56:59 +000040
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000041void SymbolTable::add(const DefinedAtom &atom) {
Shankar Easwaran8962feb2013-03-14 16:09:49 +000042 if (!atom.name().empty() &&
Rui Ueyama8b08c372013-11-25 17:09:29 +000043 atom.scope() != DefinedAtom::scopeTranslationUnit) {
Nick Kledzik233f5372013-01-15 00:17:57 +000044 // Named atoms cannot be merged by content.
45 assert(atom.merge() != DefinedAtom::mergeByContent);
46 // Track named atoms that are not scoped to file (static).
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000047 addByName(atom);
Rui Ueyama8b08c372013-11-25 17:09:29 +000048 return;
49 }
50 if (atom.merge() == DefinedAtom::mergeByContent) {
Nick Kledzik233f5372013-01-15 00:17:57 +000051 // Named atoms cannot be merged by content.
52 assert(atom.name().empty());
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000053 addByContent(atom);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000054 }
55}
56
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000057const Atom *SymbolTable::findGroup(StringRef sym) {
58 NameToAtom::iterator pos = _groupTable.find(sym);
59 if (pos == _groupTable.end())
60 return nullptr;
61 return pos->second;
62}
63
64bool SymbolTable::addGroup(const DefinedAtom &da) {
65 StringRef name = da.name();
66 assert(!name.empty());
67 const Atom *existing = findGroup(name);
68 if (existing == nullptr) {
69 _groupTable[name] = &da;
70 return true;
71 }
72 _replacedAtoms[&da] = existing;
73 return false;
74}
75
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000076enum NameCollisionResolution {
77 NCR_First,
78 NCR_Second,
Nick Kledzik6bc04c62012-02-22 21:56:59 +000079 NCR_DupDef,
80 NCR_DupUndef,
81 NCR_DupShLib,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000082 NCR_Error
83};
84
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000085static NameCollisionResolution cases[4][4] = {
86 //regular absolute undef sharedLib
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000087 {
88 // first is regular
Nick Kledzik6bc04c62012-02-22 21:56:59 +000089 NCR_DupDef, NCR_Error, NCR_First, NCR_First
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000090 },
91 {
92 // first is absolute
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000093 NCR_Error, NCR_Error, NCR_First, NCR_First
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000094 },
95 {
96 // first is undef
Nick Kledzik6bc04c62012-02-22 21:56:59 +000097 NCR_Second, NCR_Second, NCR_DupUndef, NCR_Second
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000098 },
99 {
100 // first is sharedLib
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000101 NCR_Second, NCR_Second, NCR_First, NCR_DupShLib
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000102 }
103};
104
105static NameCollisionResolution collide(Atom::Definition first,
106 Atom::Definition second) {
107 return cases[first][second];
108}
109
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000110enum MergeResolution {
111 MCR_First,
112 MCR_Second,
113 MCR_Largest,
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000114 MCR_SameSize,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000115 MCR_Error
116};
117
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000118static MergeResolution mergeCases[][6] = {
119 // no tentative weak weakAddress sameNameAndSize largest
120 {MCR_Error, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // no
121 {MCR_Second, MCR_Largest, MCR_Second, MCR_Second, MCR_SameSize, MCR_Largest}, // tentative
122 {MCR_Second, MCR_First, MCR_First, MCR_Second, MCR_SameSize, MCR_Largest}, // weak
123 {MCR_Second, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // weakAddress
124 {MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize}, // sameSize
125 {MCR_Largest, MCR_Largest, MCR_Largest, MCR_Largest, MCR_SameSize, MCR_Largest}, // largest
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000126};
127
Michael J. Spencer765792d2012-04-03 18:40:27 +0000128static MergeResolution mergeSelect(DefinedAtom::Merge first,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000129 DefinedAtom::Merge second) {
Rui Ueyama7caea312014-03-08 00:44:01 +0000130 assert(first != DefinedAtom::mergeByContent);
131 assert(second != DefinedAtom::mergeByContent);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000132 return mergeCases[first][second];
133}
134
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000135static uint64_t getSizeFollowReferences(const DefinedAtom *atom, uint32_t kind) {
136 uint64_t size = 0;
137redo:
138 while (atom) {
139 for (const Reference *r : *atom) {
140 if (r->kindNamespace() == Reference::KindNamespace::all &&
141 r->kindArch() == Reference::KindArch::all &&
142 r->kindValue() == kind) {
143 atom = cast<DefinedAtom>(r->target());
144 size += atom->size();
145 goto redo;
146 }
147 }
148 break;
149 }
150 return size;
151}
152
153// Returns the size of the section containing the given atom. Atoms in the same
154// section are connected by layout-before and layout-after edges, so this
155// function traverses them to get the total size of atoms in the same section.
156static uint64_t sectionSize(const DefinedAtom *atom) {
157 return atom->size()
158 + getSizeFollowReferences(atom, lld::Reference::kindLayoutBefore)
159 + getSizeFollowReferences(atom, lld::Reference::kindLayoutAfter);
160}
161
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000162void SymbolTable::addByName(const Atom &newAtom) {
Michael J. Spencere6203a52012-04-03 18:39:40 +0000163 StringRef name = newAtom.name();
Nick Kledzik233f5372013-01-15 00:17:57 +0000164 assert(!name.empty());
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +0000165 const Atom *existing = findByName(name);
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000166 if (existing == nullptr) {
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000167 // Name is not in symbol table yet, add it associate with this atom.
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000168 _nameTable[name] = &newAtom;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000169 return;
Michael J. Spencer765792d2012-04-03 18:40:27 +0000170 }
Rui Ueyamaf347e752013-11-13 23:22:00 +0000171
172 // Name is already in symbol table and associated with another atom.
173 bool useNew = true;
174 switch (collide(existing->definition(), newAtom.definition())) {
175 case NCR_First:
176 useNew = false;
177 break;
178 case NCR_Second:
179 useNew = true;
180 break;
181 case NCR_DupDef:
182 assert(existing->definition() == Atom::definitionRegular);
183 assert(newAtom.definition() == Atom::definitionRegular);
184 switch (mergeSelect(((DefinedAtom*)existing)->merge(),
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000185 ((DefinedAtom*)&newAtom)->merge())) {
Rui Ueyama5a3804f2013-11-25 17:09:25 +0000186 case MCR_First:
187 useNew = false;
188 break;
189 case MCR_Second:
190 useNew = true;
191 break;
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000192 case MCR_Largest: {
193 uint64_t existingSize = sectionSize((DefinedAtom*)existing);
194 uint64_t newSize = sectionSize((DefinedAtom*)&newAtom);
195 useNew = (newSize >= existingSize);
Rui Ueyama5a3804f2013-11-25 17:09:25 +0000196 break;
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000197 }
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000198 case MCR_SameSize: {
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000199 uint64_t existingSize = sectionSize((DefinedAtom*)existing);
200 uint64_t newSize = sectionSize((DefinedAtom*)&newAtom);
201 if (existingSize == newSize) {
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000202 useNew = true;
203 break;
204 }
205 llvm::errs() << "Size mismatch: "
Rui Ueyama7ad72eb2014-03-18 19:37:50 +0000206 << existing->name() << " (" << existingSize << ") "
207 << newAtom.name() << " (" << newSize << ")\n";
Rui Ueyamac79dd2f2014-03-07 23:05:10 +0000208 // fallthrough
209 }
Rui Ueyama5a3804f2013-11-25 17:09:25 +0000210 case MCR_Error:
Rui Ueyamaa9a51292014-03-28 16:26:38 +0000211 if (!_context.getAllowDuplicates()) {
212 llvm::errs() << "Duplicate symbols: "
213 << existing->name()
214 << ":"
215 << existing->file().path()
216 << " and "
217 << newAtom.name()
218 << ":"
219 << newAtom.file().path()
220 << "\n";
221 llvm::report_fatal_error("duplicate symbol error");
222 }
223 useNew = false;
Rui Ueyama5a3804f2013-11-25 17:09:25 +0000224 break;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000225 }
226 break;
227 case NCR_DupUndef: {
Rui Ueyamab4dca7f2013-11-15 03:12:24 +0000228 const UndefinedAtom* existingUndef = dyn_cast<UndefinedAtom>(existing);
229 const UndefinedAtom* newUndef = dyn_cast<UndefinedAtom>(&newAtom);
230 assert(existingUndef != nullptr);
231 assert(newUndef != nullptr);
232
233 bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull());
234 if (!sameCanBeNull &&
235 _context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
236 llvm::errs() << "lld warning: undefined symbol "
237 << existingUndef->name()
238 << " has different weakness in "
239 << existingUndef->file().path()
240 << " and in " << newUndef->file().path() << "\n";
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000241 }
Rui Ueyamab4dca7f2013-11-15 03:12:24 +0000242
243 const UndefinedAtom *existingFallback = existingUndef->fallback();
244 const UndefinedAtom *newFallback = newUndef->fallback();
245 bool hasDifferentFallback =
246 (existingFallback && newFallback &&
247 existingFallback->name() != newFallback->name());
248 if (hasDifferentFallback) {
249 llvm::errs() << "lld warning: undefined symbol "
250 << existingUndef->name() << " has different fallback: "
251 << existingFallback->name() << " in "
252 << existingUndef->file().path() << " and "
253 << newFallback->name() << " in "
254 << newUndef->file().path() << "\n";
255 }
256
257 bool hasNewFallback = newUndef->fallback();
258 if (sameCanBeNull)
259 useNew = hasNewFallback;
260 else
261 useNew = (newUndef->canBeNull() < existingUndef->canBeNull());
Rui Ueyamaf347e752013-11-13 23:22:00 +0000262 break;
Rui Ueyamab4dca7f2013-11-15 03:12:24 +0000263 }
Rui Ueyamaf347e752013-11-13 23:22:00 +0000264 case NCR_DupShLib: {
265 const SharedLibraryAtom* curShLib =
266 dyn_cast<SharedLibraryAtom>(existing);
267 const SharedLibraryAtom* newShLib =
268 dyn_cast<SharedLibraryAtom>(&newAtom);
269 assert(curShLib != nullptr);
270 assert(newShLib != nullptr);
271 bool sameNullness = (curShLib->canBeNullAtRuntime()
272 == newShLib->canBeNullAtRuntime());
273 bool sameName = curShLib->loadName().equals(newShLib->loadName());
274 if (!sameName) {
275 useNew = false;
276 if (_context.warnIfCoalesableAtomsHaveDifferentLoadName()) {
277 // FIXME: need diagonstics interface for writing warning messages
278 llvm::errs() << "lld warning: shared library symbol "
279 << curShLib->name()
280 << " has different load path in "
281 << curShLib->file().path()
282 << " and in "
283 << newShLib->file().path();
284 }
285 } else if (!sameNullness) {
286 useNew = false;
287 if (_context.warnIfCoalesableAtomsHaveDifferentCanBeNull()) {
288 // FIXME: need diagonstics interface for writing warning messages
289 llvm::errs() << "lld warning: shared library symbol "
290 << curShLib->name()
291 << " has different weakness in "
292 << curShLib->file().path()
293 << " and in "
294 << newShLib->file().path();
295 }
296 } else {
297 // Both shlib atoms are identical and can be coalesced.
298 useNew = false;
299 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000300 }
Rui Ueyamaf347e752013-11-13 23:22:00 +0000301 break;
Rui Ueyamabcccb5d2013-11-13 23:23:38 +0000302 case NCR_Error:
303 llvm::errs() << "SymbolTable: error while merging " << name << "\n";
Rui Ueyama9310e012013-11-14 06:39:31 +0000304 llvm::report_fatal_error("duplicate symbol error");
305 break;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000306 }
Rui Ueyamabcccb5d2013-11-13 23:23:38 +0000307
Rui Ueyamaf347e752013-11-13 23:22:00 +0000308 if (useNew) {
309 // Update name table to use new atom.
310 _nameTable[name] = &newAtom;
311 // Add existing atom to replacement table.
312 _replacedAtoms[existing] = &newAtom;
313 } else {
314 // New atom is not being used. Add it to replacement table.
315 _replacedAtoms[&newAtom] = existing;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000316 }
317}
318
Michael J. Spencer67f25272013-03-20 22:18:22 +0000319unsigned SymbolTable::AtomMappingInfo::getHashValue(const DefinedAtom *atom) {
320 auto content = atom->rawContent();
321 return llvm::hash_combine(atom->size(),
322 atom->contentType(),
323 llvm::hash_combine_range(content.begin(),
324 content.end()));
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000325}
326
Michael J. Spencer765792d2012-04-03 18:40:27 +0000327bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l,
Michael J. Spencer67f25272013-03-20 22:18:22 +0000328 const DefinedAtom * const r) {
Rui Ueyamaf347e752013-11-13 23:22:00 +0000329 if (l == r)
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000330 return true;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000331 if (l == getEmptyKey())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000332 return false;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000333 if (r == getEmptyKey())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000334 return false;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000335 if (l == getTombstoneKey())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000336 return false;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000337 if (r == getTombstoneKey())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000338 return false;
Michael J. Spencere6203a52012-04-03 18:39:40 +0000339
Rui Ueyamaf347e752013-11-13 23:22:00 +0000340 if (l->contentType() != r->contentType())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000341 return false;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000342 if (l->size() != r->size())
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000343 return false;
Michael J. Spencere6203a52012-04-03 18:39:40 +0000344 ArrayRef<uint8_t> lc = l->rawContent();
345 ArrayRef<uint8_t> rc = r->rawContent();
Michael J. Spencer67f25272013-03-20 22:18:22 +0000346 return memcmp(lc.data(), rc.data(), lc.size()) == 0;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000347}
348
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000349void SymbolTable::addByContent(const DefinedAtom & newAtom) {
Nick Kledzik233f5372013-01-15 00:17:57 +0000350 // Currently only read-only constants can be merged.
351 assert(newAtom.permissions() == DefinedAtom::permR__);
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000352 AtomContentSet::iterator pos = _contentTable.find(&newAtom);
Rui Ueyamaf347e752013-11-13 23:22:00 +0000353 if (pos == _contentTable.end()) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000354 _contentTable.insert(&newAtom);
355 return;
356 }
357 const Atom* existing = *pos;
Rui Ueyamaf347e752013-11-13 23:22:00 +0000358 // New atom is not being used. Add it to replacement table.
359 _replacedAtoms[&newAtom] = existing;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000360}
361
Michael J. Spencere6203a52012-04-03 18:39:40 +0000362const Atom *SymbolTable::findByName(StringRef sym) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000363 NameToAtom::iterator pos = _nameTable.find(sym);
364 if (pos == _nameTable.end())
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000365 return nullptr;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000366 return pos->second;
367}
368
Michael J. Spencere6203a52012-04-03 18:39:40 +0000369bool SymbolTable::isDefined(StringRef sym) {
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +0000370 const Atom *atom = findByName(sym);
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000371 if (atom == nullptr)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000372 return false;
Rui Ueyama69c71cc2013-11-18 22:42:03 +0000373 return atom->definition() != Atom::definitionUndefined;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000374}
375
Rui Ueyamae5416ec2013-09-12 19:14:05 +0000376void SymbolTable::addReplacement(const Atom *replaced,
377 const Atom *replacement) {
378 _replacedAtoms[replaced] = replacement;
379}
380
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000381const Atom *SymbolTable::replacement(const Atom *atom) {
382 AtomToAtom::iterator pos = _replacedAtoms.find(atom);
383 if (pos == _replacedAtoms.end())
384 return atom;
385 // might be chain, recurse to end
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +0000386 return replacement(pos->second);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000387}
388
389unsigned int SymbolTable::size() {
390 return _nameTable.size();
391}
392
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000393void SymbolTable::undefines(std::vector<const UndefinedAtom *> &undefs) {
Rui Ueyama17e899c2013-11-25 17:09:27 +0000394 for (auto it : _nameTable) {
395 const Atom *atom = it.second;
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000396 assert(atom != nullptr);
Rui Ueyamae5416ec2013-09-12 19:14:05 +0000397 if (const auto undef = dyn_cast<const UndefinedAtom>(atom)) {
398 AtomToAtom::iterator pos = _replacedAtoms.find(undef);
399 if (pos != _replacedAtoms.end())
400 continue;
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000401 undefs.push_back(undef);
Rui Ueyamae5416ec2013-09-12 19:14:05 +0000402 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000403 }
404}
405
Nick Kledzik20e652d2012-04-20 01:24:37 +0000406void SymbolTable::tentativeDefinitions(std::vector<StringRef> &names) {
407 for (auto entry : _nameTable) {
408 const Atom *atom = entry.second;
409 StringRef name = entry.first;
410 assert(atom != nullptr);
Rui Ueyamaf347e752013-11-13 23:22:00 +0000411 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom))
412 if (defAtom->merge() == DefinedAtom::mergeAsTentative)
Nick Kledzik20e652d2012-04-20 01:24:37 +0000413 names.push_back(name);
Nick Kledzik20e652d2012-04-20 01:24:37 +0000414 }
415}
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000416} // namespace lld