#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 "Options.h"
#include "ld.hpp"
#include "SymbolTable.h"
namespace ld {
namespace tool {
class Resolver : public ld::File::AtomHandler
{
public:
Resolver(const Options& opts, const InputFiles& inputs, ld::Internal& state)
: _options(opts), _inputFiles(inputs), _internal(state),
_symbolTable(opts, state.indirectBindingTable),
_haveLLVMObjs(false), _addToFinalSection(false),
_completedInitialObjectFiles(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();
void resolveUndefines();
void checkUndefines(bool force=false);
void checkDylibSymbolCollisions();
void tentativeOverrideOfDylib(ld::Atom&);
void fillInInternalState();
void fillInHelpersInInternalState();
void removeCoalescedAwayAtoms();
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*>&);
static unsigned int ppcSubTypeIndex(uint32_t subtype);
bool printReferencedBy(const char* name, SymbolTable::IndirectBindingSlot slot);
class CStringEquals {
public:
bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
};
typedef __gnu_cxx::hash_set<const char*, __gnu_cxx::hash<const char*>, 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;
const InputFiles& _inputFiles;
ld::Internal& _internal;
std::vector<const ld::Atom*> _atoms;
std::set<const ld::Atom*> _deadStripRoots;
std::vector<const ld::Atom*> _atomsWithUnresolvedReferences;
SymbolTable _symbolTable;
bool _haveLLVMObjs;
bool _addToFinalSection;
bool _completedInitialObjectFiles;
};
class DeadStripResolver
{
public:
private:
};
} }
#endif // __RESOLVER_H__