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