MachOObject.cpp revision 71130f8aa1cef096083b95267a8a688a3bef6426
1fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar//===- MachOObject.cpp - Mach-O Object File Wrapper -----------------------===// 2fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// 3fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// The LLVM Compiler Infrastructure 4fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// 5fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// License. See LICENSE.TXT for details. 7fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar// 8fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar//===----------------------------------------------------------------------===// 9fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar 10fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar#include "llvm/Object/MachOObject.h" 1195369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar#include "llvm/ADT/StringRef.h" 12fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar#include "llvm/Support/MemoryBuffer.h" 13a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar#include "llvm/System/Host.h" 14a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar#include "llvm/System/SwapByteOrder.h" 15fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar 16fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbarusing namespace llvm; 17a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarusing namespace llvm::object; 18a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 194ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar/* Translation Utilities */ 204ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 21a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbartemplate<typename T> 22a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarstatic void SwapValue(T &Value) { 23a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar Value = sys::SwapByteOrder(Value); 24a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar} 25fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar 264ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<typename T> 274ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarstatic void SwapStruct(T &Value); 284ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 294ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<typename T> 304ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarstatic void ReadInMemoryStruct(const MachOObject &MOO, 314ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar StringRef Buffer, uint64_t Base, 324ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar InMemoryStruct<T> &Res) { 334ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar typedef T struct_type; 344ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar uint64_t Size = sizeof(struct_type); 354ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 364ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar // Check that the buffer contains the expected data. 374ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar if (Base + Size > Buffer.size()) { 384ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar Res = 0; 394ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar return; 404ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar } 414ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 424ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar // Check whether we can return a direct pointer. 434ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar struct_type *Ptr = (struct_type *) (Buffer.data() + Base); 444ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar if (!MOO.isSwappedEndian()) { 454ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar Res = Ptr; 464ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar return; 474ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar } 484ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 494ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar // Otherwise, copy the struct and translate the values. 504ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar Res = *Ptr; 514ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapStruct(*Res); 524ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar} 534ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 544ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar/* *** */ 554ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 5695369163f58f06a6494ca9623184a8849ecf85f3Daniel DunbarMachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_, 5795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar bool Is64Bit_) 58a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_), 59a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar IsSwappedEndian(IsLittleEndian != sys::isLittleEndianHost()), 60f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) { 61a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar // Load the common header. 62a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header)); 63a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (IsSwappedEndian) { 64a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.Magic); 65a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.CPUType); 66a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.CPUSubtype); 67a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.FileType); 68a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.NumLoadCommands); 69a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.SizeOfLoadCommands); 70a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header.Flags); 71a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 72a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 73a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (is64Bit()) { 74a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar memcpy(&Header64Ext, Buffer->getBuffer().data() + sizeof(Header), 75a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar sizeof(Header64Ext)); 76a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (IsSwappedEndian) { 77a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Header64Ext.Reserved); 78a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 79a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 80a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 81a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar // Create the load command array if sane. 82a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (getHeader().NumLoadCommands < (1 << 20)) 83a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar LoadCommands = new LoadCommandInfo[getHeader().NumLoadCommands]; 84a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar} 85a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 86a956d8b71755b908d8a150736e8857d2214060c6Daniel DunbarMachOObject::~MachOObject() { 87a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar delete LoadCommands; 88fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar} 89fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar 90fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel DunbarMachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer, 91fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar std::string *ErrorStr) { 9295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar // First, check the magic value and initialize the basic object info. 9395369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar bool IsLittleEndian = false, Is64Bit = false; 9495369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar StringRef Magic = Buffer->getBuffer().slice(0, 4); 9595369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar if (Magic == "\xFE\xED\xFA\xCE") { 9695369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar } else if (Magic == "\xCE\xFA\xED\xFE") { 9795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar IsLittleEndian = true; 9895369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar } else if (Magic == "\xFE\xED\xFA\xCF") { 9995369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar Is64Bit = true; 10095369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar } else if (Magic == "\xCF\xFA\xED\xFE") { 10195369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar IsLittleEndian = true; 10295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar Is64Bit = true; 10395369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar } else { 104a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (ErrorStr) *ErrorStr = "not a Mach object file (invalid magic)"; 105a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar return 0; 106a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 107a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 108a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar // Ensure that the at least the full header is present. 109a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar unsigned HeaderSize = Is64Bit ? macho::Header64Size : macho::Header32Size; 110a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (Buffer->getBufferSize() < HeaderSize) { 111a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (ErrorStr) *ErrorStr = "not a Mach object file (invalid header)"; 11295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar return 0; 11395369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar } 11495369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar 11595369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar OwningPtr<MachOObject> Object(new MachOObject(Buffer, IsLittleEndian, 11695369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar Is64Bit)); 11795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar 118a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar // Check for bogus number of load commands. 119a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (Object->getHeader().NumLoadCommands >= (1 << 20)) { 120a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (ErrorStr) *ErrorStr = "not a Mach object file (unreasonable header)"; 121a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar return 0; 122a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 123a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 124fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar if (ErrorStr) *ErrorStr = ""; 12595369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar return Object.take(); 126fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar} 127a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 12871130f8aa1cef096083b95267a8a688a3bef6426Daniel DunbarStringRef MachOObject::getData(size_t Offset, size_t Size) const { 12971130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar return Buffer->getBuffer().substr(Offset,Size); 13071130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar} 13171130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar 132f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbarvoid MachOObject::RegisterStringTable(macho::SymtabLoadCommand &SLC) { 133f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar HasStringTable = true; 134f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar StringTable = Buffer->getBuffer().substr(SLC.StringTableOffset, 135f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar SLC.StringTableSize); 136f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar} 137f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar 138a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarconst MachOObject::LoadCommandInfo & 139a956d8b71755b908d8a150736e8857d2214060c6Daniel DunbarMachOObject::getLoadCommandInfo(unsigned Index) const { 140a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar assert(Index < getHeader().NumLoadCommands && "Invalid index!"); 141a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 142a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar // Load the command, if necessary. 143a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (Index >= NumLoadedCommands) { 144a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar uint64_t Offset; 145a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (Index == 0) { 146a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar Offset = getHeaderSize(); 147a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } else { 148a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar const LoadCommandInfo &Prev = getLoadCommandInfo(Index - 1); 149a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar Offset = Prev.Offset + Prev.Command.Size; 150a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 151a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 152a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar LoadCommandInfo &Info = LoadCommands[Index]; 153a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar memcpy(&Info.Command, Buffer->getBuffer().data() + Offset, 154a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar sizeof(macho::LoadCommand)); 155a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar if (IsSwappedEndian) { 156a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Info.Command.Type); 157a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar SwapValue(Info.Command.Size); 158a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 159a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar Info.Offset = Offset; 160a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar NumLoadedCommands = Index + 1; 161a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar } 162a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar 163a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar return LoadCommands[Index]; 164a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar} 1654ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 1664ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<> 1673946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::SegmentLoadCommand &Value) { 1684ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Type); 1694ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Size); 1704ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.VMAddress); 1714ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.VMSize); 1724ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.FileOffset); 1734ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.FileSize); 1744ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.MaxVMProtection); 1754ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.InitialVMProtection); 1764ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.NumSections); 1774ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Flags); 1784ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar} 1794ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarvoid MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI, 1804ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar InMemoryStruct<macho::SegmentLoadCommand> &Res) const { 1814ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); 1824ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar} 1834ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar 1844ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<> 1853946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::Segment64LoadCommand &Value) { 1864ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Type); 1874ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Size); 1884ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.VMAddress); 1894ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.VMSize); 1904ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.FileOffset); 1914ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.FileSize); 1924ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.MaxVMProtection); 1934ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.InitialVMProtection); 1944ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.NumSections); 1954ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar SwapValue(Value.Flags); 1964ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar} 1974ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarvoid MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI, 1984ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar InMemoryStruct<macho::Segment64LoadCommand> &Res) const { 1994ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); 2004ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar} 201f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar 202f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbartemplate<> 2033946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::SymtabLoadCommand &Value) { 204f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.Type); 205f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.Size); 206f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.SymbolTableOffset); 207f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumSymbolTableEntries); 208f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.StringTableOffset); 209f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.StringTableSize); 210f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar} 211f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbarvoid MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI, 212f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar InMemoryStruct<macho::SymtabLoadCommand> &Res) const { 213f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); 214f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar} 215f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar 216f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbartemplate<> 2173946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::DysymtabLoadCommand &Value) { 218f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.Type); 219f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.Size); 220f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.LocalSymbolIndex); 221f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumLocalSymbols); 222f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.ExternalSymbolsIndex); 223f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumExternalSymbols); 224f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.UndefinedSymbolsIndex); 225f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumUndefinedSymbols); 226f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.TOCOffset); 227f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumTOCEntries); 228f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.ModuleTableOffset); 229f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumModuleTableEntries); 230f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.ReferenceSymbolTableOffset); 231f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumReferencedSymbolTableEntries); 232f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.IndirectSymbolTableOffset); 233f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumIndirectSymbolTableEntries); 234f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.ExternalRelocationTableOffset); 235f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumExternalRelocationTableEntries); 236f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.LocalRelocationTableOffset); 237f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar SwapValue(Value.NumLocalRelocationTableEntries); 238f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar} 239f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbarvoid MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI, 240f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar InMemoryStruct<macho::DysymtabLoadCommand> &Res) const { 241f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); 242f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar} 2434c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar 2444c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbartemplate<> 2454c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbarvoid SwapStruct(macho::IndirectSymbolTableEntry &Value) { 2464c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar SwapValue(Value.Index); 2474c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar} 2484c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbarvoid 2494c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel DunbarMachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC, 2504c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar unsigned Index, 2514c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const { 2524c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar uint64_t Offset = (DLC.IndirectSymbolTableOffset + 2534c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar Index * sizeof(macho::IndirectSymbolTableEntry)); 2544c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 2554c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar} 2562acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar 2572acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar 2582acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbartemplate<> 2592acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid SwapStruct(macho::Section &Value) { 2602acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Address); 2612acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Size); 2622acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Offset); 2632acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Align); 2642acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.RelocationTableOffset); 2652acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.NumRelocationTableEntries); 2662acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Flags); 2672acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Reserved1); 2682acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Reserved2); 2692acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar} 2702acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid MachOObject::ReadSection(const LoadCommandInfo &LCI, 2712acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar unsigned Index, 2722acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar InMemoryStruct<macho::Section> &Res) const { 2732acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar assert(LCI.Command.Type == macho::LCT_Segment && 2742acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar "Unexpected load command info!"); 2752acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) + 2762acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar Index * sizeof(macho::Section)); 2772acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 2782acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar} 2792acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar 2802acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbartemplate<> 2812acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid SwapStruct(macho::Section64 &Value) { 2822acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Address); 2832acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Size); 2842acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Offset); 2852acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Align); 2862acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.RelocationTableOffset); 2872acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.NumRelocationTableEntries); 2882acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Flags); 2892acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Reserved1); 2902acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Reserved2); 2912acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar SwapValue(Value.Reserved3); 2922acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar} 2932acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid MachOObject::ReadSection64(const LoadCommandInfo &LCI, 2942acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar unsigned Index, 2952acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar InMemoryStruct<macho::Section64> &Res) const { 2962acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar assert(LCI.Command.Type == macho::LCT_Segment64 && 2972acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar "Unexpected load command info!"); 2982acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) + 2992acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar Index * sizeof(macho::Section64)); 3002acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 3012acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar} 30290e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar 30390e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbartemplate<> 30490e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbarvoid SwapStruct(macho::RelocationEntry &Value) { 30590e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar SwapValue(Value.Word0); 30690e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar SwapValue(Value.Word1); 30790e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar} 30890e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbarvoid MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset, 30990e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar unsigned Index, 31090e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar InMemoryStruct<macho::RelocationEntry> &Res) const { 31190e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar uint64_t Offset = (RelocationTableOffset + 31290e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar Index * sizeof(macho::RelocationEntry)); 31390e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 31490e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar} 3152208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar 3162208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbartemplate<> 3172208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid SwapStruct(macho::SymbolTableEntry &Value) { 3182208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.StringIndex); 3192208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.Flags); 3202208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.Value); 3212208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar} 3222208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset, 3232208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar unsigned Index, 3242208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar InMemoryStruct<macho::SymbolTableEntry> &Res) const { 3252208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar uint64_t Offset = (SymbolTableOffset + 3262208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar Index * sizeof(macho::SymbolTableEntry)); 3272208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 3282208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar} 3292208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar 3302208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbartemplate<> 3312208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid SwapStruct(macho::Symbol64TableEntry &Value) { 3322208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.StringIndex); 3332208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.Flags); 3342208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar SwapValue(Value.Value); 3352208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar} 3362208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset, 3372208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar unsigned Index, 3382208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar InMemoryStruct<macho::Symbol64TableEntry> &Res) const { 3392208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar uint64_t Offset = (SymbolTableOffset + 3402208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar Index * sizeof(macho::Symbol64TableEntry)); 3412208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); 3422208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar} 343