X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FObject%2FMachOObject.cpp;h=9cdac8681dddae9cb4f9eb66e0e08ae9a1570480;hb=50f1c37123968b7f57068280483ec78f6ff7973e;hp=1e15f296e0f56143e5fdeae56bc5eb24f1b29bd6;hpb=f879f14cef93fe51ee8c180be7acf70294807b8f;p=oota-llvm.git diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp index 1e15f296e0f..9cdac8681dd 100644 --- a/lib/Object/MachOObject.cpp +++ b/lib/Object/MachOObject.cpp @@ -9,9 +9,12 @@ #include "llvm/Object/MachOObject.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Host.h" -#include "llvm/System/SwapByteOrder.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Debug.h" using namespace llvm; using namespace llvm::object; @@ -57,7 +60,7 @@ MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_, bool Is64Bit_) : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_), IsSwappedEndian(IsLittleEndian != sys::isLittleEndianHost()), - LoadCommands(0), NumLoadedCommands(0) { + HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) { // Load the common header. memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header)); if (IsSwappedEndian) { @@ -84,7 +87,7 @@ MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_, } MachOObject::~MachOObject() { - delete LoadCommands; + delete [] LoadCommands; } MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer, @@ -125,6 +128,16 @@ MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer, return Object.take(); } +StringRef MachOObject::getData(size_t Offset, size_t Size) const { + return Buffer->getBuffer().substr(Offset,Size); +} + +void MachOObject::RegisterStringTable(macho::SymtabLoadCommand &SLC) { + HasStringTable = true; + StringTable = Buffer->getBuffer().substr(SLC.StringTableOffset, + SLC.StringTableSize); +} + const MachOObject::LoadCommandInfo & MachOObject::getLoadCommandInfo(unsigned Index) const { assert(Index < getHeader().NumLoadCommands && "Invalid index!"); @@ -154,7 +167,7 @@ MachOObject::getLoadCommandInfo(unsigned Index) const { } template<> -static void SwapStruct(macho::SegmentLoadCommand &Value) { +void SwapStruct(macho::SegmentLoadCommand &Value) { SwapValue(Value.Type); SwapValue(Value.Size); SwapValue(Value.VMAddress); @@ -172,7 +185,7 @@ void MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI, } template<> -static void SwapStruct(macho::Segment64LoadCommand &Value) { +void SwapStruct(macho::Segment64LoadCommand &Value) { SwapValue(Value.Type); SwapValue(Value.Size); SwapValue(Value.VMAddress); @@ -190,7 +203,7 @@ void MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI, } template<> -static void SwapStruct(macho::SymtabLoadCommand &Value) { +void SwapStruct(macho::SymtabLoadCommand &Value) { SwapValue(Value.Type); SwapValue(Value.Size); SwapValue(Value.SymbolTableOffset); @@ -204,10 +217,10 @@ void MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI, } template<> -static void SwapStruct(macho::DysymtabLoadCommand &Value) { +void SwapStruct(macho::DysymtabLoadCommand &Value) { SwapValue(Value.Type); SwapValue(Value.Size); - SwapValue(Value.LocalSymbolIndex); + SwapValue(Value.LocalSymbolsIndex); SwapValue(Value.NumLocalSymbols); SwapValue(Value.ExternalSymbolsIndex); SwapValue(Value.NumExternalSymbols); @@ -230,3 +243,166 @@ void MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI, InMemoryStruct &Res) const { ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); } + +template<> +void SwapStruct(macho::LinkeditDataLoadCommand &Value) { + SwapValue(Value.Type); + SwapValue(Value.Size); + SwapValue(Value.DataOffset); + SwapValue(Value.DataSize); +} +void MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI, + InMemoryStruct &Res) const { + ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); +} + +template<> +void SwapStruct(macho::IndirectSymbolTableEntry &Value) { + SwapValue(Value.Index); +} +void +MachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC, + unsigned Index, + InMemoryStruct &Res) const { + uint64_t Offset = (DLC.IndirectSymbolTableOffset + + Index * sizeof(macho::IndirectSymbolTableEntry)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + + +template<> +void SwapStruct(macho::Section &Value) { + SwapValue(Value.Address); + SwapValue(Value.Size); + SwapValue(Value.Offset); + SwapValue(Value.Align); + SwapValue(Value.RelocationTableOffset); + SwapValue(Value.NumRelocationTableEntries); + SwapValue(Value.Flags); + SwapValue(Value.Reserved1); + SwapValue(Value.Reserved2); +} +void MachOObject::ReadSection(const LoadCommandInfo &LCI, + unsigned Index, + InMemoryStruct &Res) const { + assert(LCI.Command.Type == macho::LCT_Segment && + "Unexpected load command info!"); + uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) + + Index * sizeof(macho::Section)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + +template<> +void SwapStruct(macho::Section64 &Value) { + SwapValue(Value.Address); + SwapValue(Value.Size); + SwapValue(Value.Offset); + SwapValue(Value.Align); + SwapValue(Value.RelocationTableOffset); + SwapValue(Value.NumRelocationTableEntries); + SwapValue(Value.Flags); + SwapValue(Value.Reserved1); + SwapValue(Value.Reserved2); + SwapValue(Value.Reserved3); +} +void MachOObject::ReadSection64(const LoadCommandInfo &LCI, + unsigned Index, + InMemoryStruct &Res) const { + assert(LCI.Command.Type == macho::LCT_Segment64 && + "Unexpected load command info!"); + uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) + + Index * sizeof(macho::Section64)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + +template<> +void SwapStruct(macho::RelocationEntry &Value) { + SwapValue(Value.Word0); + SwapValue(Value.Word1); +} +void MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset, + unsigned Index, + InMemoryStruct &Res) const { + uint64_t Offset = (RelocationTableOffset + + Index * sizeof(macho::RelocationEntry)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + +template<> +void SwapStruct(macho::SymbolTableEntry &Value) { + SwapValue(Value.StringIndex); + SwapValue(Value.Flags); + SwapValue(Value.Value); +} +void MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset, + unsigned Index, + InMemoryStruct &Res) const { + uint64_t Offset = (SymbolTableOffset + + Index * sizeof(macho::SymbolTableEntry)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + +template<> +void SwapStruct(macho::Symbol64TableEntry &Value) { + SwapValue(Value.StringIndex); + SwapValue(Value.Flags); + SwapValue(Value.Value); +} +void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset, + unsigned Index, + InMemoryStruct &Res) const { + uint64_t Offset = (SymbolTableOffset + + Index * sizeof(macho::Symbol64TableEntry)); + ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); +} + + +void MachOObject::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { + const char *ptr = Buffer->getBufferStart() + Index; + uint64_t data = 0; + uint64_t delta = 0; + uint32_t shift = 0; + while (true) { + assert(ptr < Buffer->getBufferEnd() && "index out of bounds"); + assert(shift < 64 && "too big for uint64_t"); + + uint8_t byte = *ptr++; + delta |= ((byte & 0x7F) << shift); + shift += 7; + if (byte < 0x80) { + if (delta == 0) + break; + data += delta; + Out.push_back(data); + delta = 0; + shift = 0; + } + } +} + +/* ** */ +// Object Dumping Facilities +void MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; } +void MachOObject::dumpHeader() const { printHeader(dbgs()); dbgs() << '\n'; } + +void MachOObject::printHeader(raw_ostream &O) const { + O << "('cputype', " << Header.CPUType << ")\n"; + O << "('cpusubtype', " << Header.CPUSubtype << ")\n"; + O << "('filetype', " << Header.FileType << ")\n"; + O << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; + O << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; + O << "('flag', " << Header.Flags << ")\n"; + + // Print extended header if 64-bit. + if (is64Bit()) + O << "('reserved', " << Header64Ext.Reserved << ")\n"; +} + +void MachOObject::print(raw_ostream &O) const { + O << "Header:\n"; + printHeader(O); + O << "Load Commands:\n"; + + O << "Buffer:\n"; +}