From 2173e1839c2d00f7f980450dd537047b7b376e6b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 26 Apr 2013 20:07:33 +0000 Subject: Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser. For Mach-O there were 2 implementations for parsing object files. A standalone llvm/Object/MachOObject.h and llvm/Object/MachO.h which implements the generic interface in llvm/Object/ObjectFile.h. This patch adds the missing features to MachO.h, moves macho-dump to use MachO.h and removes ObjectFile.h. In addition to making sure that check-all is clean, I checked that the new version produces exactly the same output in all Mach-O files in a llvm+clang build directory (including executables and shared libraries). To test the performance, I ran macho-dump over all the files in a llvm+clang build directory again, but this time redirecting the output to /dev/null. Both the old and new versions take about 4.6 seconds (2.5 user) to finish. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180624 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/CMakeLists.txt | 1 - lib/Object/MachOObject.cpp | 422 ----------------------------------------- lib/Object/MachOObjectFile.cpp | 161 +++++++++++++--- 3 files changed, 132 insertions(+), 452 deletions(-) delete mode 100644 lib/Object/MachOObject.cpp (limited to 'lib/Object') diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt index c20fc0cc39..4ed129f467 100644 --- a/lib/Object/CMakeLists.txt +++ b/lib/Object/CMakeLists.txt @@ -4,7 +4,6 @@ add_llvm_library(LLVMObject COFFObjectFile.cpp ELFObjectFile.cpp Error.cpp - MachOObject.cpp MachOObjectFile.cpp Object.cpp ObjectFile.cpp diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp deleted file mode 100644 index d88f96f298..0000000000 --- a/lib/Object/MachOObject.cpp +++ /dev/null @@ -1,422 +0,0 @@ -//===- MachOObject.cpp - Mach-O Object File Wrapper -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Object/MachOObject.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; -using namespace llvm::object; - -/* Translation Utilities */ - -template -static void SwapValue(T &Value) { - Value = sys::SwapByteOrder(Value); -} - -template -static void SwapStruct(T &Value); - -template -static void ReadInMemoryStruct(const MachOObject &MOO, - StringRef Buffer, uint64_t Base, - InMemoryStruct &Res) { - typedef T struct_type; - uint64_t Size = sizeof(struct_type); - - // Check that the buffer contains the expected data. - if (Base + Size > Buffer.size()) { - Res = 0; - return; - } - - // Check whether we can return a direct pointer. - struct_type *Ptr = reinterpret_cast( - const_cast(Buffer.data() + Base)); - if (!MOO.isSwappedEndian()) { - Res = Ptr; - return; - } - - // Otherwise, copy the struct and translate the values. - Res = *Ptr; - SwapStruct(*Res); -} - -/* *** */ - -MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_, - bool Is64Bit_) - : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_), - IsSwappedEndian(IsLittleEndian != sys::IsLittleEndianHost), - HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) { - // Load the common header. - memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header)); - if (IsSwappedEndian) { - SwapValue(Header.Magic); - SwapValue(Header.CPUType); - SwapValue(Header.CPUSubtype); - SwapValue(Header.FileType); - SwapValue(Header.NumLoadCommands); - SwapValue(Header.SizeOfLoadCommands); - SwapValue(Header.Flags); - } - - if (is64Bit()) { - memcpy(&Header64Ext, Buffer->getBuffer().data() + sizeof(Header), - sizeof(Header64Ext)); - if (IsSwappedEndian) { - SwapValue(Header64Ext.Reserved); - } - } - - // Create the load command array if sane. - if (getHeader().NumLoadCommands < (1 << 20)) - LoadCommands = new LoadCommandInfo[getHeader().NumLoadCommands]; -} - -MachOObject::~MachOObject() { - delete [] LoadCommands; -} - -MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer, - std::string *ErrorStr) { - // First, check the magic value and initialize the basic object info. - bool IsLittleEndian = false, Is64Bit = false; - StringRef Magic = Buffer->getBuffer().slice(0, 4); - if (Magic == "\xFE\xED\xFA\xCE") { - } else if (Magic == "\xCE\xFA\xED\xFE") { - IsLittleEndian = true; - } else if (Magic == "\xFE\xED\xFA\xCF") { - Is64Bit = true; - } else if (Magic == "\xCF\xFA\xED\xFE") { - IsLittleEndian = true; - Is64Bit = true; - } else { - if (ErrorStr) *ErrorStr = "not a Mach object file (invalid magic)"; - return 0; - } - - // Ensure that the at least the full header is present. - unsigned HeaderSize = Is64Bit ? macho::Header64Size : macho::Header32Size; - if (Buffer->getBufferSize() < HeaderSize) { - if (ErrorStr) *ErrorStr = "not a Mach object file (invalid header)"; - return 0; - } - - OwningPtr Object(new MachOObject(Buffer, IsLittleEndian, - Is64Bit)); - - // Check for bogus number of load commands. - if (Object->getHeader().NumLoadCommands >= (1 << 20)) { - if (ErrorStr) *ErrorStr = "not a Mach object file (unreasonable header)"; - return 0; - } - - if (ErrorStr) *ErrorStr = ""; - 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!"); - - // Load the command, if necessary. - if (Index >= NumLoadedCommands) { - uint64_t Offset; - if (Index == 0) { - Offset = getHeaderSize(); - } else { - const LoadCommandInfo &Prev = getLoadCommandInfo(Index - 1); - Offset = Prev.Offset + Prev.Command.Size; - } - - LoadCommandInfo &Info = LoadCommands[Index]; - memcpy(&Info.Command, Buffer->getBuffer().data() + Offset, - sizeof(macho::LoadCommand)); - if (IsSwappedEndian) { - SwapValue(Info.Command.Type); - SwapValue(Info.Command.Size); - } - Info.Offset = Offset; - NumLoadedCommands = Index + 1; - } - - return LoadCommands[Index]; -} - -template<> -void SwapStruct(macho::SegmentLoadCommand &Value) { - SwapValue(Value.Type); - SwapValue(Value.Size); - SwapValue(Value.VMAddress); - SwapValue(Value.VMSize); - SwapValue(Value.FileOffset); - SwapValue(Value.FileSize); - SwapValue(Value.MaxVMProtection); - SwapValue(Value.InitialVMProtection); - SwapValue(Value.NumSections); - SwapValue(Value.Flags); -} -void MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI, - InMemoryStruct &Res) const { - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); -} - -template<> -void SwapStruct(macho::Segment64LoadCommand &Value) { - SwapValue(Value.Type); - SwapValue(Value.Size); - SwapValue(Value.VMAddress); - SwapValue(Value.VMSize); - SwapValue(Value.FileOffset); - SwapValue(Value.FileSize); - SwapValue(Value.MaxVMProtection); - SwapValue(Value.InitialVMProtection); - SwapValue(Value.NumSections); - SwapValue(Value.Flags); -} -void MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI, - InMemoryStruct &Res) const { - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); -} - -template<> -void SwapStruct(macho::SymtabLoadCommand &Value) { - SwapValue(Value.Type); - SwapValue(Value.Size); - SwapValue(Value.SymbolTableOffset); - SwapValue(Value.NumSymbolTableEntries); - SwapValue(Value.StringTableOffset); - SwapValue(Value.StringTableSize); -} -void MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI, - InMemoryStruct &Res) const { - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); -} - -template<> -void SwapStruct(macho::DysymtabLoadCommand &Value) { - SwapValue(Value.Type); - SwapValue(Value.Size); - SwapValue(Value.LocalSymbolsIndex); - SwapValue(Value.NumLocalSymbols); - SwapValue(Value.ExternalSymbolsIndex); - SwapValue(Value.NumExternalSymbols); - SwapValue(Value.UndefinedSymbolsIndex); - SwapValue(Value.NumUndefinedSymbols); - SwapValue(Value.TOCOffset); - SwapValue(Value.NumTOCEntries); - SwapValue(Value.ModuleTableOffset); - SwapValue(Value.NumModuleTableEntries); - SwapValue(Value.ReferenceSymbolTableOffset); - SwapValue(Value.NumReferencedSymbolTableEntries); - SwapValue(Value.IndirectSymbolTableOffset); - SwapValue(Value.NumIndirectSymbolTableEntries); - SwapValue(Value.ExternalRelocationTableOffset); - SwapValue(Value.NumExternalRelocationTableEntries); - SwapValue(Value.LocalRelocationTableOffset); - SwapValue(Value.NumLocalRelocationTableEntries); -} -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::LinkerOptionsLoadCommand &Value) { - SwapValue(Value.Type); - SwapValue(Value.Size); - SwapValue(Value.Count); -} -void MachOObject::ReadLinkerOptionsLoadCommand(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); -} - -template<> -void SwapStruct(macho::DataInCodeTableEntry &Value) { - SwapValue(Value.Offset); - SwapValue(Value.Length); - SwapValue(Value.Kind); -} -void MachOObject::ReadDataInCodeTableEntry(uint64_t TableOffset, - unsigned Index, - InMemoryStruct &Res) const { - uint64_t Offset = (TableOffset + - Index * sizeof(macho::DataInCodeTableEntry)); - ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); -} - -void MachOObject::ReadULEB128s(uint64_t Index, - SmallVectorImpl &Out) const { - DataExtractor extractor(Buffer->getBuffer(), true, 0); - - uint32_t offset = Index; - uint64_t data = 0; - while (uint64_t delta = extractor.getULEB128(&offset)) { - data += delta; - Out.push_back(data); - } -} - -/* ** */ -// 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"; -} diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 38198b1793..bb6ca93176 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -119,6 +119,11 @@ void SwapStruct(macho::Header &H) { SwapValue(H.Flags); } +template<> +void SwapStruct(macho::Header64Ext &E) { + SwapValue(E.Reserved); +} + template<> void SwapStruct(macho::SymtabLoadCommand &C) { SwapValue(C.Type); @@ -129,6 +134,30 @@ void SwapStruct(macho::SymtabLoadCommand &C) { SwapValue(C.StringTableSize); } +template<> +void SwapStruct(macho::DysymtabLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.LocalSymbolsIndex); + SwapValue(C.NumLocalSymbols); + SwapValue(C.ExternalSymbolsIndex); + SwapValue(C.NumExternalSymbols); + SwapValue(C.UndefinedSymbolsIndex); + SwapValue(C.NumUndefinedSymbols); + SwapValue(C.TOCOffset); + SwapValue(C.NumTOCEntries); + SwapValue(C.ModuleTableOffset); + SwapValue(C.NumModuleTableEntries); + SwapValue(C.ReferenceSymbolTableOffset); + SwapValue(C.NumReferencedSymbolTableEntries); + SwapValue(C.IndirectSymbolTableOffset); + SwapValue(C.NumIndirectSymbolTableEntries); + SwapValue(C.ExternalRelocationTableOffset); + SwapValue(C.NumExternalRelocationTableEntries); + SwapValue(C.LocalRelocationTableOffset); + SwapValue(C.NumLocalRelocationTableEntries); +} + template<> void SwapStruct(macho::LinkeditDataLoadCommand &C) { SwapValue(C.Type); @@ -165,6 +194,25 @@ void SwapStruct(macho::Segment64LoadCommand &C) { SwapValue(C.Flags); } +template<> +void SwapStruct(macho::IndirectSymbolTableEntry &C) { + SwapValue(C.Index); +} + +template<> +void SwapStruct(macho::LinkerOptionsLoadCommand &C) { + SwapValue(C.Type); + SwapValue(C.Size); + SwapValue(C.Count); +} + +template<> +void SwapStruct(macho::DataInCodeTableEntry &C) { + SwapValue(C.Offset); + SwapValue(C.Length); + SwapValue(C.Kind); +} + template T getStruct(const MachOObjectFile *O, const char *P) { T Cmd; @@ -174,32 +222,20 @@ T getStruct(const MachOObjectFile *O, const char *P) { return Cmd; } -static macho::SegmentLoadCommand -getSegmentLoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - -static macho::Segment64LoadCommand -getSegment64LoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - static uint32_t getSegmentLoadCommandNumSections(const MachOObjectFile *O, const MachOObjectFile::LoadCommandInfo &L) { if (O->is64Bit()) { - macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L); + macho::Segment64LoadCommand S = O->getSegment64LoadCommand(L); return S.NumSections; } - macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L); + macho::SegmentLoadCommand S = O->getSegmentLoadCommand(L); return S.NumSections; } -static const SectionBase * -getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, - unsigned Sec) { +static const char * +getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, + unsigned Sec) { uintptr_t CommandAddr = reinterpret_cast(L.Ptr); bool Is64 = O->is64Bit(); @@ -209,7 +245,7 @@ getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, sizeof(macho::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; - return reinterpret_cast(SectionAddr); + return reinterpret_cast(SectionAddr); } static const char *getPtr(const MachOObjectFile *O, size_t Offset) { @@ -377,7 +413,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64bits, error_code &ec) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), - SymtabLoadCmd(NULL) { + SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) { uint32_t LoadCommandCount = this->getHeader().NumLoadCommands; macho::LoadCommandType SegmentLoadType = is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment; @@ -387,13 +423,14 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, if (Load.C.Type == macho::LCT_Symtab) { assert(!SymtabLoadCmd && "Multiple symbol tables"); SymtabLoadCmd = Load.Ptr; - } - - if (Load.C.Type == SegmentLoadType) { + } else if (Load.C.Type == macho::LCT_Dysymtab) { + assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables"); + DysymtabLoadCmd = Load.Ptr; + } else if (Load.C.Type == SegmentLoadType) { uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); for (unsigned J = 0; J < NumSections; ++J) { - const SectionBase *Sec = getSectionBase(this, Load, J); - Sections.push_back(reinterpret_cast(Sec)); + const char *Sec = getSectionPtr(this, Load, J); + Sections.push_back(Sec); } } @@ -416,10 +453,9 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, StringRef &Res) const { - macho::SymtabLoadCommand S = getSymtabLoadCommand(); - const char *StringTable = getPtr(this, S.StringTableOffset); + StringRef StringTable = getStringTableData(); SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - const char *Start = &StringTable[Entry.StringIndex]; + const char *Start = &StringTable.data()[Entry.StringIndex]; Res = StringRef(Start); return object_error::success; } @@ -1271,6 +1307,18 @@ StringRef MachOObjectFile::getLoadName() const { report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); } +relocation_iterator MachOObjectFile::getSectionRelBegin(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return getSectionRelBegin(DRI); +} + +relocation_iterator MachOObjectFile::getSectionRelEnd(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return getSectionRelEnd(DRI); +} + StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { ArrayRef Raw = getSectionRawFinalSegmentName(Sec); @@ -1375,6 +1423,18 @@ macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { return getStruct(this, Sections[DRI.d.a]); } +macho::Section MachOObjectFile::getSection(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + +macho::Section64 MachOObjectFile::getSection64(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + macho::SymbolTableEntry MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const char *P = reinterpret_cast(DRI.p); @@ -1392,6 +1452,21 @@ MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandIn return getStruct(this, L.Ptr); } +macho::SegmentLoadCommand +MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +macho::Segment64LoadCommand +MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +macho::LinkerOptionsLoadCommand +MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + macho::RelocationEntry MachOObjectFile::getRelocation(DataRefImpl Rel) const { const char *P = reinterpret_cast(Rel.p); @@ -1402,11 +1477,39 @@ macho::Header MachOObjectFile::getHeader() const { return getStruct(this, getPtr(this, 0)); } -macho::SymtabLoadCommand -MachOObjectFile::getSymtabLoadCommand() const { +macho::Header64Ext MachOObjectFile::getHeader64Ext() const { + return + getStruct(this, getPtr(this, sizeof(macho::Header))); +} + +macho::IndirectSymbolTableEntry MachOObjectFile::getIndirectSymbolTableEntry( + const macho::DysymtabLoadCommand &DLC, + unsigned Index) const { + uint64_t Offset = DLC.IndirectSymbolTableOffset + + Index * sizeof(macho::IndirectSymbolTableEntry); + return getStruct(this, getPtr(this, Offset)); +} + +macho::DataInCodeTableEntry +MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, + unsigned Index) const { + uint64_t Offset = DataOffset + Index * sizeof(macho::DataInCodeTableEntry); + return getStruct(this, getPtr(this, Offset)); +} + +macho::SymtabLoadCommand MachOObjectFile::getSymtabLoadCommand() const { return getStruct(this, SymtabLoadCmd); } +macho::DysymtabLoadCommand MachOObjectFile::getDysymtabLoadCommand() const { + return getStruct(this, DysymtabLoadCmd); +} + +StringRef MachOObjectFile::getStringTableData() const { + macho::SymtabLoadCommand S = getSymtabLoadCommand(); + return getData().substr(S.StringTableOffset, S.StringTableSize); +} + bool MachOObjectFile::is64Bit() const { return getType() == getMachOType(false, true) || getType() == getMachOType(true, true); -- cgit v1.2.3-18-g5258