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"
11d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer#include "llvm/ADT/SmallVector.h"
12d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h"
13ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer#include "llvm/Support/DataExtractor.h"
14ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer#include "llvm/Support/Debug.h"
151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Host.h"
16ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer#include "llvm/Support/MemoryBuffer.h"
17ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer#include "llvm/Support/SwapByteOrder.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h"
19fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar
20fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbarusing namespace llvm;
21a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarusing namespace llvm::object;
22a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
234ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar/* Translation Utilities */
244ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
25a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbartemplate<typename T>
26a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarstatic void SwapValue(T &Value) {
27a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  Value = sys::SwapByteOrder(Value);
28a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar}
29fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar
304ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<typename T>
314ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarstatic void SwapStruct(T &Value);
324ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
334ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<typename T>
344ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarstatic void ReadInMemoryStruct(const MachOObject &MOO,
354ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar                               StringRef Buffer, uint64_t Base,
364ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar                               InMemoryStruct<T> &Res) {
374ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  typedef T struct_type;
384ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  uint64_t Size = sizeof(struct_type);
394ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
404ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  // Check that the buffer contains the expected data.
414ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  if (Base + Size >  Buffer.size()) {
424ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar    Res = 0;
434ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar    return;
444ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  }
454ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
464ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  // Check whether we can return a direct pointer.
475a80eefdf7ef9022cd148b9eed16aa3c14b59a56David Greene  struct_type *Ptr = reinterpret_cast<struct_type *>(
485a80eefdf7ef9022cd148b9eed16aa3c14b59a56David Greene                       const_cast<char *>(Buffer.data() + Base));
494ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  if (!MOO.isSwappedEndian()) {
504ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar    Res = Ptr;
514ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar    return;
524ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  }
534ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
544ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  // Otherwise, copy the struct and translate the values.
554ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  Res = *Ptr;
564ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapStruct(*Res);
574ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar}
584ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
594ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar/* *** */
604ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
6195369163f58f06a6494ca9623184a8849ecf85f3Daniel DunbarMachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_,
6295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar                         bool Is64Bit_)
63a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_),
64a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    IsSwappedEndian(IsLittleEndian != sys::isLittleEndianHost()),
65f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar    HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) {
66a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  // Load the common header.
67a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header));
68a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (IsSwappedEndian) {
69a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.Magic);
70a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.CPUType);
71a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.CPUSubtype);
72a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.FileType);
73a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.NumLoadCommands);
74a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.SizeOfLoadCommands);
75a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    SwapValue(Header.Flags);
76a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  }
77a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
78a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (is64Bit()) {
79a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    memcpy(&Header64Ext, Buffer->getBuffer().data() + sizeof(Header),
80a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar           sizeof(Header64Ext));
81a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (IsSwappedEndian) {
82a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      SwapValue(Header64Ext.Reserved);
83a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    }
84a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  }
85a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
86a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  // Create the load command array if sane.
87a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (getHeader().NumLoadCommands < (1 << 20))
88a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    LoadCommands = new LoadCommandInfo[getHeader().NumLoadCommands];
89a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar}
90a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
91a956d8b71755b908d8a150736e8857d2214060c6Daniel DunbarMachOObject::~MachOObject() {
9223dcd00edeea556d26eed0cd2b3807dbd44107abBenjamin Kramer  delete [] LoadCommands;
93fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar}
94fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar
95fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel DunbarMachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer,
96fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar                                         std::string *ErrorStr) {
9795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  // First, check the magic value and initialize the basic object info.
9895369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  bool IsLittleEndian = false, Is64Bit = false;
9995369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  StringRef Magic = Buffer->getBuffer().slice(0, 4);
10095369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  if (Magic == "\xFE\xED\xFA\xCE") {
10195369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  }  else if (Magic == "\xCE\xFA\xED\xFE") {
10295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar    IsLittleEndian = true;
10395369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  } else if (Magic == "\xFE\xED\xFA\xCF") {
10495369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar    Is64Bit = true;
10595369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  } else if (Magic == "\xCF\xFA\xED\xFE") {
10695369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar    IsLittleEndian = true;
10795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar    Is64Bit = true;
10895369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  } else {
109a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (ErrorStr) *ErrorStr = "not a Mach object file (invalid magic)";
110a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    return 0;
111a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  }
112a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
113a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  // Ensure that the at least the full header is present.
114a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  unsigned HeaderSize = Is64Bit ? macho::Header64Size : macho::Header32Size;
115a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (Buffer->getBufferSize() < HeaderSize) {
116a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (ErrorStr) *ErrorStr = "not a Mach object file (invalid header)";
11795369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar    return 0;
11895369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  }
11995369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar
12095369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  OwningPtr<MachOObject> Object(new MachOObject(Buffer, IsLittleEndian,
12195369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar                                                Is64Bit));
12295369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar
123a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  // Check for bogus number of load commands.
124a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (Object->getHeader().NumLoadCommands >= (1 << 20)) {
125a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (ErrorStr) *ErrorStr = "not a Mach object file (unreasonable header)";
126a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    return 0;
127a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  }
128a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
129fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar  if (ErrorStr) *ErrorStr = "";
13095369163f58f06a6494ca9623184a8849ecf85f3Daniel Dunbar  return Object.take();
131fbd25b7d1d030ca0cbea28c690b636c35299826eDaniel Dunbar}
132a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
13371130f8aa1cef096083b95267a8a688a3bef6426Daniel DunbarStringRef MachOObject::getData(size_t Offset, size_t Size) const {
13471130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar  return Buffer->getBuffer().substr(Offset,Size);
13571130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar}
13671130f8aa1cef096083b95267a8a688a3bef6426Daniel Dunbar
137f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbarvoid MachOObject::RegisterStringTable(macho::SymtabLoadCommand &SLC) {
138f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar  HasStringTable = true;
139f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar  StringTable = Buffer->getBuffer().substr(SLC.StringTableOffset,
140f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar                                           SLC.StringTableSize);
141f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar}
142f2e2a5ff04e13720cec0c130c1d88d81d0ae6007Daniel Dunbar
143a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbarconst MachOObject::LoadCommandInfo &
144a956d8b71755b908d8a150736e8857d2214060c6Daniel DunbarMachOObject::getLoadCommandInfo(unsigned Index) const {
145a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  assert(Index < getHeader().NumLoadCommands && "Invalid index!");
146a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
147a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  // Load the command, if necessary.
148a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  if (Index >= NumLoadedCommands) {
149a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    uint64_t Offset;
150a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (Index == 0) {
151a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      Offset = getHeaderSize();
152a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    } else {
153a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      const LoadCommandInfo &Prev = getLoadCommandInfo(Index - 1);
154a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      Offset = Prev.Offset + Prev.Command.Size;
155a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    }
156a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
157a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    LoadCommandInfo &Info = LoadCommands[Index];
158a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    memcpy(&Info.Command, Buffer->getBuffer().data() + Offset,
159a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar           sizeof(macho::LoadCommand));
160a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    if (IsSwappedEndian) {
161a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      SwapValue(Info.Command.Type);
162a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar      SwapValue(Info.Command.Size);
163a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    }
164a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    Info.Offset = Offset;
165a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar    NumLoadedCommands = Index + 1;
166a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  }
167a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar
168a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar  return LoadCommands[Index];
169a956d8b71755b908d8a150736e8857d2214060c6Daniel Dunbar}
1704ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
1714ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<>
1723946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::SegmentLoadCommand &Value) {
1734ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Type);
1744ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Size);
1754ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.VMAddress);
1764ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.VMSize);
1774ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.FileOffset);
1784ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.FileSize);
1794ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.MaxVMProtection);
1804ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.InitialVMProtection);
1814ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.NumSections);
1824ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Flags);
1834ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar}
1844ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarvoid MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI,
1854ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar                         InMemoryStruct<macho::SegmentLoadCommand> &Res) const {
1864ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
1874ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar}
1884ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar
1894ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbartemplate<>
1903946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::Segment64LoadCommand &Value) {
1914ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Type);
1924ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Size);
1934ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.VMAddress);
1944ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.VMSize);
1954ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.FileOffset);
1964ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.FileSize);
1974ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.MaxVMProtection);
1984ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.InitialVMProtection);
1994ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.NumSections);
2004ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  SwapValue(Value.Flags);
2014ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar}
2024ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbarvoid MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI,
2034ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar                       InMemoryStruct<macho::Segment64LoadCommand> &Res) const {
2044ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
2054ba1f5e0011fa0c17ff121634bf8e88270f3b52eDaniel Dunbar}
206f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar
207f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbartemplate<>
2083946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::SymtabLoadCommand &Value) {
209f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.Type);
210f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.Size);
211f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.SymbolTableOffset);
212f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumSymbolTableEntries);
213f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.StringTableOffset);
214f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.StringTableSize);
215f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar}
216f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbarvoid MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI,
217f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar                          InMemoryStruct<macho::SymtabLoadCommand> &Res) const {
218f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
219f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar}
220f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar
221f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbartemplate<>
2223946e3b4764ab0146693aad53687d33b7ae6bb78Benjamin Kramervoid SwapStruct(macho::DysymtabLoadCommand &Value) {
223f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.Type);
224f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.Size);
225a87d7ec234e1d4a31f4403ee9495d7700e6a593cDaniel Dunbar  SwapValue(Value.LocalSymbolsIndex);
226f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumLocalSymbols);
227f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.ExternalSymbolsIndex);
228f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumExternalSymbols);
229f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.UndefinedSymbolsIndex);
230f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumUndefinedSymbols);
231f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.TOCOffset);
232f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumTOCEntries);
233f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.ModuleTableOffset);
234f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumModuleTableEntries);
235f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.ReferenceSymbolTableOffset);
236f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumReferencedSymbolTableEntries);
237f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.IndirectSymbolTableOffset);
238f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumIndirectSymbolTableEntries);
239f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.ExternalRelocationTableOffset);
240f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumExternalRelocationTableEntries);
241f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.LocalRelocationTableOffset);
242f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  SwapValue(Value.NumLocalRelocationTableEntries);
243f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar}
244f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbarvoid MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI,
245f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar                        InMemoryStruct<macho::DysymtabLoadCommand> &Res) const {
246f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
247f879f14cef93fe51ee8c180be7acf70294807b8fDaniel Dunbar}
2484c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar
2494c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbartemplate<>
2509942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramervoid SwapStruct(macho::LinkeditDataLoadCommand &Value) {
2519942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer  SwapValue(Value.Type);
2529942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer  SwapValue(Value.Size);
2539942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer  SwapValue(Value.DataOffset);
2549942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer  SwapValue(Value.DataSize);
2559942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer}
2569942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramervoid MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI,
2579942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer                    InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const {
2589942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
2599942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer}
2609942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramer
2619942acab0a42755637a682308c8262b88cbbb9e9Benjamin Kramertemplate<>
262a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarvoid SwapStruct(macho::LinkerOptionsLoadCommand &Value) {
263a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  SwapValue(Value.Type);
264a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  SwapValue(Value.Size);
265a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  SwapValue(Value.Count);
266a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar}
267a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarvoid MachOObject::ReadLinkerOptionsLoadCommand(const LoadCommandInfo &LCI,
268a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar                   InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const {
269a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
270a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar}
271a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar
272a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbartemplate<>
2734c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbarvoid SwapStruct(macho::IndirectSymbolTableEntry &Value) {
2744c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar  SwapValue(Value.Index);
2754c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar}
2764c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbarvoid
2774c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel DunbarMachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
2784c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar                                          unsigned Index,
2794c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar                   InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const {
2804c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar  uint64_t Offset = (DLC.IndirectSymbolTableOffset +
2814c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar                     Index * sizeof(macho::IndirectSymbolTableEntry));
2824c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
2834c55e0db0f0a095dcd76326bef24d0fe05d2a5e4Daniel Dunbar}
2842acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar
2852acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar
2862acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbartemplate<>
2872acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid SwapStruct(macho::Section &Value) {
2882acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Address);
2892acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Size);
2902acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Offset);
2912acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Align);
2922acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.RelocationTableOffset);
2932acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.NumRelocationTableEntries);
2942acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Flags);
2952acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Reserved1);
2962acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Reserved2);
2972acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar}
2982acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid MachOObject::ReadSection(const LoadCommandInfo &LCI,
2992acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                              unsigned Index,
3002acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                              InMemoryStruct<macho::Section> &Res) const {
3012acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  assert(LCI.Command.Type == macho::LCT_Segment &&
3022acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar         "Unexpected load command info!");
3032acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) +
3042acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                     Index * sizeof(macho::Section));
3052acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
3062acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar}
3072acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar
3082acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbartemplate<>
3092acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid SwapStruct(macho::Section64 &Value) {
3102acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Address);
3112acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Size);
3122acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Offset);
3132acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Align);
3142acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.RelocationTableOffset);
3152acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.NumRelocationTableEntries);
3162acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Flags);
3172acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Reserved1);
3182acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Reserved2);
3192acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  SwapValue(Value.Reserved3);
3202acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar}
3212acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbarvoid MachOObject::ReadSection64(const LoadCommandInfo &LCI,
3222acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                                unsigned Index,
3232acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                                InMemoryStruct<macho::Section64> &Res) const {
3242acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  assert(LCI.Command.Type == macho::LCT_Segment64 &&
3252acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar         "Unexpected load command info!");
3262acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) +
3272acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar                     Index * sizeof(macho::Section64));
3282acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
3292acadbddf6783055249da9fc9ea40a05b83ce56aDaniel Dunbar}
33090e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar
33190e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbartemplate<>
33290e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbarvoid SwapStruct(macho::RelocationEntry &Value) {
33390e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar  SwapValue(Value.Word0);
33490e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar  SwapValue(Value.Word1);
33590e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar}
33690e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbarvoid MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset,
33790e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar                                      unsigned Index,
33890e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar                            InMemoryStruct<macho::RelocationEntry> &Res) const {
33990e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar  uint64_t Offset = (RelocationTableOffset +
34090e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar                     Index * sizeof(macho::RelocationEntry));
34190e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
34290e3e3a429e75a7d3671afcc30ed376b6186fd58Daniel Dunbar}
3432208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar
3442208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbartemplate<>
3452208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid SwapStruct(macho::SymbolTableEntry &Value) {
3462208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.StringIndex);
3472208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.Flags);
3482208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.Value);
3492208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar}
3502208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset,
3512208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                                       unsigned Index,
3522208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                           InMemoryStruct<macho::SymbolTableEntry> &Res) const {
3532208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  uint64_t Offset = (SymbolTableOffset +
3542208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                     Index * sizeof(macho::SymbolTableEntry));
3552208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
3562208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar}
3572208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar
3582208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbartemplate<>
3592208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid SwapStruct(macho::Symbol64TableEntry &Value) {
3602208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.StringIndex);
3612208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.Flags);
3622208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  SwapValue(Value.Value);
3632208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar}
3642208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbarvoid MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset,
3652208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                                       unsigned Index,
3662208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                         InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
3672208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  uint64_t Offset = (SymbolTableOffset +
3682208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar                     Index * sizeof(macho::Symbol64TableEntry));
3692208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
3702208b58b83392b2a3558e556c7447b13c3aea857Daniel Dunbar}
371592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher
3723e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachtemplate<>
3733e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid SwapStruct(macho::DataInCodeTableEntry &Value) {
3743e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  SwapValue(Value.Offset);
3753e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  SwapValue(Value.Length);
3763e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  SwapValue(Value.Kind);
3773e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
3783e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MachOObject::ReadDataInCodeTableEntry(uint64_t TableOffset,
3793e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                                           unsigned Index,
3803e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                       InMemoryStruct<macho::DataInCodeTableEntry> &Res) const {
3813e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  uint64_t Offset = (TableOffset +
3823e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach                     Index * sizeof(macho::DataInCodeTableEntry));
3833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
3843e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach}
385d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer
386d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramervoid MachOObject::ReadULEB128s(uint64_t Index,
387d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer                               SmallVectorImpl<uint64_t> &Out) const {
388ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer  DataExtractor extractor(Buffer->getBuffer(), true, 0);
389ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer
390ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer  uint32_t offset = Index;
391d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer  uint64_t data = 0;
392ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer  while (uint64_t delta = extractor.getULEB128(&offset)) {
393ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer    data += delta;
394ef56d1d35d741da0de6e27717d51564eade63e6dBenjamin Kramer    Out.push_back(data);
395d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer  }
396d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer}
397d4522460d495fb0be3303f0727f9bd00867c0b16Benjamin Kramer
398592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher/* ** */
399592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher// Object Dumping Facilities
400592cf78f842999d3b6c958822927790bc3f45c62Eric Christophervoid MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; }
401592cf78f842999d3b6c958822927790bc3f45c62Eric Christophervoid MachOObject::dumpHeader() const { printHeader(dbgs()); dbgs() << '\n'; }
402592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher
403592cf78f842999d3b6c958822927790bc3f45c62Eric Christophervoid MachOObject::printHeader(raw_ostream &O) const {
404592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('cputype', " << Header.CPUType << ")\n";
405592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('cpusubtype', " << Header.CPUSubtype << ")\n";
406592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('filetype', " << Header.FileType << ")\n";
407592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('num_load_commands', " << Header.NumLoadCommands << ")\n";
408592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n";
409592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "('flag', " << Header.Flags << ")\n";
410b2798fab4ef8d0e0edb349da2c7236e18e00c5b9Eli Bendersky
411592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  // Print extended header if 64-bit.
412592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  if (is64Bit())
413592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher    O << "('reserved', " << Header64Ext.Reserved << ")\n";
414592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher}
415592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher
416592cf78f842999d3b6c958822927790bc3f45c62Eric Christophervoid MachOObject::print(raw_ostream &O) const {
417592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "Header:\n";
418592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  printHeader(O);
419592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "Load Commands:\n";
420b2798fab4ef8d0e0edb349da2c7236e18e00c5b9Eli Bendersky
421592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher  O << "Buffer:\n";
422592cf78f842999d3b6c958822927790bc3f45c62Eric Christopher}
423