#ifndef LLVM_OBJECT_MACHOOBJECT_H
#define LLVM_OBJECT_MACHOOBJECT_H
#include <string>
#include "llvm/ADT/InMemoryStruct.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/MachOFormat.h"
namespace llvm {
class MemoryBuffer;
class raw_ostream;
namespace object {
class MachOObject {
public:
struct LoadCommandInfo {
macho::LoadCommand Command;
uint64_t Offset;
};
private:
OwningPtr<MemoryBuffer> Buffer;
bool IsLittleEndian;
bool Is64Bit;
bool IsSwappedEndian;
bool HasStringTable;
LoadCommandInfo *LoadCommands;
mutable unsigned NumLoadedCommands;
macho::Header Header;
macho::Header64Ext Header64Ext;
StringRef StringTable;
private:
MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
public:
~MachOObject();
static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
std::string *ErrorStr = 0);
bool isLittleEndian() const { return IsLittleEndian; }
bool isSwappedEndian() const { return IsSwappedEndian; }
bool is64Bit() const { return Is64Bit; }
unsigned getHeaderSize() const {
return Is64Bit ? macho::Header64Size : macho::Header32Size;
}
StringRef getData(size_t Offset, size_t Size) const;
StringRef getStringTableData() const {
assert(HasStringTable && "String table has not been registered!");
return StringTable;
}
StringRef getStringAtIndex(unsigned Index) const {
size_t End = getStringTableData().find('\0', Index);
return getStringTableData().slice(Index, End);
}
void RegisterStringTable(macho::SymtabLoadCommand &SLC);
const macho::Header &getHeader() const { return Header; }
const macho::Header64Ext &getHeader64Ext() const {
assert(is64Bit() && "Invalid access!");
return Header64Ext;
}
const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
void ReadSegmentLoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
void ReadSegment64LoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
void ReadSymtabLoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
void ReadDysymtabLoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
void ReadLinkeditDataLoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
void ReadIndirectSymbolTableEntry(
const macho::DysymtabLoadCommand &DLC,
unsigned Index,
InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
void ReadSection(
const LoadCommandInfo &LCI,
unsigned Index,
InMemoryStruct<macho::Section> &Res) const;
void ReadSection64(
const LoadCommandInfo &LCI,
unsigned Index,
InMemoryStruct<macho::Section64> &Res) const;
void ReadRelocationEntry(
uint64_t RelocationTableOffset, unsigned Index,
InMemoryStruct<macho::RelocationEntry> &Res) const;
void ReadSymbolTableEntry(
uint64_t SymbolTableOffset, unsigned Index,
InMemoryStruct<macho::SymbolTableEntry> &Res) const;
void ReadSymbol64TableEntry(
uint64_t SymbolTableOffset, unsigned Index,
InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
void ReadDataInCodeTableEntry(
uint64_t TableOffset, unsigned Index,
InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
void dump() const;
void dumpHeader() const;
void print(raw_ostream &O) const;
void printHeader(raw_ostream &O) const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
V.print(OS);
return OS;
}
} }
#endif