#ifndef __OBJECTFILE__
#define __OBJECTFILE__
#include <stdint.h>
#include <vector>
#include <map>
namespace ObjectFile {
struct LineInfo
{
uint32_t atomOffset;
const char* fileName;
uint32_t lineNumber;
};
class ReaderOptions
{
public:
ReaderOptions() : fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false), fLinkingMainExecutable(false),
fForFinalLinkedImage(false), fForStatic(false), fForDyld(false), fMakeTentativeDefinitionsReal(false),
fWhyLoad(false), fRootSafe(false), fSetuidSafe(false),fDebugInfoStripping(kDebugInfoFull),
fLogObjectFiles(false), fLogAllFiles(false),
fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),
fTraceOutputFile(NULL), fVersionMin(kMinUnset) {}
enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
enum VersionMin { kMinUnset, k10_1, k10_2, k10_3, k10_4, k10_5 };
struct AliasPair {
const char* realName;
const char* alias;
};
bool fFullyLoadArchives;
bool fLoadAllObjcObjectsFromArchives;
bool fFlatNamespace;
bool fLinkingMainExecutable;
bool fForFinalLinkedImage;
bool fForStatic;
bool fForDyld;
bool fMakeTentativeDefinitionsReal;
bool fWhyLoad;
bool fRootSafe;
bool fSetuidSafe;
DebugInfoStripping fDebugInfoStripping;
bool fLogObjectFiles;
bool fLogAllFiles;
bool fTraceDylibs;
bool fTraceIndirectDylibs;
bool fTraceArchives;
const char* fTraceOutputFile;
VersionMin fVersionMin;
std::vector<AliasPair> fAliases;
};
class Reader
{
public:
enum DebugInfoKind { kDebugInfoNone=0, kDebugInfoStabs=1, kDebugInfoDwarf=2, kDebugInfoStabsUUID=3 };
struct Stab
{
class Atom* atom;
uint8_t type;
uint8_t other;
uint16_t desc;
uint32_t value;
const char* string;
};
enum ObjcConstraint { kObjcNone, kObjcRetainRelease, kObjcRetainReleaseOrGC, kObjcGC };
enum CpuConstraint { kCpuAny, kCpuG3, kCpuG4, kCpuG5 };
class DylibHander
{
public:
virtual ~DylibHander() {}
virtual Reader* findDylib(const char* installPath, const char* fromPath) = 0;
};
static Reader* createReader(const char* path, const ReaderOptions& options);
virtual const char* getPath() = 0;
virtual time_t getModificationTime() = 0;
virtual DebugInfoKind getDebugInfoKind() = 0;
virtual std::vector<class Atom*>& getAtoms() = 0;
virtual std::vector<class Atom*>* getJustInTimeAtomsFor(const char* name) = 0;
virtual std::vector<Stab>* getStabs() = 0;
virtual ObjcConstraint getObjCConstraint() { return kObjcNone; }
virtual CpuConstraint getCpuConstraint() { return kCpuAny; }
virtual bool objcReplacementClasses() { return false; }
virtual bool canScatterAtoms() { return true; }
virtual void optimize(std::vector<ObjectFile::Atom*>&, std::vector<ObjectFile::Atom*>&, uint32_t) { }
virtual const char* getInstallPath() { return NULL; }
virtual uint32_t getTimestamp() { return 0; }
virtual uint32_t getCurrentVersion() { return 0; }
virtual uint32_t getCompatibilityVersion() { return 0; }
virtual void processIndirectLibraries(DylibHander* handler) { }
virtual void setExplicitlyLinked() { }
virtual bool explicitlyLinked() { return false; }
virtual bool implicitlyLinked() { return false; }
virtual bool providedExportAtom() { return false; }
virtual const char* parentUmbrella() { return NULL; }
virtual std::vector<const char*>* getAllowableClients() { return NULL; }
protected:
Reader() {}
virtual ~Reader() {}
};
class Segment
{
public:
virtual const char* getName() const = 0;
virtual bool isContentReadable() const = 0;
virtual bool isContentWritable() const = 0;
virtual bool isContentExecutable() const = 0;
uint64_t getBaseAddress() const { return fBaseAddress; }
void setBaseAddress(uint64_t addr) { fBaseAddress = addr; }
virtual bool hasFixedAddress() const { return false; }
protected:
Segment() : fBaseAddress(0) {}
virtual ~Segment() {}
uint64_t fBaseAddress;
};
class Reference;
class Section
{
public:
unsigned int getIndex() { return fIndex; }
uint64_t getBaseAddress() { return fBaseAddress; }
void setBaseAddress(uint64_t addr) { fBaseAddress = addr; }
void* fOther;
protected:
Section() : fOther(NULL), fBaseAddress(0), fIndex(0) {}
uint64_t fBaseAddress;
unsigned int fIndex;
};
struct Alignment
{
Alignment(int p2, int m=0) : powerOf2(p2), modulus(m) {}
uint8_t trailingZeros() const { return (modulus==0) ? powerOf2 : __builtin_ctz(modulus); }
uint16_t powerOf2;
uint16_t modulus;
};
class Atom
{
public:
enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
enum DefinitionKind { kRegularDefinition, kWeakDefinition, kTentativeDefinition, kExternalDefinition, kExternalWeakDefinition, kAbsoluteSymbol };
enum SymbolTableInclusion { kSymbolTableNotIn, kSymbolTableIn, kSymbolTableInAndNeverStrip, kSymbolTableInAsAbsolute };
virtual Reader* getFile() const = 0;
virtual bool getTranslationUnitSource(const char** dir, const char** name) const = 0;
virtual const char* getName() const = 0;
virtual const char* getDisplayName() const = 0;
virtual Scope getScope() const = 0;
virtual DefinitionKind getDefinitionKind() const = 0;
virtual SymbolTableInclusion getSymbolTableInclusion() const = 0;
virtual bool dontDeadStrip() const = 0;
virtual bool isZeroFill() const = 0;
virtual uint64_t getSize() const = 0;
virtual std::vector<ObjectFile::Reference*>& getReferences() const = 0;
virtual bool mustRemainInSection() const = 0;
virtual const char* getSectionName() const = 0;
virtual Segment& getSegment() const = 0;
virtual Atom& getFollowOnAtom() const = 0;
virtual uint32_t getOrdinal() const = 0;
virtual std::vector<LineInfo>* getLineInfo() const = 0;
virtual Alignment getAlignment() const = 0;
virtual void copyRawContent(uint8_t buffer[]) const = 0;
virtual void setScope(Scope) = 0;
uint64_t getSectionOffset() const { return fSectionOffset; }
uint64_t getAddress() const { return fSection->getBaseAddress() + fSectionOffset; }
class Section* getSection() const { return fSection; }
virtual void setSectionOffset(uint64_t offset) { fSectionOffset = offset; }
virtual void setSection(class Section* sect) { fSection = sect; }
protected:
Atom() : fSectionOffset(0), fSection(NULL) {}
virtual ~Atom() {}
uint64_t fSectionOffset;
class Section* fSection;
};
class Reference
{
public:
enum TargetBinding { kUnboundByName, kBoundDirectly, kBoundByName, kDontBind };
virtual TargetBinding getTargetBinding() const = 0;
virtual TargetBinding getFromTargetBinding() const = 0;
virtual uint8_t getKind() const = 0;
virtual uint64_t getFixUpOffset() const = 0;
virtual const char* getTargetName() const = 0;
virtual Atom& getTarget() const = 0;
virtual uint64_t getTargetOffset() const = 0;
virtual Atom& getFromTarget() const = 0;
virtual const char* getFromTargetName() const = 0;
virtual uint64_t getFromTargetOffset() const = 0;
virtual void setTarget(Atom&, uint64_t offset) = 0;
virtual void setFromTarget(Atom&) = 0;
virtual const char* getDescription() const = 0;
protected:
Reference() {}
virtual ~Reference() {}
};
};
#endif // __OBJECTFILE__