#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), fLoadObjcClassesInArchives(false), fFlatNamespace(false),
fForFinalLinkedImage(false), fWhyLoad(false), fDebugInfoStripping(kDebugInfoFull),
fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false), fTraceOutputFile(NULL) {}
enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
bool fFullyLoadArchives;
bool fLoadObjcClassesInArchives;
bool fFlatNamespace;
bool fForFinalLinkedImage;
bool fWhyLoad;
DebugInfoStripping fDebugInfoStripping;
bool fTraceDylibs;
bool fTraceIndirectDylibs;
bool fTraceArchives;
const char* fTraceOutputFile;
};
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;
};
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;
unsigned int getSortOrder() const { return fSortOrder; }
void setSortOrder(unsigned int order) { fSortOrder=order; }
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 std::vector<const char*>* getDependentLibraryPaths() { return NULL; }
virtual bool reExports(Reader*) { return false; }
virtual const char* parentUmbrella() { return NULL; }
virtual std::vector<const char*>* getAllowableClients() { return NULL; }
protected:
Reader() : fSortOrder(0) {}
virtual ~Reader() {}
unsigned int fSortOrder;
};
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;
};
class Atom
{
public:
enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
enum DefinitionKind { kRegularDefinition, kWeakDefinition, kTentativeDefinition, kExternalDefinition, kExternalWeakDefinition };
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 bool requiresFollowOnAtom() const = 0;
virtual Atom& getFollowOnAtom() const = 0;
virtual std::vector<LineInfo>* getLineInfo() const = 0;
virtual uint8_t getAlignment() const = 0;
virtual void copyRawContent(uint8_t buffer[]) const = 0;
virtual void setScope(Scope) = 0;
uint64_t getSectionOffset() const { return fSectionOffset; }
uint64_t getSegmentOffset() const { return fSegmentOffset; }
uint64_t getAddress() const { return fSection->getBaseAddress() + fSectionOffset; }
unsigned int getSortOrder() const { return fSortOrder; }
class Section* getSection() const { return fSection; }
void setSegmentOffset(uint64_t offset) { fSegmentOffset = offset; }
void setSectionOffset(uint64_t offset) { fSectionOffset = offset; }
void setSection(class Section* sect) { fSection = sect; }
unsigned int setSortOrder(unsigned int order);
protected:
Atom() : fSegmentOffset(0), fSectionOffset(0), fSortOrder(0), fSection(NULL) {}
virtual ~Atom() {}
uint64_t fSegmentOffset;
uint64_t fSectionOffset;
unsigned int fSortOrder;
class Section* fSection;
};
inline unsigned int Atom::setSortOrder(unsigned int order)
{
if ( this->requiresFollowOnAtom() ) {
fSortOrder = order;
return this->getFollowOnAtom().setSortOrder(order+1);
}
else {
fSortOrder = order;
return (order + 1);
}
}
class Reference
{
public:
virtual bool isTargetUnbound() const = 0;
virtual bool isFromTargetUnbound() 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 bool hasFromTarget() 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__