blob: 6570183c5bba065f44d805edf9fad05b2de29865 [file] [log] [blame]
//===- Core/Resolver.h - Resolves Atom References -------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_CORE_RESOLVER_H_
#define LLD_CORE_RESOLVER_H_
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
#include "lld/Core/SymbolTable.h"
#include "llvm/ADT/DenseSet.h"
#include <set>
#include <vector>
namespace lld {
class Atom;
class InputFiles;
class Platform;
class SymbolTable;
/// The Resolver is responsible for merging all input object files
/// and producing a merged graph.
///
/// All platform specific resolving is done by delegating to the
/// Platform object specified.
class Resolver : public InputFiles::Handler {
public:
Resolver(Platform &plat, const InputFiles &inputs)
: _platform(plat)
, _inputFiles(inputs)
, _symbolTable(plat)
, _haveLLVMObjs(false)
, _addToFinalSection(false)
, _completedInitialObjectFiles(false) {}
// InputFiles::Handler methods
virtual void doDefinedAtom(const class DefinedAtom&);
virtual void doUndefinedAtom(const class UndefinedAtom&);
virtual void doSharedLibraryAtom(const class SharedLibraryAtom &);
virtual void doAbsoluteAtom(const class AbsoluteAtom &);
virtual void doFile(const File&);
/// @brief do work of merging and resolving and return list
void resolve();
File& resultFile() {
return _result;
}
private:
struct WhyLiveBackChain {
WhyLiveBackChain *previous;
const Atom *referer;
};
void initializeState();
void addInitialUndefines();
void buildInitialAtomList();
void resolveUndefines();
void updateReferences();
void deadStripOptimize();
void checkUndefines(bool final);
void removeCoalescedAwayAtoms();
void checkDylibSymbolCollisions();
void linkTimeOptimize();
void tweakAtoms();
const Atom *entryPoint();
void markLive(const Atom &atom, WhyLiveBackChain *previous);
void addAtoms(const std::vector<const DefinedAtom *>&);
class MergedFile : public File {
public:
MergedFile() : File("<linker-internal>"), _mainAtom(nullptr) { }
virtual const Atom *entryPoint() const {
return _mainAtom;
}
virtual const atom_collection<DefinedAtom>& defined() const {
return _definedAtoms;
}
virtual const atom_collection<UndefinedAtom>& undefined() const {
return _undefinedAtoms;
}
virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
return _sharedLibraryAtoms;
}
virtual const atom_collection<AbsoluteAtom>& absolute() const {
return _absoluteAtoms;
}
void addAtoms(std::vector<const Atom*>& atoms);
virtual void addAtom(const Atom& atom);
private:
friend class Resolver;
const Atom* _mainAtom;
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
};
Platform& _platform;
const InputFiles& _inputFiles;
SymbolTable _symbolTable;
std::vector<const Atom *> _atoms;
std::set<const Atom *> _deadStripRoots;
std::vector<const Atom *> _atomsWithUnresolvedReferences;
llvm::DenseSet<const Atom *> _liveAtoms;
MergedFile _result;
bool _haveLLVMObjs;
bool _addToFinalSection;
bool _completedInitialObjectFiles;
};
} // namespace lld
#endif // LLD_CORE_RESOLVER_H_