blob: 8e94929340f72f3898a9a296342113494bbe53c5 [file] [log] [blame]
Michael J. Spencer773a8fb2011-12-18 08:27:59 +00001//===- Core/Resolver.cpp - Resolves Atom References -----------------------===//
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
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000010#include "lld/Core/Atom.h"
11#include "lld/Core/File.h"
12#include "lld/Core/InputFiles.h"
Michael J. Spencere6203a52012-04-03 18:39:40 +000013#include "lld/Core/LLVM.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000014#include "lld/Core/Resolver.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000015#include "lld/Core/SymbolTable.h"
Michael J. Spencer4586fbc2013-01-22 20:49:42 +000016#include "lld/Core/TargetInfo.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000017#include "lld/Core/UndefinedAtom.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000018
Nick Kledzikabb69812012-05-31 22:34:00 +000019#include "llvm/Support/Debug.h"
Michael J. Spencer4586fbc2013-01-22 20:49:42 +000020#include "llvm/Support/ErrorHandling.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000021#include "llvm/Support/Format.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000022#include "llvm/Support/raw_ostream.h"
23
24#include <algorithm>
25#include <cassert>
26#include <vector>
27
28namespace lld {
29
Michael J. Spencer765792d2012-04-03 18:40:27 +000030/// This is used as a filter function to std::remove_if to dead strip atoms.
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000031class NotLive {
32public:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000033 NotLive(const llvm::DenseSet<const Atom*>& la) : _liveAtoms(la) { }
Michael J. Spencer765792d2012-04-03 18:40:27 +000034
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000035 bool operator()(const Atom *atom) const {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000036 // don't remove if live
37 if ( _liveAtoms.count(atom) )
38 return false;
Nick Kledzik23384e82012-02-07 02:59:54 +000039 // don't remove if marked never-dead-strip
Michael J. Spencere6203a52012-04-03 18:39:40 +000040 if (const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom)) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000041 if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
42 return false;
43 }
44 // do remove this atom
45 return true;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000046 }
Michael J. Spencer765792d2012-04-03 18:40:27 +000047
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000048private:
49 const llvm::DenseSet<const Atom*> _liveAtoms;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000050};
51
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000052
Michael J. Spencer765792d2012-04-03 18:40:27 +000053/// This is used as a filter function to std::remove_if to coalesced atoms.
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000054class AtomCoalescedAway {
55public:
56 AtomCoalescedAway(SymbolTable &sym) : _symbolTable(sym) {}
57
58 bool operator()(const Atom *atom) const {
59 const Atom *rep = _symbolTable.replacement(atom);
60 return rep != atom;
61 }
62
63private:
64 SymbolTable &_symbolTable;
65};
66
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000067
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000068// add all atoms from all initial .o files
69void Resolver::buildInitialAtomList() {
Nick Kledzikabb69812012-05-31 22:34:00 +000070 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver initial atom list:\n");
71
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000072 // each input files contributes initial atoms
73 _atoms.reserve(1024);
74 _inputFiles.forEachInitialAtom(*this);
75
76 _completedInitialObjectFiles = true;
77}
78
79
80// called before the first atom in any file is added with doAtom()
81void Resolver::doFile(const File &file) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000082}
83
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000084
85void Resolver::doUndefinedAtom(const class UndefinedAtom& atom) {
Nick Kledzikabb69812012-05-31 22:34:00 +000086 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
87 << " UndefinedAtom: "
88 << llvm::format("0x%09lX", &atom)
89 << ", name="
90 << atom.name()
91 << "\n");
92
93 // add to list of known atoms
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000094 _atoms.push_back(&atom);
Michael J. Spencer765792d2012-04-03 18:40:27 +000095
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000096 // tell symbol table
97 _symbolTable.add(atom);
98}
99
100
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000101// called on each atom when a file is added
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000102void Resolver::doDefinedAtom(const DefinedAtom &atom) {
Nick Kledzikabb69812012-05-31 22:34:00 +0000103 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
104 << " DefinedAtom: "
105 << llvm::format("0x%09lX", &atom)
Nick Kledzik36293f62013-01-23 22:32:56 +0000106 << ", file=#"
107 << atom.file().ordinal()
108 << ", atom=#"
109 << atom.ordinal()
Nick Kledzikabb69812012-05-31 22:34:00 +0000110 << ", name="
111 << atom.name()
112 << "\n");
113
Nick Kledzik36293f62013-01-23 22:32:56 +0000114 // Verify on zero-size atoms are pinned to start or end of section.
115 switch ( atom.sectionPosition() ) {
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000116 case DefinedAtom::sectionPositionStart:
Nick Kledzik36293f62013-01-23 22:32:56 +0000117 case DefinedAtom::sectionPositionEnd:
118 assert(atom.size() == 0);
119 break;
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000120 case DefinedAtom::sectionPositionEarly:
121 case DefinedAtom::sectionPositionAny:
Nick Kledzik36293f62013-01-23 22:32:56 +0000122 break;
123 }
124
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000125 // add to list of known atoms
126 _atoms.push_back(&atom);
Michael J. Spencer765792d2012-04-03 18:40:27 +0000127
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000128 // tell symbol table
Nick Kledzik233f5372013-01-15 00:17:57 +0000129 _symbolTable.add(atom);
Nick Kledzikabb69812012-05-31 22:34:00 +0000130
Nick Kledzikc314b462013-04-04 18:59:24 +0000131 if (_targetInfo.deadStrip()) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000132 // add to set of dead-strip-roots, all symbols that
133 // the compiler marks as don't strip
Nick Kledzikbb963df2012-04-18 21:55:06 +0000134 if (atom.deadStrip() == DefinedAtom::deadStripNever)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000135 _deadStripRoots.insert(&atom);
136 }
137}
138
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000139void Resolver::doSharedLibraryAtom(const SharedLibraryAtom& atom) {
Nick Kledzikabb69812012-05-31 22:34:00 +0000140 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
141 << " SharedLibraryAtom: "
142 << llvm::format("0x%09lX", &atom)
143 << ", name="
144 << atom.name()
145 << "\n");
146
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000147 // add to list of known atoms
148 _atoms.push_back(&atom);
Michael J. Spencer765792d2012-04-03 18:40:27 +0000149
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000150 // tell symbol table
151 _symbolTable.add(atom);
152}
Michael J. Spencer765792d2012-04-03 18:40:27 +0000153
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000154void Resolver::doAbsoluteAtom(const AbsoluteAtom& atom) {
Nick Kledzikabb69812012-05-31 22:34:00 +0000155 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
156 << " AbsoluteAtom: "
157 << llvm::format("0x%09lX", &atom)
158 << ", name="
159 << atom.name()
160 << "\n");
161
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000162 // add to list of known atoms
163 _atoms.push_back(&atom);
Michael J. Spencer765792d2012-04-03 18:40:27 +0000164
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000165 // tell symbol table
Hemant Kulkarnif8286132012-11-05 19:13:54 +0000166 if (atom.scope() != Atom::scopeTranslationUnit) {
167 _symbolTable.add(atom);
168 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000169}
170
171
Michael J. Spencer765792d2012-04-03 18:40:27 +0000172
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000173// utility to add a vector of atoms
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000174void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) {
175 for (std::vector<const DefinedAtom *>::const_iterator it = newAtoms.begin();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000176 it != newAtoms.end(); ++it) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000177 this->doDefinedAtom(**it);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000178 }
179}
180
181// ask symbol table if any definitionUndefined atoms still exist
182// if so, keep searching libraries until no more atoms being added
183void Resolver::resolveUndefines() {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000184 const bool searchArchives =
185 _targetInfo.searchArchivesToOverrideTentativeDefinitions();
186 const bool searchSharedLibs =
187 _targetInfo.searchSharedLibrariesToOverrideTentativeDefinitions();
188
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000189 // keep looping until no more undefines were added in last loop
190 unsigned int undefineGenCount = 0xFFFFFFFF;
191 while (undefineGenCount != _symbolTable.size()) {
192 undefineGenCount = _symbolTable.size();
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000193 std::vector<const UndefinedAtom *> undefines;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000194 _symbolTable.undefines(undefines);
Nick Kledzik062a98c2012-04-08 23:52:13 +0000195 for ( const Atom *undefAtom : undefines ) {
196 StringRef undefName = undefAtom->name();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000197 // load for previous undefine may also have loaded this undefine
198 if (!_symbolTable.isDefined(undefName)) {
199 _inputFiles.searchLibraries(undefName, true, true, false, *this);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000200 }
201 }
202 // search libraries for overrides of common symbols
Nick Kledzik20e652d2012-04-20 01:24:37 +0000203 if (searchArchives || searchSharedLibs) {
204 std::vector<StringRef> tentDefNames;
205 _symbolTable.tentativeDefinitions(tentDefNames);
206 for ( StringRef tentDefName : tentDefNames ) {
207 // Load for previous tentative may also have loaded
Nick Kledzikabb69812012-05-31 22:34:00 +0000208 // something that overrode this tentative, so always check.
Nick Kledzik20e652d2012-04-20 01:24:37 +0000209 const Atom *curAtom = _symbolTable.findByName(tentDefName);
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000210 assert(curAtom != nullptr);
Michael J. Spencere6203a52012-04-03 18:39:40 +0000211 if (const DefinedAtom* curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
Nick Kledzik20e652d2012-04-20 01:24:37 +0000212 if (curDefAtom->merge() == DefinedAtom::mergeAsTentative ) {
213 // Still tentative definition, so look for override.
214 _inputFiles.searchLibraries(tentDefName, searchSharedLibs,
215 searchArchives, true, *this);
216 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000217 }
218 }
219 }
220 }
221}
222
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000223
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000224// switch all references to undefined or coalesced away atoms
225// to the new defined atom
226void Resolver::updateReferences() {
Nick Kledzik062a98c2012-04-08 23:52:13 +0000227 for(const Atom *atom : _atoms) {
228 if (const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom)) {
229 for (const Reference *ref : *defAtom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000230 const Atom* newTarget = _symbolTable.replacement(ref->target());
231 (const_cast<Reference*>(ref))->setTarget(newTarget);
232 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000233 }
234 }
235}
236
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000237
Nick Kledzikbb963df2012-04-18 21:55:06 +0000238// for dead code stripping, recursively mark atoms "live"
239void Resolver::markLive(const Atom &atom) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000240 // if already marked live, then done (stop recursion)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000241 if ( _liveAtoms.count(&atom) )
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000242 return;
243
244 // mark this atom is live
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000245 _liveAtoms.insert(&atom);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000246
247 // mark all atoms it references as live
Michael J. Spencere6203a52012-04-03 18:39:40 +0000248 if ( const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(&atom)) {
Nick Kledzik062a98c2012-04-08 23:52:13 +0000249 for (const Reference *ref : *defAtom) {
Nick Kledzikbb963df2012-04-18 21:55:06 +0000250 const Atom *target = ref->target();
251 if ( target != nullptr )
252 this->markLive(*target);
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000253 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000254 }
255}
256
Nick Kledzikbb963df2012-04-18 21:55:06 +0000257
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000258// remove all atoms not actually used
259void Resolver::deadStripOptimize() {
260 // only do this optimization with -dead_strip
Nick Kledzikc314b462013-04-04 18:59:24 +0000261 if (!_targetInfo.deadStrip())
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000262 return;
263
264 // clear liveness on all atoms
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000265 _liveAtoms.clear();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000266
Nick Kledzikbb963df2012-04-18 21:55:06 +0000267 // By default, shared libraries are built with all globals as dead strip roots
Nick Kledzikc314b462013-04-04 18:59:24 +0000268 if (_targetInfo.globalsAreDeadStripRoots()) {
Nick Kledzikbb963df2012-04-18 21:55:06 +0000269 for ( const Atom *atom : _atoms ) {
270 const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom);
271 if (defAtom == nullptr)
272 continue;
273 if ( defAtom->scope() == DefinedAtom::scopeGlobal )
274 _deadStripRoots.insert(defAtom);
275 }
276 }
Nick Kledzikabb69812012-05-31 22:34:00 +0000277
Nick Kledzikbb963df2012-04-18 21:55:06 +0000278 // Or, use list of names that are dead stip roots.
Nick Kledzikc314b462013-04-04 18:59:24 +0000279 for (const StringRef &name : _targetInfo.deadStripRoots()) {
Nick Kledzikbb963df2012-04-18 21:55:06 +0000280 const Atom *symAtom = _symbolTable.findByName(name);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000281 assert(symAtom->definition() != Atom::definitionUndefined);
282 _deadStripRoots.insert(symAtom);
283 }
284
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000285 // mark all roots as live, and recursively all atoms they reference
Nick Kledzik062a98c2012-04-08 23:52:13 +0000286 for ( const Atom *dsrAtom : _deadStripRoots) {
Nick Kledzikbb963df2012-04-18 21:55:06 +0000287 this->markLive(*dsrAtom);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000288 }
289
290 // now remove all non-live atoms from _atoms
291 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000292 NotLive(_liveAtoms)), _atoms.end());
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000293}
294
Nick Kledzikbb963df2012-04-18 21:55:06 +0000295
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000296// error out if some undefines remain
Nick Kledzikc314b462013-04-04 18:59:24 +0000297bool Resolver::checkUndefines(bool final) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000298 // when using LTO, undefines are checked after bitcode is optimized
299 if (_haveLLVMObjs && !final)
Nick Kledzikc314b462013-04-04 18:59:24 +0000300 return false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000301
302 // build vector of remaining undefined symbols
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000303 std::vector<const UndefinedAtom *> undefinedAtoms;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000304 _symbolTable.undefines(undefinedAtoms);
Nick Kledzikc314b462013-04-04 18:59:24 +0000305 if (_targetInfo.deadStrip()) {
Nick Kledzikbb963df2012-04-18 21:55:06 +0000306 // When dead code stripping, we don't care if dead atoms are undefined.
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000307 undefinedAtoms.erase(std::remove_if(
308 undefinedAtoms.begin(), undefinedAtoms.end(),
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000309 NotLive(_liveAtoms)), undefinedAtoms.end());
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000310 }
311
Nick Kledzikbb963df2012-04-18 21:55:06 +0000312 // error message about missing symbols
Nick Kledzikc314b462013-04-04 18:59:24 +0000313 if (!undefinedAtoms.empty()) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000314 // FIXME: need diagnostics interface for writing error messages
Nick Kledzikc314b462013-04-04 18:59:24 +0000315 bool foundUndefines = false;
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000316 for (const UndefinedAtom *undefAtom : undefinedAtoms) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000317 const File &f = undefAtom->file();
Michael J. Spencer9d70cef2013-04-24 19:00:26 +0000318
319 // Skip over a weak symbol.
320 if (undefAtom->canBeNull() != UndefinedAtom::canBeNullNever)
321 continue;
322
323 // If this is a library and undefined symbols are allowed on the
324 // target platform, skip over it.
325 if (isa<SharedLibraryFile>(f) && _targetInfo.allowShlibUndefines())
326 continue;
327
328 // Seems like this symbol is undefined. Warn that.
329 foundUndefines = true;
330 if (_targetInfo.printRemainingUndefines()) {
Shankar Easwaraneeee23e2013-04-11 02:56:30 +0000331 llvm::errs() << "Undefined Symbol: " << undefAtom->file().path()
332 << " : " << undefAtom->name() << "\n";
Michael J. Spencer280dadb2013-01-31 22:56:13 +0000333 }
Nick Kledzikbb963df2012-04-18 21:55:06 +0000334 }
Nick Kledzikc314b462013-04-04 18:59:24 +0000335 if (foundUndefines) {
336 if (_targetInfo.printRemainingUndefines())
337 llvm::errs() << "symbol(s) not found\n";
338 return true;
339 }
Nick Kledzikbb963df2012-04-18 21:55:06 +0000340 }
Nick Kledzikc314b462013-04-04 18:59:24 +0000341 return false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000342}
343
Nick Kledzikbb963df2012-04-18 21:55:06 +0000344
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000345// remove from _atoms all coaleseced away atoms
346void Resolver::removeCoalescedAwayAtoms() {
347 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
348 AtomCoalescedAway(_symbolTable)), _atoms.end());
349}
350
351// check for interactions between symbols defined in this linkage unit
352// and same symbol name in linked dynamic shared libraries
353void Resolver::checkDylibSymbolCollisions() {
Nick Kledzik062a98c2012-04-08 23:52:13 +0000354 for ( const Atom *atom : _atoms ) {
355 const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom);
Michael J. Spencerc9d25062012-03-29 19:39:14 +0000356 if (defAtom == nullptr)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000357 continue;
Michael J. Spencer765792d2012-04-03 18:40:27 +0000358 if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000359 continue;
360 assert(defAtom->scope() != DefinedAtom::scopeTranslationUnit);
361 // See if any shared library also has symbol which
362 // collides with the tentative definition.
363 // SymbolTable will warn if needed.
364 _inputFiles.searchLibraries(defAtom->name(), true, false, false, *this);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000365 }
366}
367
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000368
369void Resolver::linkTimeOptimize() {
370 // FIX ME
371}
372
Nick Kledzikc314b462013-04-04 18:59:24 +0000373bool Resolver::resolve() {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000374 this->buildInitialAtomList();
375 this->resolveUndefines();
376 this->updateReferences();
377 this->deadStripOptimize();
Nick Kledzikc314b462013-04-04 18:59:24 +0000378 if (this->checkUndefines(false)) {
379 if (!_targetInfo.allowRemainingUndefines())
380 return true;
381 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000382 this->removeCoalescedAwayAtoms();
383 this->checkDylibSymbolCollisions();
384 this->linkTimeOptimize();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000385 this->_result.addAtoms(_atoms);
Nick Kledzikc314b462013-04-04 18:59:24 +0000386 return false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000387}
388
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000389void Resolver::MergedFile::addAtom(const Atom& atom) {
Michael J. Spencere6203a52012-04-03 18:39:40 +0000390 if (const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(&atom)) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000391 _definedAtoms._atoms.push_back(defAtom);
Michael J. Spencere6203a52012-04-03 18:39:40 +0000392 } else if (const UndefinedAtom* undefAtom = dyn_cast<UndefinedAtom>(&atom)) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000393 _undefinedAtoms._atoms.push_back(undefAtom);
Michael J. Spencerb4955622012-04-02 23:56:36 +0000394 } else if (const SharedLibraryAtom* slAtom =
Michael J. Spencere6203a52012-04-03 18:39:40 +0000395 dyn_cast<SharedLibraryAtom>(&atom)) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000396 _sharedLibraryAtoms._atoms.push_back(slAtom);
Michael J. Spencere6203a52012-04-03 18:39:40 +0000397 } else if (const AbsoluteAtom* abAtom = dyn_cast<AbsoluteAtom>(&atom)) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000398 _absoluteAtoms._atoms.push_back(abAtom);
Michael J. Spencerb4955622012-04-02 23:56:36 +0000399 } else {
Nick Kledzik751eb3d2012-06-15 20:37:24 +0000400 llvm_unreachable("atom has unknown definition kind");
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000401 }
402}
403
Nick Kledzik36293f62013-01-23 22:32:56 +0000404
405MutableFile::DefinedAtomRange Resolver::MergedFile::definedAtoms() {
406 return range<std::vector<const DefinedAtom*>::iterator>(
407 _definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
408}
409
410
411
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000412void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
Nick Kledzikabb69812012-05-31 22:34:00 +0000413 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
Nick Kledzik062a98c2012-04-08 23:52:13 +0000414 for ( const Atom *atom : all ) {
Nick Kledzikabb69812012-05-31 22:34:00 +0000415 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
416 << llvm::format(" 0x%09lX", atom)
417 << ", name="
418 << atom->name()
419 << "\n");
Nick Kledzik062a98c2012-04-08 23:52:13 +0000420 this->addAtom(*atom);
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000421 }
422}
423
424
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000425} // namespace lld