#ifndef __RESOLVER_H__
#define __RESOLVER_H__
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <mach/mach_time.h>
#include <mach/vm_statistics.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
#include <vector>
#include <unordered_set>
#include "Options.h"
#include "ld.hpp"
#include "SymbolTable.h"
namespace ld {
namespace tool {
class Resolver : public ld::File::AtomHandler
{
public:
Resolver(const Options& opts, InputFiles& inputs, ld::Internal& state)
: _options(opts), _inputFiles(inputs), _internal(state),
_symbolTable(opts, state.indirectBindingTable),
_haveLLVMObjs(false),
_completedInitialObjectFiles(false),
_ltoCodeGenFinished(false),
_haveAliases(false) {}
virtual void doAtom(const ld::Atom&);
virtual void doFile(const class File&);
void resolve();
private:
struct WhyLiveBackChain
{
WhyLiveBackChain* previous;
const ld::Atom* referer;
};
void initializeState();
void buildAtomList();
void addInitialUndefines();
void deadStripOptimize(bool force=false);
void resolveUndefines();
void checkUndefines(bool force=false);
void checkDylibSymbolCollisions();
void tentativeOverrideOfDylib(ld::Atom&);
void fillInInternalState();
void fillInHelpersInInternalState();
void removeCoalescedAwayAtoms();
void syncAliases();
void fillInEntryPoint();
void linkTimeOptimize();
void convertReferencesToIndirect(const ld::Atom& atom);
const ld::Atom* entryPoint(bool searchArchives);
void markLive(const ld::Atom& atom, WhyLiveBackChain* previous);
bool isDtraceProbe(ld::Fixup::Kind kind);
void liveUndefines(std::vector<const char*>&);
void remainingUndefines(std::vector<const char*>&);
bool printReferencedBy(const char* name, SymbolTable::IndirectBindingSlot slot);
void tweakWeakness();
void doLinkerOption(const std::vector<const char*>& linkerOption, const char* fileName);
void dumpAtoms();
typedef std::unordered_set<const char*, CStringHash, CStringEquals> StringSet;
class NotLive {
public:
bool operator()(const ld::Atom* atom) const {
return ! (atom->live() || atom->dontDeadStrip());
}
};
class AtomCoalescedAway {
public:
bool operator()(const ld::Atom* atom) const {
return atom->coalescedAway();
}
};
const Options& _options;
InputFiles& _inputFiles;
ld::Internal& _internal;
std::vector<const ld::Atom*> _atoms;
std::set<const ld::Atom*> _deadStripRoots;
std::vector<const ld::Atom*> _dontDeadStripIfReferencesLive;
std::vector<const ld::Atom*> _atomsWithUnresolvedReferences;
std::vector<const class AliasAtom*> _aliasesFromCmdLine;
SymbolTable _symbolTable;
bool _haveLLVMObjs;
bool _completedInitialObjectFiles;
bool _ltoCodeGenFinished;
bool _haveAliases;
};
class DeadStripResolver
{
public:
private:
};
} }
#endif // __RESOLVER_H__