10b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
20b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
30b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//                     The LLVM Compiler Infrastructure
40b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
50b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// This file is distributed under the University of Illinois Open Source
60b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// License. See LICENSE.TXT for details.
70b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
80b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===----------------------------------------------------------------------===//
90b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// This file implements the MachO-specific dumper for llvm-objdump.
110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===----------------------------------------------------------------------===//
130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Object/MachO.h"
150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm-objdump.h"
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm-c/Disassembler.h"
170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/STLExtras.h"
18ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/ADT/StringExtras.h"
19f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/Triple.h"
2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Config/config.h"
216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DIContext.h"
226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DWARF/DWARFContext.h"
230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCAsmInfo.h"
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCContext.h"
25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCDisassembler/MCDisassembler.h"
260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInst.h"
270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstPrinter.h"
280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrDesc.h"
290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrInfo.h"
30c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach#include "llvm/MC/MCRegisterInfo.h"
310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCSubtargetInfo.h"
32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Object/MachOUniversal.h"
33da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola#include "llvm/Support/Casting.h"
340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/CommandLine.h"
350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Debug.h"
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Endian.h"
370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Format.h"
38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/FormattedStream.h"
390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/GraphWriter.h"
40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/LEB128.h"
41f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/MachO.h"
420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/MemoryBuffer.h"
430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetRegistry.h"
440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetSelect.h"
45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/ToolOutputFile.h"
460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/raw_ostream.h"
470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <algorithm>
480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <cstring>
49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error>
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if HAVE_CXXABI_H
5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <cxxabi.h>
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef HAVE_LIBXAR
56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarextern "C" {
57de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include <xar/xar.h>
58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace llvm;
620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace object;
630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool>
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    UseDbg("g",
6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           cl::desc("Print line information from debug info if available"));
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<std::string> DSYMFile("dsym",
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     cl::desc("Use .dSYM file for debug info"));
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool> FullLeadingAddr("full-leading-addr",
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     cl::desc("Print full leading address"));
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> NoLeadingAddr("no-leading-addr",
754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                   cl::desc("Print no leading address"));
764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool> llvm::UniversalHeaders("universal-headers",
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                     cl::desc("Print Mach-O universal headers "
79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                              "(requires -macho)"));
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::ArchiveHeaders("archive-headers",
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                         cl::desc("Print archive headers for Mach-O archives "
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  "(requires -macho)"));
85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    ArchiveMemberOffsets("archive-member-offsets",
886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                         cl::desc("Print the offset to each archive member for "
896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                  "Mach-O archives (requires -macho and "
906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                  "-archive-headers)"));
916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarcl::opt<bool>
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::IndirectSymbols("indirect-symbols",
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                          cl::desc("Print indirect symbol table for Mach-O "
95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                   "objects (requires -macho)"));
96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::DataInCode("data-in-code",
99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                     cl::desc("Print the data in code table for Mach-O objects "
100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                              "(requires -macho)"));
101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    llvm::LinkOptHints("link-opt-hints",
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       cl::desc("Print the linker optimization hints for "
105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                "Mach-O objects (requires -macho)"));
106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarcl::opt<bool>
1084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    llvm::InfoPlist("info-plist",
1094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                    cl::desc("Print the info plist section as strings for "
1104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                             "Mach-O objects (requires -macho)"));
1114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarcl::opt<bool>
1134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    llvm::DylibsUsed("dylibs-used",
1144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     cl::desc("Print the shared libraries used for linked "
1154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                              "Mach-O files (requires -macho)"));
1164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarcl::opt<bool>
1184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    llvm::DylibId("dylib-id",
1194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                  cl::desc("Print the shared library's id for the dylib Mach-O "
1204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                           "file (requires -macho)"));
1214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarcl::opt<bool>
1234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    llvm::NonVerbose("non-verbose",
1244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     cl::desc("Print the info for Mach-O objects in "
1254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                              "non-verbose or numeric form (requires -macho)"));
1264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarcl::opt<bool>
1280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    llvm::ObjcMetaData("objc-meta-data",
1290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       cl::desc("Print the Objective-C runtime meta data for "
1300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                "Mach-O files (requires -macho)"));
1310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarcl::opt<std::string> llvm::DisSymName(
1334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    "dis-symname",
1344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    cl::desc("disassemble just this symbol's instructions (requires -macho"));
1354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> NoSymbolicOperands(
1374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    "no-symbolic-operands",
1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    cl::desc("do not symbolic operands when disassembling (requires -macho)"));
1394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::list<std::string>
141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              cl::ZeroOrMore);
143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ArchAll = false;
145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic std::string ThumbTripleName;
1478c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const Target *GetTarget(const MachOObjectFile *MachOObj,
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               const char **McpuDefault,
15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               const Target **ThumbTarget) {
1510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Figure out the target triple.
152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  llvm::Triple TT(TripleName);
153a99350511cceb8a723800957bae500078f054062Cameron Zwarich  if (TripleName.empty()) {
154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TT = MachOObj->getArchTriple(McpuDefault);
155a99350511cceb8a723800957bae500078f054062Cameron Zwarich    TripleName = TT.str();
156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (TT.getArch() == Triple::arm) {
159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // We've inferred a 32-bit ARM target from the object file. All MachO CPUs
160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // that support ARM are also capable of Thumb mode.
161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    llvm::Triple ThumbTriple = TT;
162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::string ThumbName = (Twine("thumb") + TT.getArchName().substr(3)).str();
163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ThumbTriple.setArchName(ThumbName);
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbTripleName = ThumbTriple.str();
1650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Get the target specific parser.
1680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::string Error;
1690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (TheTarget && ThumbTripleName.empty())
17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return TheTarget;
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  *ThumbTarget = TargetRegistry::lookupTarget(ThumbTripleName, Error);
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (*ThumbTarget)
1750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return TheTarget;
1760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  errs() << "llvm-objdump: error: unable to get target for '";
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!TheTarget)
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << TripleName;
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << ThumbTripleName;
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  errs() << "', see --version and --triple.\n";
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
1840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
1850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
186481837a743be2bd4723d96f304abba93140dc206Owen Andersonstruct SymbolSorter {
187481837a743be2bd4723d96f304abba93140dc206Owen Anderson  bool operator()(const SymbolRef &A, const SymbolRef &B) {
188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<SymbolRef::Type> ATypeOrErr = A.getType();
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!ATypeOrErr) {
190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(ATypeOrErr.takeError(), OS, "");
193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SymbolRef::Type AType = *ATypeOrErr;
197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<SymbolRef::Type> BTypeOrErr = B.getType();
198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!BTypeOrErr) {
199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(BTypeOrErr.takeError(), OS, "");
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SymbolRef::Type BType = *BTypeOrErr;
206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : A.getValue();
207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : B.getValue();
208481837a743be2bd4723d96f304abba93140dc206Owen Anderson    return AAddr < BAddr;
209481837a743be2bd4723d96f304abba93140dc206Owen Anderson  }
2100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer};
2110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
21254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby// Types for the storted data in code table that is built before disassembly
21354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby// and the predicate function to sort them.
21454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef std::pair<uint64_t, DiceRef> DiceTableEntry;
21554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef std::vector<DiceTableEntry> DiceTable;
21654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef DiceTable::iterator dice_table_iterator;
21754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This is used to search for a data in code table entry for the PC being
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// disassembled.  The j parameter has the PC in j.first.  A single data in code
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// table entry can cover many bytes for each of its Kind's.  So if the offset,
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// aka the i.first value, of the data in code table entry plus its Length
22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// covers the PC being searched for this will return true.  If not it will
22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// return false.
22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic bool compareDiceTableEntries(const DiceTableEntry &i,
22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    const DiceTableEntry &j) {
22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t Length;
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  i.second.getLength(Length);
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return j.first >= i.first && j.first < i.first + Length;
23054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby}
23154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
2324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic uint64_t DumpDataInCode(const uint8_t *bytes, uint64_t Length,
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               unsigned short Kind) {
23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Value, Size = 1;
23554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
23654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  switch (Kind) {
23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  default:
2385510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_DATA:
23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Length >= 4) {
24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!NoShowRawInsn)
241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        dumpBytes(makeArrayRef(bytes, 4), outs());
24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
24354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.long " << Value;
24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Size = 4;
24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Length >= 2) {
24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!NoShowRawInsn)
247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        dumpBytes(makeArrayRef(bytes, 2), outs());
24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Value = bytes[1] << 8 | bytes[0];
24954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.short " << Value;
25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Size = 2;
25137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!NoShowRawInsn)
253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        dumpBytes(makeArrayRef(bytes, 2), outs());
25454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      Value = bytes[0];
25554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.byte " << Value;
25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Size = 1;
25754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    }
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Kind == MachO::DICE_KIND_DATA)
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\t@ KIND_DATA\n";
26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\t@ data in code kind = " << Kind << "\n";
26254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
2635510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE8:
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!NoShowRawInsn)
265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      dumpBytes(makeArrayRef(bytes, 1), outs());
26654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[0];
26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\t.byte " << format("%3u", Value) << "\t@ KIND_JUMP_TABLE8\n";
26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Size = 1;
26954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
2705510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE16:
27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!NoShowRawInsn)
272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      dumpBytes(makeArrayRef(bytes, 2), outs());
27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value = bytes[1] << 8 | bytes[0];
27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\t.short " << format("%5u", Value & 0xffff)
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "\t@ KIND_JUMP_TABLE16\n";
27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Size = 2;
27754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
2785510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE32:
27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case MachO::DICE_KIND_ABS_JUMP_TABLE32:
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!NoShowRawInsn)
281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      dumpBytes(makeArrayRef(bytes, 4), outs());
28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\t.long " << Value;
28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Kind == MachO::DICE_KIND_JUMP_TABLE32)
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\t@ KIND_JUMP_TABLE32\n";
28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\t@ KIND_ABS_JUMP_TABLE32\n";
28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Size = 4;
28954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
29054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  }
29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Size;
29254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby}
29354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
2946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic void getSectionsAndSymbols(MachOObjectFile *MachOObj,
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  std::vector<SectionRef> &Sections,
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  std::vector<SymbolRef> &Symbols,
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<uint64_t> &FoundFns,
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  uint64_t &BaseSegmentAddress) {
299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (const SymbolRef &Symbol : MachOObj->symbols()) {
300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<StringRef> SymName = Symbol.getName();
301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!SymName) {
302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(SymName.takeError(), OS, "");
305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!SymName->startswith("ltmp"))
309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Symbols.push_back(Symbol);
310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : MachOObj->sections()) {
313481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getName(SectName);
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sections.push_back(Section);
316481837a743be2bd4723d96f304abba93140dc206Owen Anderson  }
3178c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool BaseSegmentAddressSet = false;
3196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Command : MachOObj->load_commands()) {
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // We found a function starts segment, parse the addresses for later
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // consumption.
323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::linkedit_data_command LLC =
324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          MachOObj->getLinkeditDataLoadCommand(Command);
325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_SEGMENT) {
328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command);
329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      StringRef SegName = SLC.segname;
330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        BaseSegmentAddressSet = true;
332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        BaseSegmentAddress = SLC.vmaddr;
333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                     uint32_t n, uint32_t count,
340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                     uint32_t stride, uint64_t addr) {
341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t nindirectsyms = Dysymtab.nindirectsyms;
343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (n > nindirectsyms)
344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (entries start past the end of the indirect symbol "
345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              "table) (reserved1 field greater than the table size)";
346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (n + count > nindirectsyms)
347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (entries extends past the end of the indirect symbol "
348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              "table)";
349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t cputype = O->getHeader().cputype;
351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (cputype & MachO::CPU_ARCH_ABI64)
352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "address            index";
353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "address    index";
355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (verbose)
356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " name\n";
357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t j = 0; j < count && n + j < nindirectsyms; j++) {
360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (cputype & MachO::CPU_ARCH_ABI64)
361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%016" PRIx64, addr + j * stride) << " ";
362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else
363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format("0x%08" PRIx32, (uint32_t)addr + j * stride) << " ";
364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachO::dysymtab_command Dysymtab = O->getDysymtabLoadCommand();
365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t indirect_symbol = O->getIndirectSymbolTableEntry(Dysymtab, n + j);
366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (indirect_symbol == MachO::INDIRECT_SYMBOL_LOCAL) {
367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "LOCAL\n";
368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (indirect_symbol ==
371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (MachO::INDIRECT_SYMBOL_LOCAL | MachO::INDIRECT_SYMBOL_ABS)) {
372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "LOCAL ABSOLUTE\n";
373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (indirect_symbol == MachO::INDIRECT_SYMBOL_ABS) {
376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "ABSOLUTE\n";
377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("%5u ", indirect_symbol);
3804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (verbose) {
3814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      MachO::symtab_command Symtab = O->getSymtabLoadCommand();
3824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (indirect_symbol < Symtab.nsyms) {
3834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol);
3844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        SymbolRef Symbol = *Sym;
385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Expected<StringRef> SymName = Symbol.getName();
386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!SymName) {
387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          std::string Buf;
388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          raw_string_ostream OS(Buf);
389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          logAllUnhandledErrors(SymName.takeError(), OS, "");
390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          OS.flush();
391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          report_fatal_error(Buf);
392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        }
393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        outs() << *SymName;
3944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      } else {
3954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        outs() << "?";
3964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      }
397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintIndirectSymbols(MachOObjectFile *O, bool verbose) {
4036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Load : O->load_commands()) {
404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Load.C.cmd == MachO::LC_SEGMENT_64) {
405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::segment_command_64 Seg = O->getSegment64LoadCommand(Load);
406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        MachO::section_64 Sec = O->getSection64(Load, J);
408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_SYMBOL_STUBS) {
414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t stride;
415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (section_type == MachO::S_SYMBOL_STUBS)
416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            stride = Sec.reserved2;
417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            stride = 8;
419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (stride == 0) {
420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "Can't print indirect symbols for (" << Sec.segname << ","
421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << Sec.sectname << ") "
422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "(size of stubs in reserved2 field is zero)\n";
423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            continue;
424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t count = Sec.size / stride;
426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "Indirect symbols for (" << Sec.segname << ","
427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << Sec.sectname << ") " << count << " entries";
428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t n = Sec.reserved1;
429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Load.C.cmd == MachO::LC_SEGMENT) {
433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::segment_command Seg = O->getSegmentLoadCommand(Load);
434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        MachO::section Sec = O->getSection(Load, J);
436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            section_type == MachO::S_SYMBOL_STUBS) {
442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t stride;
443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (section_type == MachO::S_SYMBOL_STUBS)
444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            stride = Sec.reserved2;
445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            stride = 4;
447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (stride == 0) {
448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "Can't print indirect symbols for (" << Sec.segname << ","
449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << Sec.sectname << ") "
450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "(size of stubs in reserved2 field is zero)\n";
451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            continue;
452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t count = Sec.size / stride;
454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "Indirect symbols for (" << Sec.segname << ","
455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << Sec.sectname << ") " << count << " entries";
456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t n = Sec.reserved1;
457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          PrintIndirectSymbolTable(O, verbose, n, count, stride, Sec.addr);
458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintDataInCodeTable(MachOObjectFile *O, bool verbose) {
465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachO::linkedit_data_command DIC = O->getDataInCodeLoadCommand();
466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t nentries = DIC.datasize / sizeof(struct MachO::data_in_code_entry);
467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "Data in code table (" << nentries << " entries)\n";
468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "offset     length kind\n";
469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (dice_iterator DI = O->begin_dices(), DE = O->end_dices(); DI != DE;
470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines       ++DI) {
471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t Offset;
472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DI->getOffset(Offset);
473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("0x%08" PRIx32, Offset) << " ";
474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint16_t Length;
475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DI->getLength(Length);
476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("%6u", Length) << " ";
477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint16_t Kind;
478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DI->getKind(Kind);
479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (verbose) {
480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      switch (Kind) {
481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::DICE_KIND_DATA:
482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "DATA";
483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::DICE_KIND_JUMP_TABLE8:
485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "JUMP_TABLE8";
486ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
487ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::DICE_KIND_JUMP_TABLE16:
488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "JUMP_TABLE16";
489ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
490ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::DICE_KIND_JUMP_TABLE32:
491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "JUMP_TABLE32";
492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::DICE_KIND_ABS_JUMP_TABLE32:
494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "ABS_JUMP_TABLE32";
495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      default:
497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("0x%04" PRIx32, Kind);
498ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else
501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%04" PRIx32, Kind);
502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintLinkOptHints(MachOObjectFile *O) {
507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachO::linkedit_data_command LohLC = O->getLinkOptHintsLoadCommand();
508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *loh = O->getData().substr(LohLC.dataoff, 1).data();
509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t nloh = LohLC.datasize;
510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "Linker optimiztion hints (" << nloh << " total bytes)\n";
511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < nloh;) {
512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned n;
513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint64_t identifier = decodeULEB128((const uint8_t *)(loh + i), &n);
514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    i += n;
515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "    identifier " << identifier << " ";
516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (i >= nloh)
517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return;
518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (identifier) {
519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 1:
520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpAdrp\n";
521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 2:
523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpLdr\n";
524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 3:
526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpAddLdr\n";
527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 4:
529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpLdrGotLdr\n";
530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 5:
532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpAddStr\n";
533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 6:
535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpLdrGotStr\n";
536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 7:
538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpAdd\n";
539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case 8:
541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "AdrpLdrGot\n";
542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "Unknown identifier value\n";
545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint64_t narguments = decodeULEB128((const uint8_t *)(loh + i), &n);
548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    i += n;
549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "    narguments " << narguments << "\n";
550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (i >= nloh)
551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return;
552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (uint32_t j = 0; j < narguments; j++) {
554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint64_t value = decodeULEB128((const uint8_t *)(loh + i), &n);
555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      i += n;
556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "\tvalue " << format("0x%" PRIx64, value) << "\n";
557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (i >= nloh)
558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return;
559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
5634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void PrintDylibs(MachOObjectFile *O, bool JustId) {
5646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Index = 0;
5656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Load : O->load_commands()) {
5664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) ||
5674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB ||
5684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     Load.C.cmd == MachO::LC_LOAD_DYLIB ||
5694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
5704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     Load.C.cmd == MachO::LC_REEXPORT_DYLIB ||
5714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
5724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) {
5734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      MachO::dylib_command dl = O->getDylibIDLoadCommand(Load);
5744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (dl.dylib.name < dl.cmdsize) {
5754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        const char *p = (const char *)(Load.Ptr) + dl.dylib.name;
5764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        if (JustId)
5774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << p << "\n";
5784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else {
5794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "\t" << p;
5804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << " (compatibility version "
5814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
5824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
5834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << (dl.dylib.compatibility_version & 0xff) << ",";
5844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << " current version "
5854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << ((dl.dylib.current_version >> 16) & 0xffff) << "."
5864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << ((dl.dylib.current_version >> 8) & 0xff) << "."
5874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                 << (dl.dylib.current_version & 0xff) << ")\n";
5884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        }
5894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      } else {
5904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        outs() << "\tBad offset (" << dl.dylib.name << ") for name of ";
5914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        if (Load.C.cmd == MachO::LC_ID_DYLIB)
5924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_ID_DYLIB ";
5934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else if (Load.C.cmd == MachO::LC_LOAD_DYLIB)
5944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_LOAD_DYLIB ";
5954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB)
5964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_LOAD_WEAK_DYLIB ";
5974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB)
5984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_LAZY_LOAD_DYLIB ";
5994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB)
6004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_REEXPORT_DYLIB ";
6014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
6024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_LOAD_UPWARD_DYLIB ";
6034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        else
6044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          outs() << "LC_??? ";
6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        outs() << "command " << Index++ << "\n";
6064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      }
6074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
6084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
6094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
6104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinestypedef DenseMap<uint64_t, StringRef> SymbolAddressMap;
612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void CreateSymbolAddressMap(MachOObjectFile *O,
614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                   SymbolAddressMap *AddrMap) {
615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Create a map of symbol addresses to symbol names.
616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (const SymbolRef &Symbol : O->symbols()) {
617de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<SymbolRef::Type> STOrErr = Symbol.getType();
618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!STOrErr) {
619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(STOrErr.takeError(), OS, "");
622de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
624de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
625de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    SymbolRef::Type ST = *STOrErr;
626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ST == SymbolRef::ST_Other) {
628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t Address = Symbol.getValue();
629de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymNameOrErr = Symbol.getName();
630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymNameOrErr) {
631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
632de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
633de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymNameOrErr.takeError(), OS, "");
634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
635de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
636de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StringRef SymName = *SymNameOrErr;
6380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (!SymName.startswith(".objc"))
6390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        (*AddrMap)[Address] = SymName;
640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
643ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// GuessSymbolName is passed the address of what might be a symbol and a
645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// pointer to the SymbolAddressMap.  It returns the name of a symbol
646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// with that address or nullptr if no symbol is found with that address.
647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic const char *GuessSymbolName(uint64_t value, SymbolAddressMap *AddrMap) {
648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *SymbolName = nullptr;
649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // A DenseMap can't lookup up some values.
650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (value != 0xffffffffffffffffULL && value != 0xfffffffffffffffeULL) {
651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    StringRef name = AddrMap->lookup(value);
652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!name.empty())
653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      SymbolName = name.data();
654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return SymbolName;
656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpCstringChar(const char c) {
659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  char p[2];
660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  p[0] = c;
661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  p[1] = '\0';
662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs().write_escaped(p);
663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpCstringSection(MachOObjectFile *O, const char *sect,
666ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               uint32_t sect_size, uint64_t sect_addr,
667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               bool print_addresses) {
668ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i++) {
669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (print_addresses) {
670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
672ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
673ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
674ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
675ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (; i < sect_size && sect[i] != '\0'; i++)
676ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DumpCstringChar(sect[i]);
677ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (i < sect_size && sect[i] == '\0')
678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "\n";
679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral4(uint32_t l, float f) {
683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l);
684ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if ((l & 0x7f800000) != 0x7f800000)
685ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format(" (%.16e)\n", f);
686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else {
687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (l == 0x7f800000)
688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (+Infinity)\n";
689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else if (l == 0xff800000)
690ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (-Infinity)\n";
691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else if ((l & 0x00400000) == 0x00400000)
692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (non-signaling Not-a-Number)\n";
693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else
694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (signaling Not-a-Number)\n";
695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
697ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral4Section(MachOObjectFile *O, const char *sect,
699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                uint32_t sect_size, uint64_t sect_addr,
700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                bool print_addresses) {
701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (print_addresses) {
703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    float f;
709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&f, sect + i, sizeof(float));
710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->isLittleEndian() != sys::IsLittleEndianHost)
711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(f);
712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t l;
713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l, sect + i, sizeof(uint32_t));
714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->isLittleEndian() != sys::IsLittleEndianHost)
715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l);
716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DumpLiteral4(l, f);
717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral8(MachOObjectFile *O, uint32_t l0, uint32_t l1,
721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                         double d) {
722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l0) << " " << format("0x%08" PRIx32, l1);
723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t Hi, Lo;
724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Hi = (O->isLittleEndian()) ? l1 : l0;
725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Lo = (O->isLittleEndian()) ? l0 : l1;
726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
727ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Hi is the high word, so this is equivalent to if(isfinite(d))
728ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if ((Hi & 0x7ff00000) != 0x7ff00000)
729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format(" (%.16e)\n", d);
730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else {
731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Hi == 0x7ff00000 && Lo == 0)
732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (+Infinity)\n";
733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else if (Hi == 0xfff00000 && Lo == 0)
734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (-Infinity)\n";
735ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else if ((Hi & 0x00080000) == 0x00080000)
736ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (non-signaling Not-a-Number)\n";
737ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else
738ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (signaling Not-a-Number)\n";
739ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
740ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
741ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
742ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral8Section(MachOObjectFile *O, const char *sect,
743ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                uint32_t sect_size, uint64_t sect_addr,
744ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                bool print_addresses) {
745ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
746ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (print_addresses) {
747ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
748ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
750ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
751ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
752ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    double d;
753ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&d, sect + i, sizeof(double));
754ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->isLittleEndian() != sys::IsLittleEndianHost)
755ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(d);
756ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t l0, l1;
757ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l0, sect + i, sizeof(uint32_t));
758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->isLittleEndian() != sys::IsLittleEndianHost) {
760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l0);
761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l1);
762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DumpLiteral8(O, l0, l1, d);
764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l0) << " ";
769ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l1) << " ";
770ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l2) << " ";
771ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("0x%08" PRIx32, l3) << "\n";
772ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                 uint32_t sect_size, uint64_t sect_addr,
776ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                 bool print_addresses) {
777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i += 16) {
778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (print_addresses) {
779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
782ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
783ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t l0, l1, l2, l3;
785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l0, sect + i, sizeof(uint32_t));
786ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l1, sect + i + sizeof(uint32_t), sizeof(uint32_t));
787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l2, sect + i + 2 * sizeof(uint32_t), sizeof(uint32_t));
788ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    memcpy(&l3, sect + i + 3 * sizeof(uint32_t), sizeof(uint32_t));
789ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->isLittleEndian() != sys::IsLittleEndianHost) {
790ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l0);
791ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l1);
792ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l2);
793ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      sys::swapByteOrder(l3);
794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
795ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DumpLiteral16(l0, l1, l2, l3);
796ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
798ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
799ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpLiteralPointerSection(MachOObjectFile *O,
800ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                      const SectionRef &Section,
801ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                      const char *sect, uint32_t sect_size,
802ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                      uint64_t sect_addr,
803ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                      bool print_addresses) {
804ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Collect the literal sections in this Mach-O file.
805ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::vector<SectionRef> LiteralSections;
806ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (const SectionRef &Section : O->sections()) {
807ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DataRefImpl Ref = Section.getRawDataRefImpl();
808ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t section_type;
809ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->is64Bit()) {
810ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const MachO::section_64 Sec = O->getSection64(Ref);
811ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      section_type = Sec.flags & MachO::SECTION_TYPE;
812ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
813ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const MachO::section Sec = O->getSection(Ref);
814ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      section_type = Sec.flags & MachO::SECTION_TYPE;
815ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
816ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (section_type == MachO::S_CSTRING_LITERALS ||
817ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        section_type == MachO::S_4BYTE_LITERALS ||
818ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        section_type == MachO::S_8BYTE_LITERALS ||
819ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        section_type == MachO::S_16BYTE_LITERALS)
820ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      LiteralSections.push_back(Section);
821ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
822ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
823ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Set the size of the literal pointer.
824ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t lp_size = O->is64Bit() ? 8 : 4;
825ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Collect the external relocation symbols for the literal pointers.
827ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (const RelocationRef &Reloc : Section.relocations()) {
829ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DataRefImpl Rel;
830ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachO::any_relocation_info RE;
831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool isExtern = false;
832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Rel = Reloc.getRawDataRefImpl();
833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    RE = O->getRelocation(Rel);
834ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    isExtern = O->getPlainRelocationExternal(RE);
835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (isExtern) {
836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t RelocOffset = Reloc.getOffset();
837ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      symbol_iterator RelocSym = Reloc.getSymbol();
838ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
839ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
840ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  array_pod_sort(Relocs.begin(), Relocs.end());
842ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Dump each literal pointer.
844ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i += lp_size) {
845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (print_addresses) {
846ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
851ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint64_t lp;
852ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->is64Bit()) {
853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      memcpy(&lp, sect + i, sizeof(uint64_t));
854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->isLittleEndian() != sys::IsLittleEndianHost)
855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(lp);
856ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t li;
858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      memcpy(&li, sect + i, sizeof(uint32_t));
859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->isLittleEndian() != sys::IsLittleEndianHost)
860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(li);
861ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      lp = li;
862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
863ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // First look for an external relocation entry for this literal pointer.
8654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    auto Reloc = std::find_if(
8664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        Relocs.begin(), Relocs.end(),
8674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        [&](const std::pair<uint64_t, SymbolRef> &P) { return P.first == i; });
8684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (Reloc != Relocs.end()) {
8694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      symbol_iterator RelocSym = Reloc->second;
870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymName = RelocSym->getName();
871de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymName) {
872de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
873de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
874de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymName.takeError(), OS, "");
875de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
878f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << "external relocation entry for symbol:" << *SymName << "\n";
879ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
8804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
881ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
882ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // For local references see what the section the literal pointer points to.
8834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    auto Sect = std::find_if(LiteralSections.begin(), LiteralSections.end(),
8844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                             [&](const SectionRef &R) {
8854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                               return lp >= R.getAddress() &&
8864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                      lp < R.getAddress() + R.getSize();
8874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                             });
8884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (Sect == LiteralSections.end()) {
8894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
8904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      continue;
8914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
892ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    uint64_t SectAddress = Sect->getAddress();
8944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    uint64_t SectSize = Sect->getSize();
8954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
8964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    StringRef SectName;
8974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    Sect->getName(SectName);
8984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    DataRefImpl Ref = Sect->getRawDataRefImpl();
8994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
9004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    outs() << SegmentName << ":" << SectName << ":";
9014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
9024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    uint32_t section_type;
9034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (O->is64Bit()) {
9044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      const MachO::section_64 Sec = O->getSection64(Ref);
9054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      section_type = Sec.flags & MachO::SECTION_TYPE;
9064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    } else {
9074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      const MachO::section Sec = O->getSection(Ref);
9084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      section_type = Sec.flags & MachO::SECTION_TYPE;
9094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
9104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
9114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    StringRef BytesStr;
9124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    Sect->getContents(BytesStr);
9134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
9144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
9154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    switch (section_type) {
9164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::S_CSTRING_LITERALS:
9174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      for (uint64_t i = lp - SectAddress; i < SectSize && Contents[i] != '\0';
9184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar           i++) {
9194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        DumpCstringChar(Contents[i]);
9204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      }
9214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      outs() << "\n";
9224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
9234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::S_4BYTE_LITERALS:
9244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      float f;
9254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
9264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      uint32_t l;
9274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
9284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (O->isLittleEndian() != sys::IsLittleEndianHost) {
9294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(f);
9304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l);
9314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      }
9324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      DumpLiteral4(l, f);
9334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
9344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::S_8BYTE_LITERALS: {
9354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      double d;
9364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
9374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      uint32_t l0, l1;
9384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
9394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
9404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar             sizeof(uint32_t));
9414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (O->isLittleEndian() != sys::IsLittleEndianHost) {
9424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(f);
9434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l0);
9444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l1);
945ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
9464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      DumpLiteral8(O, l0, l1, d);
9474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
9484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
9494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::S_16BYTE_LITERALS: {
9504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      uint32_t l0, l1, l2, l3;
9514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
9524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
9534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar             sizeof(uint32_t));
9544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
9554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar             sizeof(uint32_t));
9564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
9574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar             sizeof(uint32_t));
9584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (O->isLittleEndian() != sys::IsLittleEndianHost) {
9594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l0);
9604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l1);
9614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l2);
9624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        sys::swapByteOrder(l3);
9634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      }
9644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      DumpLiteral16(l0, l1, l2, l3);
9654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
9664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpInitTermPointerSection(MachOObjectFile *O, const char *sect,
972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       uint32_t sect_size, uint64_t sect_addr,
973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       SymbolAddressMap *AddrMap,
974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       bool verbose) {
975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t stride;
976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  stride = (O->is64Bit()) ? sizeof(uint64_t) : sizeof(uint32_t);
977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < sect_size; i += stride) {
978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *SymbolName = nullptr;
979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (O->is64Bit()) {
980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%016" PRIx64, sect_addr + i * stride) << " ";
981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint64_t pointer_value;
982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      memcpy(&pointer_value, sect + i, stride);
983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->isLittleEndian() != sys::IsLittleEndianHost)
984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(pointer_value);
985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%016" PRIx64, pointer_value);
986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (verbose)
987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        SymbolName = GuessSymbolName(pointer_value, AddrMap);
988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
989ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%08" PRIx64, sect_addr + i * stride) << " ";
990ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t pointer_value;
991ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      memcpy(&pointer_value, sect + i, stride);
992ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->isLittleEndian() != sys::IsLittleEndianHost)
993ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(pointer_value);
994ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("0x%08" PRIx32, pointer_value);
995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (verbose)
996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        SymbolName = GuessSymbolName(pointer_value, AddrMap);
997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (SymbolName)
999ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " " << SymbolName;
1000ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
1001ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1002ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1003ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1004ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpRawSectionContents(MachOObjectFile *O, const char *sect,
1005ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                   uint32_t size, uint64_t addr) {
1006ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t cputype = O->getHeader().cputype;
1007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (cputype == MachO::CPU_TYPE_I386 || cputype == MachO::CPU_TYPE_X86_64) {
1008ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t j;
1009ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (uint32_t i = 0; i < size; i += j, addr += j) {
1010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
1011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, addr) << "\t";
1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
10134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        outs() << format("%08" PRIx64, addr) << "\t";
1014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (j = 0; j < 16 && i + j < size; j++) {
1015ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint8_t byte_word = *(sect + i + j);
1016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1018ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "\n";
1019ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1020ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
1021ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t j;
1022ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (uint32_t i = 0; i < size; i += j, addr += j) {
1023ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (O->is64Bit())
1024ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format("%016" PRIx64, addr) << "\t";
1025ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else
1026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << format("%08" PRIx64, addr) << "\t";
1027ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (j = 0; j < 4 * sizeof(int32_t) && i + j < size;
1028ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           j += sizeof(int32_t)) {
1029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (i + j + sizeof(int32_t) <= size) {
1030ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          uint32_t long_word;
1031ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&long_word, sect + i + j, sizeof(int32_t));
1032ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (O->isLittleEndian() != sys::IsLittleEndianHost)
1033ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            sys::swapByteOrder(long_word);
1034ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << format("%08" PRIx32, long_word) << " ";
1035ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
1036ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          for (uint32_t k = 0; i + j + k < size; k++) {
1037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            uint8_t byte_word = *(sect + i + j + k);
1038ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << format("%02" PRIx32, (uint32_t)byte_word) << " ";
1039ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1040ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1041ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1042ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "\n";
1043ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1044ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1045ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1046ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1047ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
1048ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                             StringRef DisSegName, StringRef DisSectName);
10490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void DumpProtocolSection(MachOObjectFile *O, const char *sect,
10500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                uint32_t size, uint32_t addr);
1051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef HAVE_LIBXAR
1052de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
1053de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                uint32_t size, bool verbose,
1054de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                bool PrintXarHeader, bool PrintXarFileHeaders,
1055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                std::string XarMemberName);
1056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif // defined(HAVE_LIBXAR)
1057ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1058ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DumpSectionContents(StringRef Filename, MachOObjectFile *O,
1059ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                bool verbose) {
1060ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SymbolAddressMap AddrMap;
1061ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (verbose)
1062ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    CreateSymbolAddressMap(O, &AddrMap);
1063ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < FilterSections.size(); ++i) {
1065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    StringRef DumpSection = FilterSections[i];
1066ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    std::pair<StringRef, StringRef> DumpSegSectName;
1067ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DumpSegSectName = DumpSection.split(',');
1068ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    StringRef DumpSegName, DumpSectName;
1069ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (DumpSegSectName.second.size()) {
1070ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DumpSegName = DumpSegSectName.first;
1071ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DumpSectName = DumpSegSectName.second;
1072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
1073ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DumpSegName = "";
1074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DumpSectName = DumpSegSectName.first;
1075ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (const SectionRef &Section : O->sections()) {
1077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      StringRef SectName;
1078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Section.getName(SectName);
1079ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DataRefImpl Ref = Section.getRawDataRefImpl();
1080ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      StringRef SegName = O->getSectionFinalSegmentName(Ref);
1081ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if ((DumpSegName.empty() || SegName == DumpSegName) &&
1082ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          (SectName == DumpSectName)) {
10830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1084ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint32_t section_flags;
1085ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (O->is64Bit()) {
1086ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          const MachO::section_64 Sec = O->getSection64(Ref);
1087ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          section_flags = Sec.flags;
1088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
1090ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          const MachO::section Sec = O->getSection(Ref);
1091ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          section_flags = Sec.flags;
1092ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1093ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint32_t section_type = section_flags & MachO::SECTION_TYPE;
1094ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1095ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        StringRef BytesStr;
1096ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Section.getContents(BytesStr);
1097ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        const char *sect = reinterpret_cast<const char *>(BytesStr.data());
1098ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint32_t sect_size = BytesStr.size();
1099ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        uint64_t sect_addr = Section.getAddress();
1100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
11010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "Contents of (" << SegName << "," << SectName
11020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar               << ") section\n";
11030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (verbose) {
1105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if ((section_flags & MachO::S_ATTR_PURE_INSTRUCTIONS) ||
1106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              (section_flags & MachO::S_ATTR_SOME_INSTRUCTIONS)) {
1107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DisassembleMachO(Filename, O, SegName, SectName);
1108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            continue;
1109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
11104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          if (SegName == "__TEXT" && SectName == "__info_plist") {
11114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            outs() << sect;
11124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            continue;
11134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          }
11140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          if (SegName == "__OBJC" && SectName == "__protocol") {
11150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            DumpProtocolSection(O, sect, sect_size, sect_addr);
11160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            continue;
11170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          }
1118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef HAVE_LIBXAR
1119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (SegName == "__LLVM" && SectName == "__bundle") {
1120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            DumpBitcodeSection(O, sect, sect_size, verbose, !NoSymbolicOperands,
1121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                               ArchiveHeaders, "");
1122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            continue;
1123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          }
1124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif // defined(HAVE_LIBXAR)
1125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          switch (section_type) {
1126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_REGULAR:
1127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DumpRawSectionContents(O, sect, sect_size, sect_addr);
1128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_ZEROFILL:
1130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "zerofill section and has no contents in the file\n";
1131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_CSTRING_LITERALS:
11334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            DumpCstringSection(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_4BYTE_LITERALS:
11364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            DumpLiteral4Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_8BYTE_LITERALS:
11394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            DumpLiteral8Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
1140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_16BYTE_LITERALS:
11420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            DumpLiteral16Section(O, sect, sect_size, sect_addr, !NoLeadingAddr);
11430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            break;
1144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_LITERAL_POINTERS:
1145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
11464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                      !NoLeadingAddr);
1147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_MOD_INIT_FUNC_POINTERS:
1149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          case MachO::S_MOD_TERM_FUNC_POINTERS:
1150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,
1151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       verbose);
1152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          default:
1154ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "Unknown section type ("
1155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << format("0x%08" PRIx32, section_type) << ")\n";
1156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DumpRawSectionContents(O, sect, sect_size, sect_addr);
1157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            break;
1158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
1160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (section_type == MachO::S_ZEROFILL)
1161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "zerofill section and has no contents in the file\n";
1162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
1163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            DumpRawSectionContents(O, sect, sect_size, sect_addr);
1164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
11704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void DumpInfoPlistSectionContents(StringRef Filename,
11714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                         MachOObjectFile *O) {
11724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
11734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    StringRef SectName;
11744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    Section.getName(SectName);
11754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    DataRefImpl Ref = Section.getRawDataRefImpl();
11764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    StringRef SegName = O->getSectionFinalSegmentName(Ref);
11774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (SegName == "__TEXT" && SectName == "__info_plist") {
11784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
11794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      StringRef BytesStr;
11804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      Section.getContents(BytesStr);
11814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      const char *sect = reinterpret_cast<const char *>(BytesStr.data());
11824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      outs() << sect;
11834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return;
11844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
11854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
11864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
11874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
1188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// checkMachOAndArchFlags() checks to see if the ObjectFile is a Mach-O file
1189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// and if it is and there is a list of architecture flags is specified then
1190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// check to make sure this Mach-O file is one of those architectures or all
1191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// architectures were specified.  If not then an error is generated and this
1192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// routine returns false.  Else it returns true.
1193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
1194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) {
1195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
1196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool ArchFound = false;
1197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachO::mach_header H;
1198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachO::mach_header_64 H_64;
1199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Triple T;
1200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (MachO->is64Bit()) {
1201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      H_64 = MachO->MachOObjectFile::getHeader64();
1202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype);
1203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
1204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      H = MachO->MachOObjectFile::getHeader();
1205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype);
1206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned i;
1208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (i = 0; i < ArchFlags.size(); ++i) {
1209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (ArchFlags[i] == T.getArchName())
1210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ArchFound = true;
1211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!ArchFound) {
1214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      errs() << "llvm-objdump: file: " + Filename + " does not contain "
1215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             << "architecture: " + ArchFlags[i] + "\n";
1216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return true;
1220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
12220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void printObjcMetaData(MachOObjectFile *O, bool verbose);
12230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// ProcessMachO() is passed a single opened Mach-O file, which may be an
1225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// archive member and or in a slice of a universal file.  It prints the
1226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// the file name and header info and then processes it according to the
1227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// command line options.
1228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
1229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                         StringRef ArchiveMemberName = StringRef(),
1230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                         StringRef ArchitectureName = StringRef()) {
1231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If we are doing some processing here on the Mach-O file print the header
1232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // info.  And don't print it otherwise like in the case of printing the
1233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // UniversalHeaders or ArchiveHeaders.
1234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable ||
1235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints ||
1236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      DylibsUsed || DylibId || ObjcMetaData || (FilterSections.size() != 0)) {
1237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << Filename;
1238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!ArchiveMemberName.empty())
1239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << '(' << ArchiveMemberName << ')';
1240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!ArchitectureName.empty())
1241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (architecture " << ArchitectureName << ")";
1242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << ":\n";
1243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Disassemble)
1246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DisassembleMachO(Filename, MachOOF, "__TEXT", "__text");
1247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (IndirectSymbols)
12484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    PrintIndirectSymbols(MachOOF, !NonVerbose);
1249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (DataInCode)
12504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    PrintDataInCodeTable(MachOOF, !NonVerbose);
1251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (LinkOptHints)
1252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PrintLinkOptHints(MachOOF);
1253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Relocations)
1254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PrintRelocations(MachOOF);
1255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (SectionHeaders)
1256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PrintSectionHeaders(MachOOF);
1257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (SectionContents)
1258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PrintSectionContents(MachOOF);
1259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (FilterSections.size() != 0)
12604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    DumpSectionContents(Filename, MachOOF, !NonVerbose);
12614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (InfoPlist)
12624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    DumpInfoPlistSectionContents(Filename, MachOOF);
12634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (DylibsUsed)
12644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    PrintDylibs(MachOOF, false);
12654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (DylibId)
12664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    PrintDylibs(MachOOF, true);
1267de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (SymbolTable) {
1268de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    StringRef ArchiveName = ArchiveMemberName == StringRef() ? "" : Filename;
1269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    PrintSymbolTable(MachOOF, ArchiveName, ArchitectureName);
1270de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (UnwindInfo)
1272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printMachOUnwindInfo(MachOOF);
1273de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (PrivateHeaders) {
1274de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    printMachOFileHeader(MachOOF);
1275de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    printMachOLoadCommands(MachOOF);
1276de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1277de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (FirstPrivateHeader)
1278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printMachOFileHeader(MachOOF);
12790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (ObjcMetaData)
12800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    printObjcMetaData(MachOOF, !NonVerbose);
1281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ExportsTrie)
1282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printExportsTrie(MachOOF);
1283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Rebase)
1284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printRebaseTable(MachOOF);
1285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Bind)
1286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printBindTable(MachOOF);
1287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (LazyBind)
1288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printLazyBindTable(MachOOF);
1289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (WeakBind)
1290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printWeakBindTable(MachOOF);
1291de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (DwarfDumpType != DIDT_Null) {
1293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
1294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Dump the complete DWARF structure.
1295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
1296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// printUnknownCPUType() helps print_fat_headers for unknown CPU's.
1300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void printUnknownCPUType(uint32_t cputype, uint32_t cpusubtype) {
1301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    cputype (" << cputype << ")\n";
1302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    cpusubtype (" << cpusubtype << ")\n";
1303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// printCPUType() helps print_fat_headers by printing the cputype and
1306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// pusubtype (symbolically for the one's it knows about).
1307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
1308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  switch (cputype) {
1309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case MachO::CPU_TYPE_I386:
1310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (cpusubtype) {
1311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_I386_ALL:
1312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_I386\n";
1313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_I386_ALL\n";
1314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
1316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      printUnknownCPUType(cputype, cpusubtype);
1317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
1320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case MachO::CPU_TYPE_X86_64:
1321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (cpusubtype) {
1322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_X86_64_ALL:
1323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_X86_64\n";
1324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_X86_64_ALL\n";
1325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_X86_64_H:
1327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_X86_64\n";
1328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_X86_64_H\n";
1329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
1331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      printUnknownCPUType(cputype, cpusubtype);
1332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
1335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case MachO::CPU_TYPE_ARM:
1336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (cpusubtype) {
1337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_ALL:
1338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_ALL\n";
1340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V4T:
1342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V4T\n";
1344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V5TEJ:
1346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n";
1348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_XSCALE:
1350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_XSCALE\n";
1352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V6:
1354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6\n";
1356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V6M:
1358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V6M\n";
1360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V7:
1362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7\n";
1364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V7EM:
1366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7EM\n";
1368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V7K:
1370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7K\n";
1372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V7M:
1374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7M\n";
1376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM_V7S:
1378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM\n";
1379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM_V7S\n";
1380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
1382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      printUnknownCPUType(cputype, cpusubtype);
1383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
1386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case MachO::CPU_TYPE_ARM64:
1387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
1388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case MachO::CPU_SUBTYPE_ARM64_ALL:
1389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype CPU_TYPE_ARM64\n";
1390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype CPU_SUBTYPE_ARM64_ALL\n";
1391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default:
1393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      printUnknownCPUType(cputype, cpusubtype);
1394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
1395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
1397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  default:
1398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printUnknownCPUType(cputype, cpusubtype);
1399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
1400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void printMachOUniversalHeaders(const object::MachOUniversalBinary *UB,
1404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       bool verbose) {
1405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "Fat headers\n";
1406de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (verbose) {
1407de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (UB->getMagic() == MachO::FAT_MAGIC)
1408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "fat_magic FAT_MAGIC\n";
1409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else // UB->getMagic() == MachO::FAT_MAGIC_64
1410de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "fat_magic FAT_MAGIC_64\n";
1411de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  } else
1412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "fat_magic " << format("0x%" PRIx32, MachO::FAT_MAGIC) << "\n";
1413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t nfat_arch = UB->getNumberOfObjects();
1415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StringRef Buf = UB->getData();
1416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint64_t size = Buf.size();
1417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint64_t big_size = sizeof(struct MachO::fat_header) +
1418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      nfat_arch * sizeof(struct MachO::fat_arch);
1419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "nfat_arch " << UB->getNumberOfObjects();
1420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (nfat_arch == 0)
1421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (malformed, contains zero architecture types)\n";
1422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (big_size > size)
1423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (malformed, architectures past end of file)\n";
1424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
1425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
1426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t i = 0; i < nfat_arch; ++i) {
1428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MachOUniversalBinary::ObjectForArch OFA(UB, i);
1429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t cputype = OFA.getCPUType();
1430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    uint32_t cpusubtype = OFA.getCPUSubType();
1431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "architecture ";
1432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (uint32_t j = 0; i != 0 && j <= i - 1; j++) {
1433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachOUniversalBinary::ObjectForArch other_OFA(UB, j);
1434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t other_cputype = other_OFA.getCPUType();
1435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t other_cpusubtype = other_OFA.getCPUSubType();
1436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (cputype != 0 && cpusubtype != 0 && cputype == other_cputype &&
1437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) ==
1438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              (other_cpusubtype & ~MachO::CPU_SUBTYPE_MASK)) {
1439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "(illegal duplicate architecture) ";
1440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (verbose) {
1444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << OFA.getArchTypeName() << "\n";
1445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      printCPUType(cputype, cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
1446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
1447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << i << "\n";
1448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cputype " << cputype << "\n";
1449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    cpusubtype " << (cpusubtype & ~MachO::CPU_SUBTYPE_MASK)
1450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             << "\n";
1451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (verbose &&
1453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64)
1454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    capabilities CPU_SUBTYPE_LIB64\n";
1455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else
1456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "    capabilities "
1457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             << format("0x%" PRIx32,
1458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24) << "\n";
1459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "    offset " << OFA.getOffset();
1460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (OFA.getOffset() > size)
1461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (past end of file)";
1462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (OFA.getOffset() % (1 << OFA.getAlign()) != 0)
1463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (not aligned on it's alignment (2^" << OFA.getAlign() << ")";
1464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
1465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "    size " << OFA.getSize();
1466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    big_size = OFA.getOffset() + OFA.getSize();
1467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (big_size > size)
1468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << " (past end of file)";
1469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
1470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "    align 2^" << OFA.getAlign() << " (" << (1 << OFA.getAlign())
1471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           << ")\n";
1472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
1474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void printArchiveChild(const Archive::Child &C, bool verbose,
1476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                              bool print_offset) {
1477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (print_offset)
1478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << C.getChildOffset() << "\t";
1479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  sys::fs::perms Mode = C.getAccessMode();
1480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (verbose) {
1481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
1482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
1483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "-";
1484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
1494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("0%o ", Mode);
1495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned UID = C.getUID();
1498ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("%3d/", UID);
1499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned GID = C.getGID();
1500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << format("%-3d ", GID);
1501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ErrorOr<uint64_t> Size = C.getRawSize();
1502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (std::error_code EC = Size.getError())
1503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    report_fatal_error(EC.message());
1504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  outs() << format("%5" PRId64, Size.get()) << " ";
15058c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
1506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StringRef RawLastModified = C.getRawLastModified();
1507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (verbose) {
1508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned Seconds;
1509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (RawLastModified.getAsInteger(10, Seconds))
1510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
1511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    else {
1512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Since cime(3) returns a 26 character string of the form:
1513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // "Sun Sep 16 01:03:52 1973\n\0"
1514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // just print 24 characters.
1515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      time_t t = Seconds;
1516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("%.24s ", ctime(&t));
151754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    }
1518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
1519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << RawLastModified << " ";
1520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1521db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola
1522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (verbose) {
1523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ErrorOr<StringRef> NameOrErr = C.getName();
1524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (NameOrErr.getError()) {
1525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      StringRef RawName = C.getRawName();
1526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << RawName << "\n";
1527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
1528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      StringRef Name = NameOrErr.get();
1529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << Name << "\n";
1530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
1532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    StringRef RawName = C.getRawName();
1533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << RawName << "\n";
1534afbaf48fc4a645a95737ea81e2e0fde47a6150baBenjamin Kramer  }
15358c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer}
15368c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
1537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
1538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Error Err;
1539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (const auto &C : A->children(Err, false))
1540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    printArchiveChild(C, verbose, print_offset);
1541de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (Err)
1542de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    report_fatal_error(std::move(Err));
1543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
15440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// ParseInputMachO() parses the named Mach-O file in Filename and handles the
1546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// -arch flags selecting just those slices as specified by them and also parses
1547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// archive files.  Then for each individual Mach-O file ProcessMachO() is
1548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// called to process the file based on the command line options.
1549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::ParseInputMachO(StringRef Filename) {
1550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Check for -arch all and verifiy the -arch flags are valid.
1551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (ArchFlags[i] == "all") {
1553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      ArchAll = true;
1554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
1555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!MachOObjectFile::isValidArch(ArchFlags[i])) {
1556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        errs() << "llvm-objdump: Unknown architecture named '" + ArchFlags[i] +
1557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      "'for the -arch option\n";
1558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return;
1559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
15620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Attempt to open the binary.
1564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
1565de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!BinaryOrErr)
1566de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    report_error(Filename, BinaryOrErr.takeError());
1567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Binary &Bin = *BinaryOrErr.get().getBinary();
1568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Archive *A = dyn_cast<Archive>(&Bin)) {
1570ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "Archive : " << Filename << "\n";
1571ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (ArchiveHeaders)
15726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets);
1573de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Error Err;
1574de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    for (auto &C : A->children(Err)) {
1575de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1576de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!ChildOrErr) {
1577de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1578de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          report_error(Filename, C, std::move(E));
1579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        continue;
1580de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
1581ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!checkMachOAndArchFlags(O, Filename))
1583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return;
1584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ProcessMachO(Filename, O, O->getFileName());
1585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1586ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Err)
1588de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_error(Filename, std::move(Err));
1589ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
1590ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1591ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (UniversalHeaders) {
1592ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
15934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      printMachOUniversalHeaders(UB, !NonVerbose);
1594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1595ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If we have a list of architecture flags specified dump only those.
1597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!ArchAll && ArchFlags.size() != 0) {
1598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Look for a slice in the universal binary that matches each ArchFlag.
1599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      bool ArchFound;
1600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ArchFound = false;
1602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                   E = UB->end_objects();
1604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             I != E; ++I) {
1605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (ArchFlags[i] == I->getArchTypeName()) {
1606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            ArchFound = true;
1607de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
1608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                I->getAsObjectFile();
1609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            std::string ArchitectureName = "";
1610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            if (ArchFlags.size() > 1)
1611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              ArchitectureName = I->getArchTypeName();
1612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            if (ObjOrErr) {
1613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              ObjectFile &O = *ObjOrErr.get();
1614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1616de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            } else if (auto E = isNotObjectErrorInvalidFileType(
1617de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       ObjOrErr.takeError())) {
1618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              report_error(Filename, StringRef(), std::move(E),
1619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           ArchitectureName);
1620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              continue;
1621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           I->getAsArchive()) {
1623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              std::unique_ptr<Archive> &A = *AOrErr;
1624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              outs() << "Archive : " << Filename;
1625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              if (!ArchitectureName.empty())
1626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                outs() << " (architecture " << ArchitectureName << ")";
1627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              outs() << "\n";
1628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              if (ArchiveHeaders)
16296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              Error Err;
1631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              for (auto &C : A->children(Err)) {
1632de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1633de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                if (!ChildOrErr) {
1634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1635de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                    report_error(Filename, C, std::move(E), ArchitectureName);
1636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  continue;
1637de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                }
1638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                if (MachOObjectFile *O =
1639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
1641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              }
1642de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              if (Err)
1643de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                report_error(Filename, std::move(Err));
1644de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            } else {
1645de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              consumeError(AOrErr.takeError());
1646de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              error("Mach-O universal file: " + Filename + " for " +
1647de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                    "architecture " + StringRef(I->getArchTypeName()) +
1648de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                    " is not a Mach-O file or an archive file");
1649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            }
1650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!ArchFound) {
1653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          errs() << "llvm-objdump: file: " + Filename + " does not contain "
1654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << "architecture: " + ArchFlags[i] + "\n";
1655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return;
1656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return;
1659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // No architecture flags were specified so if this contains a slice that
1661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // matches the host architecture dump only that.
1662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!ArchAll) {
1663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                 E = UB->end_objects();
1665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           I != E; ++I) {
1666ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (MachOObjectFile::getHostArch().getArchName() ==
1667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            I->getArchTypeName()) {
1668de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          std::string ArchiveName;
1670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          ArchiveName.clear();
1671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (ObjOrErr) {
1672ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            ObjectFile &O = *ObjOrErr.get();
1673ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
1674ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              ProcessMachO(Filename, MachOOF);
1675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else if (auto E = isNotObjectErrorInvalidFileType(
1676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     ObjOrErr.takeError())) {
1677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            report_error(Filename, std::move(E));
1678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            continue;
1679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                         I->getAsArchive()) {
1681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            std::unique_ptr<Archive> &A = *AOrErr;
1682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "Archive : " << Filename << "\n";
1683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            if (ArchiveHeaders)
16846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar              printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            Error Err;
1686de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            for (auto &C : A->children(Err)) {
1687de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1688de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              if (!ChildOrErr) {
1689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1690de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  report_error(Filename, C, std::move(E));
1691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                continue;
1692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              }
1693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              if (MachOObjectFile *O =
1694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
1695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                ProcessMachO(Filename, O, O->getFileName());
1696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            }
1697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            if (Err)
1698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              report_error(Filename, std::move(Err));
1699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else {
1700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            consumeError(AOrErr.takeError());
1701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            error("Mach-O universal file: " + Filename + " for architecture " +
1702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  StringRef(I->getArchTypeName()) +
1703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  " is not a Mach-O file or an archive file");
1704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return;
1706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Either all architectures have been specified or none have been specified
1710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // and this does not contain the host architecture so dump all the slices.
1711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               E = UB->end_objects();
1714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines         I != E; ++I) {
1715de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      std::string ArchitectureName = "";
1717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (moreThanOneArch)
1718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ArchitectureName = I->getArchTypeName();
1719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (ObjOrErr) {
1720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ObjectFile &Obj = *ObjOrErr.get();
1721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
1722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          ProcessMachO(Filename, MachOOF, "", ArchitectureName);
1723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      } else if (auto E = isNotObjectErrorInvalidFileType(
1724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 ObjOrErr.takeError())) {
1725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_error(StringRef(), Filename, std::move(E), ArchitectureName);
1726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        continue;
1727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      } else if (Expected<std::unique_ptr<Archive>> AOrErr =
1728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   I->getAsArchive()) {
1729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        std::unique_ptr<Archive> &A = *AOrErr;
1730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "Archive : " << Filename;
1731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!ArchitectureName.empty())
1732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << " (architecture " << ArchitectureName << ")";
1733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "\n";
1734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (ArchiveHeaders)
17356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
1736de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Error Err;
1737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        for (auto &C : A->children(Err)) {
1738de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1739de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (!ChildOrErr) {
1740de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1741de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              report_error(Filename, C, std::move(E), ArchitectureName);
1742ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            continue;
1743de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          }
1744ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (MachOObjectFile *O =
1745ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
1746ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
1747ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
1748ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           ArchitectureName);
1749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1750ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1751de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (Err)
1752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          report_error(Filename, std::move(Err));
1753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      } else {
1754de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        consumeError(AOrErr.takeError());
1755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        error("Mach-O universal file: " + Filename + " for architecture " +
1756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              StringRef(I->getArchTypeName()) +
1757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              " is not a Mach-O file or an archive file");
1758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
1759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
1761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ObjectFile *O = dyn_cast<ObjectFile>(&Bin)) {
1763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!checkMachOAndArchFlags(O, Filename))
1764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return;
1765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
1766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      ProcessMachO(Filename, MachOOF);
1767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else
1768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      errs() << "llvm-objdump: '" << Filename << "': "
1769ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             << "Object is not a Mach-O file type.\n";
1770de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
1771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1772de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  llvm_unreachable("Input object can't be invalid at this point");
1773da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola}
1774da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola
177537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef std::pair<uint64_t, const char *> BindInfoEntry;
177637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef std::vector<BindInfoEntry> BindTable;
177737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestypedef BindTable::iterator bind_table_iterator;
177837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
177937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The block of info used by the Symbolizer call backs.
178037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct DisassembleInfo {
178137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool verbose;
178237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MachOObjectFile *O;
178337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SectionRef S;
178437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SymbolAddressMap *AddrMap;
178537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::vector<SectionRef> *Sections;
178637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *class_name;
178737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *selector_name;
178837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  char *method;
178937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  char *demangled_name;
179037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t adrp_addr;
179137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t adrp_inst;
179237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  BindTable *bindtable;
1793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t depth;
179437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
179537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
179637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolizerGetOpInfo() is the operand information call back function.
179737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This is called to get the symbolic information for operand(s) of an
179837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// instruction when it is being done.  This routine does this from
179937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the relocation information, symbol table, etc. That block of information
180037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// is a pointer to the struct DisassembleInfo that was passed when the
180137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// disassembler context was created and passed to back to here when
180237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// called back by the disassembler for instruction operands that could have
180337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// relocation information. The address of the instruction containing operand is
180437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// at the Pc parameter.  The immediate value the operand has is passed in
180537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// op_info->Value and is at Offset past the start of the instruction and has a
180637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// byte Size of 1, 2 or 4. The symbolc information is returned in TagBuf is the
180737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// LLVMOpInfo1 struct defined in the header "llvm-c/Disassembler.h" as symbol
180837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// names and addends of the symbolic expression to add for the operand.  The
180937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// value of TagType is currently 1 (for the LLVMOpInfo1 struct). If symbolic
181037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// information is returned then this function returns 1 else it returns 0.
18114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
18124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                               uint64_t Size, int TagType, void *TagBuf) {
181337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
181437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct LLVMOpInfo1 *op_info = (struct LLVMOpInfo1 *)TagBuf;
181537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t value = op_info->Value;
181637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
181737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Make sure all fields returned are zero if we don't set them.
181837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  memset((void *)op_info, '\0', sizeof(struct LLVMOpInfo1));
181937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  op_info->Value = value;
182037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
182137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If the TagType is not the value 1 which it code knows about or if no
182237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // verbose symbolic information is wanted then just return 0, indicating no
182337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // information is being returned.
18244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (TagType != 1 || !info->verbose)
182537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 0;
182637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
182737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned int Arch = info->O->getArch();
182837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Arch == Triple::x86) {
182937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
183037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
1831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // TODO:
1833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Search the external relocation entries of a fully linked image
1834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // (if any) for an entry that matches this segment offset.
1835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // uint32_t seg_offset = (Pc + Offset);
1836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return 0;
1837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // In MH_OBJECT filetypes search the section's relocation entries (if any)
1839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // for an entry for this section offset.
184037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t sect_addr = info->S.getAddress();
184137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t sect_offset = (Pc + Offset) - sect_addr;
184237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool reloc_found = false;
184337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DataRefImpl Rel;
184437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::any_relocation_info RE;
184537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool isExtern = false;
184637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolRef Symbol;
184737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool r_scattered = false;
184837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t r_value, pair_r_value, r_type;
184937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (const RelocationRef &Reloc : info->S.relocations()) {
1850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t RelocOffset = Reloc.getOffset();
185137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (RelocOffset == sect_offset) {
185237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Rel = Reloc.getRawDataRefImpl();
185337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        RE = info->O->getRelocation(Rel);
185437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        r_type = info->O->getAnyRelocationType(RE);
185537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        r_scattered = info->O->isRelocationScattered(RE);
185637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (r_scattered) {
185737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          r_value = info->O->getScatteredRelocationValue(RE);
185837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
185937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
186037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            DataRefImpl RelNext = Rel;
186137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            info->O->moveRelocationNext(RelNext);
186237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            MachO::any_relocation_info RENext;
186337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            RENext = info->O->getRelocation(RelNext);
186437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (info->O->isRelocationScattered(RENext))
186537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              pair_r_value = info->O->getScatteredRelocationValue(RENext);
186637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            else
186737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              return 0;
186837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
186937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        } else {
187037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          isExtern = info->O->getPlainRelocationExternal(RE);
187137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (isExtern) {
187237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            symbol_iterator RelocSym = Reloc.getSymbol();
187337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Symbol = *RelocSym;
187437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
187537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
187637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reloc_found = true;
187737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
187837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
187937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
188037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (reloc_found && isExtern) {
1881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymName = Symbol.getName();
1882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymName) {
1883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
1884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
1885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymName.takeError(), OS, "");
1886de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
1887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
1888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
1889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const char *name = SymName->data();
189037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Present = 1;
189137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Name = name;
189237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // For i386 extern relocation entries the value in the instruction is
189337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // the offset from the symbol, and value is already set in op_info->Value.
189437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
189537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
189637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (reloc_found && (r_type == MachO::GENERIC_RELOC_SECTDIFF ||
189737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                        r_type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)) {
1898ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const char *add = GuessSymbolName(r_value, info->AddrMap);
1899ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
190037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint32_t offset = value - (r_value - pair_r_value);
190137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Present = 1;
190237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (add != nullptr)
190337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->AddSymbol.Name = add;
190437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
190537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->AddSymbol.Value = r_value;
190637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->SubtractSymbol.Present = 1;
190737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (sub != nullptr)
190837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->SubtractSymbol.Name = sub;
190937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
191037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->SubtractSymbol.Value = pair_r_value;
191137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->Value = offset;
191237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
191337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
191437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 0;
19154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
19164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (Arch == Triple::x86_64) {
191737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Size != 1 && Size != 2 && Size != 4 && Size != 0)
191837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
1919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
1920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // TODO:
1921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Search the external relocation entries of a fully linked image
1922f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // (if any) for an entry that matches this segment offset.
1923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // uint64_t seg_offset = (Pc + Offset);
1924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return 0;
1925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // In MH_OBJECT filetypes search the section's relocation entries (if any)
1927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // for an entry for this section offset.
192837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t sect_addr = info->S.getAddress();
192937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t sect_offset = (Pc + Offset) - sect_addr;
193037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool reloc_found = false;
193137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DataRefImpl Rel;
193237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::any_relocation_info RE;
193337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool isExtern = false;
193437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolRef Symbol;
193537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (const RelocationRef &Reloc : info->S.relocations()) {
1936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t RelocOffset = Reloc.getOffset();
193737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (RelocOffset == sect_offset) {
193837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Rel = Reloc.getRawDataRefImpl();
193937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        RE = info->O->getRelocation(Rel);
194037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // NOTE: Scattered relocations don't exist on x86_64.
194137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        isExtern = info->O->getPlainRelocationExternal(RE);
194237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (isExtern) {
194337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          symbol_iterator RelocSym = Reloc.getSymbol();
194437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Symbol = *RelocSym;
194537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
194637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reloc_found = true;
194737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
194837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
194937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
195037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (reloc_found && isExtern) {
195137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // The Value passed in will be adjusted by the Pc if the instruction
195237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // adds the Pc.  But for x86_64 external relocation entries the Value
195337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // is the offset from the external symbol.
195437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->O->getAnyRelocationPCRel(RE))
195537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->Value -= Pc + Offset + Size;
1956de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymName = Symbol.getName();
1957de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymName) {
1958de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
1959de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
1960de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymName.takeError(), OS, "");
1961de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
1962de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
1963de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
1964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const char *name = SymName->data();
196537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      unsigned Type = info->O->getAnyRelocationType(RE);
196637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
196737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        DataRefImpl RelNext = Rel;
196837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        info->O->moveRelocationNext(RelNext);
196937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
197037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        unsigned TypeNext = info->O->getAnyRelocationType(RENext);
197137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        bool isExternNext = info->O->getPlainRelocationExternal(RENext);
197237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        unsigned SymbolNum = info->O->getPlainRelocationSymbolNum(RENext);
197337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (TypeNext == MachO::X86_64_RELOC_UNSIGNED && isExternNext) {
197437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          op_info->SubtractSymbol.Present = 1;
197537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          op_info->SubtractSymbol.Name = name;
197637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum);
197737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Symbol = *RelocSymNext;
1978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          Expected<StringRef> SymNameNext = Symbol.getName();
1979de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (!SymNameNext) {
1980de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            std::string Buf;
1981de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            raw_string_ostream OS(Buf);
1982de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            logAllUnhandledErrors(SymNameNext.takeError(), OS, "");
1983de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            OS.flush();
1984de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            report_fatal_error(Buf);
1985de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          }
1986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          name = SymNameNext->data();
198737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
198837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
198937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // TODO: add the VariantKinds to op_info->VariantKind for relocation types
199037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // like: X86_64_RELOC_TLV, X86_64_RELOC_GOT_LOAD and X86_64_RELOC_GOT.
199137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Present = 1;
199237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Name = name;
199337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
199437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
199537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 0;
19964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
19974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (Arch == Triple::arm) {
199837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Offset != 0 || (Size != 4 && Size != 2))
199937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
2000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // TODO:
2002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Search the external relocation entries of a fully linked image
2003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // (if any) for an entry that matches this segment offset.
2004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // uint32_t seg_offset = (Pc + Offset);
2005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return 0;
2006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // In MH_OBJECT filetypes search the section's relocation entries (if any)
2008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // for an entry for this section offset.
200937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t sect_addr = info->S.getAddress();
201037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t sect_offset = (Pc + Offset) - sect_addr;
201137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DataRefImpl Rel;
201237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::any_relocation_info RE;
201337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool isExtern = false;
201437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolRef Symbol;
201537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool r_scattered = false;
201637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t r_value, pair_r_value, r_type, r_length, other_half;
20174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    auto Reloc =
20184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        std::find_if(info->S.relocations().begin(), info->S.relocations().end(),
20194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     [&](const RelocationRef &Reloc) {
2020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                       uint64_t RelocOffset = Reloc.getOffset();
20214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                       return RelocOffset == sect_offset;
20224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     });
20234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
20244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (Reloc == info->S.relocations().end())
20254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return 0;
20264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
20274c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    Rel = Reloc->getRawDataRefImpl();
20284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    RE = info->O->getRelocation(Rel);
20294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    r_length = info->O->getAnyRelocationLength(RE);
20304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    r_scattered = info->O->isRelocationScattered(RE);
20314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_scattered) {
20324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      r_value = info->O->getScatteredRelocationValue(RE);
20334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      r_type = info->O->getScatteredRelocationType(RE);
20344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    } else {
20354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      r_type = info->O->getAnyRelocationType(RE);
20364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      isExtern = info->O->getPlainRelocationExternal(RE);
20374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (isExtern) {
20384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        symbol_iterator RelocSym = Reloc->getSymbol();
20394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        Symbol = *RelocSym;
204037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
204137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
20424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_type == MachO::ARM_RELOC_HALF ||
20434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        r_type == MachO::ARM_RELOC_SECTDIFF ||
20444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        r_type == MachO::ARM_RELOC_LOCAL_SECTDIFF ||
20454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
20464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      DataRefImpl RelNext = Rel;
20474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      info->O->moveRelocationNext(RelNext);
20484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      MachO::any_relocation_info RENext;
20494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      RENext = info->O->getRelocation(RelNext);
20504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      other_half = info->O->getAnyRelocationAddress(RENext) & 0xffff;
20514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (info->O->isRelocationScattered(RENext))
20524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        pair_r_value = info->O->getScatteredRelocationValue(RENext);
20534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
20544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
20554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (isExtern) {
2056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymName = Symbol.getName();
2057de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymName) {
2058de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
2059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
2060de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymName.takeError(), OS, "");
2061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
2062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
2063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
2064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const char *name = SymName->data();
206537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Present = 1;
206637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Name = name;
2067ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      switch (r_type) {
2068ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::ARM_RELOC_HALF:
2069ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if ((r_length & 0x1) == 1) {
2070ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          op_info->Value = value << 16 | other_half;
2071ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
2072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
2073ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          op_info->Value = other_half << 16 | value;
2074ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
207537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
2076ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
2077ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      default:
2078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
207937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
208037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
208137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
208237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If we have a branch that is not an external relocation entry then
208337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // return 0 so the code in tryAddingSymbolicOperand() can use the
208437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // SymbolLookUp call back with the branch target address to look up the
208537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // symbol and possiblity add an annotation for a symbol stub.
20864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (isExtern == 0 && (r_type == MachO::ARM_RELOC_BR24 ||
20874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                          r_type == MachO::ARM_THUMB_RELOC_BR22))
208837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
208937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
209037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t offset = 0;
20914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_type == MachO::ARM_RELOC_HALF ||
20924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
20934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if ((r_length & 0x1) == 1)
20944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        value = value << 16 | other_half;
20954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      else
20964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        value = other_half << 16 | value;
20974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
20984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_scattered && (r_type != MachO::ARM_RELOC_HALF &&
20994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                        r_type != MachO::ARM_RELOC_HALF_SECTDIFF)) {
21004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      offset = value - r_value;
21014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      value = r_value;
210237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
210337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
21044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_type == MachO::ARM_RELOC_HALF_SECTDIFF) {
210537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if ((r_length & 0x1) == 1)
210637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
210737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
210837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
2109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const char *add = GuessSymbolName(r_value, info->AddrMap);
2110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const char *sub = GuessSymbolName(pair_r_value, info->AddrMap);
211137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int32_t offset = value - (r_value - pair_r_value);
211237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Present = 1;
211337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (add != nullptr)
211437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->AddSymbol.Name = add;
211537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
211637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->AddSymbol.Value = r_value;
211737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->SubtractSymbol.Present = 1;
211837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (sub != nullptr)
211937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->SubtractSymbol.Name = sub;
212037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
212137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        op_info->SubtractSymbol.Value = pair_r_value;
212237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->Value = offset;
212337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
212437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
212537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
212637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    op_info->AddSymbol.Present = 1;
212737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    op_info->Value = offset;
21284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_type == MachO::ARM_RELOC_HALF) {
21294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if ((r_length & 0x1) == 1)
21304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_HI16;
21314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      else
21324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        op_info->VariantKind = LLVMDisassembler_VariantKind_ARM_LO16;
213337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
2134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *add = GuessSymbolName(value, info->AddrMap);
213537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (add != nullptr) {
213637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      op_info->AddSymbol.Name = add;
213737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 1;
213837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
213937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    op_info->AddSymbol.Value = value;
214037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 1;
21414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
21424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (Arch == Triple::aarch64) {
214337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Offset != 0 || Size != 4)
214437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return 0;
2145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (info->O->getHeader().filetype != MachO::MH_OBJECT) {
2146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // TODO:
2147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Search the external relocation entries of a fully linked image
2148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // (if any) for an entry that matches this segment offset.
2149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // uint64_t seg_offset = (Pc + Offset);
2150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return 0;
2151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // In MH_OBJECT filetypes search the section's relocation entries (if any)
2153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // for an entry for this section offset.
215437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t sect_addr = info->S.getAddress();
215537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t sect_offset = (Pc + Offset) - sect_addr;
21564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    auto Reloc =
21574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        std::find_if(info->S.relocations().begin(), info->S.relocations().end(),
21584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     [&](const RelocationRef &Reloc) {
2159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                       uint64_t RelocOffset = Reloc.getOffset();
21604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                       return RelocOffset == sect_offset;
21614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                     });
21624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
21634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (Reloc == info->S.relocations().end())
21644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return 0;
21654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
21664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    DataRefImpl Rel = Reloc->getRawDataRefImpl();
21674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    MachO::any_relocation_info RE = info->O->getRelocation(Rel);
21684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    uint32_t r_type = info->O->getAnyRelocationType(RE);
21694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (r_type == MachO::ARM64_RELOC_ADDEND) {
21704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      DataRefImpl RelNext = Rel;
21714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      info->O->moveRelocationNext(RelNext);
21724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      MachO::any_relocation_info RENext = info->O->getRelocation(RelNext);
21734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (value == 0) {
21744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        value = info->O->getPlainRelocationSymbolNum(RENext);
21754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        op_info->Value = value;
217637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
217737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
21784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    // NOTE: Scattered relocations don't exist on arm64.
21794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (!info->O->getPlainRelocationExternal(RE))
21804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return 0;
2181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<StringRef> SymName = Reloc->getSymbol()->getName();
2182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!SymName) {
2183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
2184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
2185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(SymName.takeError(), OS, "");
2186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
2187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
2188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const char *name = SymName->data();
21904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    op_info->AddSymbol.Present = 1;
21914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    op_info->AddSymbol.Name = name;
219237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
21934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    switch (r_type) {
21944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_PAGE21:
21954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @page */
21964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGE;
21974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
21984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_PAGEOFF12:
21994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @pageoff */
22004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_PAGEOFF;
22014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
22024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
22034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @gotpage */
22044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGE;
22054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
22064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
22074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @gotpageoff */
22084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF;
22094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
22104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
22114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @tvlppage is not implemented in llvm-mc */
22124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVP;
22134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
22144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
22154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      /* @tvlppageoff is not implemented in llvm-mc */
22164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_ARM64_TLVOFF;
22174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
22184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    default:
22194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    case MachO::ARM64_RELOC_BRANCH26:
22204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      op_info->VariantKind = LLVMDisassembler_VariantKind_None;
22214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      break;
222237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
22234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return 1;
222437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
22254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return 0;
222637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
222737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
222837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// GuessCstringPointer is passed the address of what might be a pointer to a
222937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// literal string in a cstring section.  If that address is in a cstring section
223037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// it returns a pointer to that string.  Else it returns nullptr.
22314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *GuessCstringPointer(uint64_t ReferenceValue,
22324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
22336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Load : info->O->load_commands()) {
223437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Load.C.cmd == MachO::LC_SEGMENT_64) {
223537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
223637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
223737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section_64 Sec = info->O->getSection64(Load, J);
223837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
223937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (section_type == MachO::S_CSTRING_LITERALS &&
224037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue >= Sec.addr &&
224137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue < Sec.addr + Sec.size) {
224237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t sect_offset = ReferenceValue - Sec.addr;
224337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_offset = Sec.offset + sect_offset;
224437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          StringRef MachOContents = info->O->getData();
224537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_size = MachOContents.size();
224637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          const char *object_addr = (const char *)MachOContents.data();
224737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (object_offset < object_size) {
224837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            const char *name = object_addr + object_offset;
224937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return name;
225037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          } else {
225137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return nullptr;
225237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
225337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
225437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
225537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Load.C.cmd == MachO::LC_SEGMENT) {
225637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
225737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
225837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section Sec = info->O->getSection(Load, J);
225937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
226037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (section_type == MachO::S_CSTRING_LITERALS &&
226137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue >= Sec.addr &&
226237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue < Sec.addr + Sec.size) {
226337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t sect_offset = ReferenceValue - Sec.addr;
226437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_offset = Sec.offset + sect_offset;
226537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          StringRef MachOContents = info->O->getData();
226637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_size = MachOContents.size();
226737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          const char *object_addr = (const char *)MachOContents.data();
226837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (object_offset < object_size) {
226937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            const char *name = object_addr + object_offset;
227037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return name;
227137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          } else {
227237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return nullptr;
227337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
227437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
227537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
227637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
227737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
227837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return nullptr;
227937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
228037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
228137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// GuessIndirectSymbol returns the name of the indirect symbol for the
228237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// ReferenceValue passed in or nullptr.  This is used when ReferenceValue maybe
228337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// an address of a symbol stub or a lazy or non-lazy pointer to associate the
228437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// symbol name being referenced by the stub or pointer.
228537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *GuessIndirectSymbol(uint64_t ReferenceValue,
228637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                       struct DisassembleInfo *info) {
228737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MachO::dysymtab_command Dysymtab = info->O->getDysymtabLoadCommand();
228837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MachO::symtab_command Symtab = info->O->getSymtabLoadCommand();
22896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Load : info->O->load_commands()) {
229037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Load.C.cmd == MachO::LC_SEGMENT_64) {
229137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
229237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
229337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section_64 Sec = info->O->getSection64(Load, J);
229437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
229537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
229637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
229737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
229837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
229937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_SYMBOL_STUBS) &&
230037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue >= Sec.addr &&
230137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue < Sec.addr + Sec.size) {
230237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint32_t stride;
230337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (section_type == MachO::S_SYMBOL_STUBS)
230437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            stride = Sec.reserved2;
230537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else
230637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            stride = 8;
230737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (stride == 0)
230837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return nullptr;
230937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
231037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (index < Dysymtab.nindirectsyms) {
231137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            uint32_t indirect_symbol =
231237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                info->O->getIndirectSymbolTableEntry(Dysymtab, index);
231337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (indirect_symbol < Symtab.nsyms) {
231437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
231537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              SymbolRef Symbol = *Sym;
2316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              Expected<StringRef> SymName = Symbol.getName();
2317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              if (!SymName) {
2318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                std::string Buf;
2319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                raw_string_ostream OS(Buf);
2320de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                logAllUnhandledErrors(SymName.takeError(), OS, "");
2321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                OS.flush();
2322de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                report_fatal_error(Buf);
2323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              }
2324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              const char *name = SymName->data();
232537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              return name;
232637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            }
232737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
232837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
232937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
233037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Load.C.cmd == MachO::LC_SEGMENT) {
233137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command Seg = info->O->getSegmentLoadCommand(Load);
233237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
233337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section Sec = info->O->getSection(Load, J);
233437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint32_t section_type = Sec.flags & MachO::SECTION_TYPE;
233537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if ((section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
233637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
233737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
233837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS ||
233937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             section_type == MachO::S_SYMBOL_STUBS) &&
234037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue >= Sec.addr &&
234137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue < Sec.addr + Sec.size) {
234237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint32_t stride;
234337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (section_type == MachO::S_SYMBOL_STUBS)
234437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            stride = Sec.reserved2;
234537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else
234637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            stride = 4;
234737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (stride == 0)
234837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return nullptr;
234937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint32_t index = Sec.reserved1 + (ReferenceValue - Sec.addr) / stride;
235037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (index < Dysymtab.nindirectsyms) {
235137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            uint32_t indirect_symbol =
235237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                info->O->getIndirectSymbolTableEntry(Dysymtab, index);
235337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (indirect_symbol < Symtab.nsyms) {
235437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol);
235537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              SymbolRef Symbol = *Sym;
2356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              Expected<StringRef> SymName = Symbol.getName();
2357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              if (!SymName) {
2358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                std::string Buf;
2359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                raw_string_ostream OS(Buf);
2360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                logAllUnhandledErrors(SymName.takeError(), OS, "");
2361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                OS.flush();
2362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                report_fatal_error(Buf);
2363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              }
2364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              const char *name = SymName->data();
236537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              return name;
236637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            }
236737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
236837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
236937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
237037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
237137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
237237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return nullptr;
237337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
237437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
237537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// method_reference() is called passing it the ReferenceName that might be
237637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// a reference it to an Objective-C method call.  If so then it allocates and
237737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// assembles a method call string with the values last seen and saved in
237837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the DisassembleInfo's class_name and selector_name fields.  This is saved
237937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// into the method field of the info and any previous string is free'ed.
238037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Then the class_name field in the info is set to nullptr.  The method call
238137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// string is set into ReferenceName and ReferenceType is set to
238237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// LLVMDisassembler_ReferenceType_Out_Objc_Message.  If this not a method call
238337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// then both ReferenceType and ReferenceName are left unchanged.
238437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void method_reference(struct DisassembleInfo *info,
238537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             uint64_t *ReferenceType,
238637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             const char **ReferenceName) {
238737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned int Arch = info->O->getArch();
238837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (*ReferenceName != nullptr) {
238937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (strcmp(*ReferenceName, "_objc_msgSend") == 0) {
239037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->selector_name != nullptr) {
239137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (info->method != nullptr)
239237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          free(info->method);
239337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (info->class_name != nullptr) {
239437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          info->method = (char *)malloc(5 + strlen(info->class_name) +
239537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                        strlen(info->selector_name));
239637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (info->method != nullptr) {
239737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcpy(info->method, "+[");
239837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, info->class_name);
239937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, " ");
240037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, info->selector_name);
240137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, "]");
240237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            *ReferenceName = info->method;
240337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
240437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
240537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        } else {
240637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          info->method = (char *)malloc(9 + strlen(info->selector_name));
240737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (info->method != nullptr) {
240837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (Arch == Triple::x86_64)
240937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              strcpy(info->method, "-[%rdi ");
241037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            else if (Arch == Triple::aarch64)
241137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              strcpy(info->method, "-[x0 ");
241237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            else
241337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              strcpy(info->method, "-[r? ");
241437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, info->selector_name);
241537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcat(info->method, "]");
241637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            *ReferenceName = info->method;
241737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
241837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
241937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
242037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        info->class_name = nullptr;
242137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
242237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (strcmp(*ReferenceName, "_objc_msgSendSuper2") == 0) {
242337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->selector_name != nullptr) {
242437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (info->method != nullptr)
242537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          free(info->method);
242637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        info->method = (char *)malloc(17 + strlen(info->selector_name));
242737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (info->method != nullptr) {
242837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (Arch == Triple::x86_64)
242937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcpy(info->method, "-[[%rdi super] ");
243037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else if (Arch == Triple::aarch64)
243137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcpy(info->method, "-[[x0 super] ");
243237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else
243337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            strcpy(info->method, "-[[r? super] ");
243437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          strcat(info->method, info->selector_name);
243537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          strcat(info->method, "]");
243637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          *ReferenceName = info->method;
243737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message;
243837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
243937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        info->class_name = nullptr;
244037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
244137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
244237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
244337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
244437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
244537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// GuessPointerPointer() is passed the address of what might be a pointer to
244637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// a reference to an Objective-C class, selector, message ref or cfstring.
244737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// If so the value of the pointer is returned and one of the booleans are set
244837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// to true.  If not zero is returned and all the booleans are set to false.
244937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic uint64_t GuessPointerPointer(uint64_t ReferenceValue,
245037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    struct DisassembleInfo *info,
245137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    bool &classref, bool &selref, bool &msgref,
245237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    bool &cfstring) {
245337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  classref = false;
245437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  selref = false;
245537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  msgref = false;
245637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  cfstring = false;
24576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Load : info->O->load_commands()) {
245837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Load.C.cmd == MachO::LC_SEGMENT_64) {
245937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command_64 Seg = info->O->getSegment64LoadCommand(Load);
246037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned J = 0; J < Seg.nsects; ++J) {
246137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section_64 Sec = info->O->getSection64(Load, J);
246237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if ((strncmp(Sec.sectname, "__objc_selrefs", 16) == 0 ||
246337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
246437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             strncmp(Sec.sectname, "__objc_superrefs", 16) == 0 ||
246537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 ||
246637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             strncmp(Sec.sectname, "__cfstring", 16) == 0) &&
246737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue >= Sec.addr &&
246837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ReferenceValue < Sec.addr + Sec.size) {
246937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t sect_offset = ReferenceValue - Sec.addr;
247037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_offset = Sec.offset + sect_offset;
247137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          StringRef MachOContents = info->O->getData();
247237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint64_t object_size = MachOContents.size();
247337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          const char *object_addr = (const char *)MachOContents.data();
247437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (object_offset < object_size) {
247537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            uint64_t pointer_value;
247637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            memcpy(&pointer_value, object_addr + object_offset,
247737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                   sizeof(uint64_t));
247837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
247937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              sys::swapByteOrder(pointer_value);
248037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (strncmp(Sec.sectname, "__objc_selrefs", 16) == 0)
248137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              selref = true;
248237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            else if (strncmp(Sec.sectname, "__objc_classrefs", 16) == 0 ||
248337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     strncmp(Sec.sectname, "__objc_superrefs", 16) == 0)
248437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              classref = true;
248537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            else if (strncmp(Sec.sectname, "__objc_msgrefs", 16) == 0 &&
248637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     ReferenceValue + 8 < Sec.addr + Sec.size) {
248737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              msgref = true;
248837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              memcpy(&pointer_value, object_addr + object_offset + 8,
248937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     sizeof(uint64_t));
249037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
249137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                sys::swapByteOrder(pointer_value);
249237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            } else if (strncmp(Sec.sectname, "__cfstring", 16) == 0)
249337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              cfstring = true;
249437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return pointer_value;
249537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          } else {
249637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return 0;
249737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
249837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
249937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
250037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
250137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // TODO: Look for LC_SEGMENT for 32-bit Mach-O files.
250237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
250337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return 0;
250437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
250537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
250637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_pointer_64 returns a pointer to the bytes in the object file at the
250737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Address from a section in the Mach-O file.  And indirectly returns the
250837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// offset into the section, number of bytes left in the section past the offset
250937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// and which section is was being referenced.  If the Address is not in a
251037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// section nullptr is returned.
25114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *get_pointer_64(uint64_t Address, uint32_t &offset,
25124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                  uint32_t &left, SectionRef &S,
25130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  DisassembleInfo *info,
25140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  bool objc_only = false) {
251537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  offset = 0;
251637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  left = 0;
251737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  S = SectionRef();
251837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned SectIdx = 0; SectIdx != info->Sections->size(); SectIdx++) {
251937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SectAddress = ((*(info->Sections))[SectIdx]).getAddress();
252037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SectSize = ((*(info->Sections))[SectIdx]).getSize();
2521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SectSize == 0)
2522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
25230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (objc_only) {
25240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      StringRef SectName;
25250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      ((*(info->Sections))[SectIdx]).getName(SectName);
25260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      DataRefImpl Ref = ((*(info->Sections))[SectIdx]).getRawDataRefImpl();
25270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
25280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (SegName != "__OBJC" && SectName != "__cstring")
25290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        continue;
25300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
253137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Address >= SectAddress && Address < SectAddress + SectSize) {
253237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      S = (*(info->Sections))[SectIdx];
253337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      offset = Address - SectAddress;
253437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      left = SectSize - offset;
253537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      StringRef SectContents;
253637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ((*(info->Sections))[SectIdx]).getContents(SectContents);
253737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return SectContents.data() + offset;
253837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
253937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
254037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return nullptr;
254137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
254237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic const char *get_pointer_32(uint32_t Address, uint32_t &offset,
25440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  uint32_t &left, SectionRef &S,
25450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  DisassembleInfo *info,
25460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  bool objc_only = false) {
25470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return get_pointer_64(Address, offset, left, S, info, objc_only);
25480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
25490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
255037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_symbol_64() returns the name of a symbol (or nullptr) and the address of
255137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the symbol indirectly through n_value. Based on the relocation information
255237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// for the specified section offset in the specified section reference.
25530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar// If no relocation information is found and a non-zero ReferenceValue for the
25540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar// symbol is passed, look up that address in the info's AddrMap.
2555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
2556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                 DisassembleInfo *info, uint64_t &n_value,
2557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                 uint64_t ReferenceValue = 0) {
255837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  n_value = 0;
25594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (!info->verbose)
256037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
256137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
256237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // See if there is an external relocation entry at the sect_offset.
256337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool reloc_found = false;
256437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DataRefImpl Rel;
256537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MachO::any_relocation_info RE;
256637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool isExtern = false;
256737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SymbolRef Symbol;
256837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const RelocationRef &Reloc : S.relocations()) {
2569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t RelocOffset = Reloc.getOffset();
257037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (RelocOffset == sect_offset) {
257137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Rel = Reloc.getRawDataRefImpl();
257237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RE = info->O->getRelocation(Rel);
257337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->O->isRelocationScattered(RE))
257437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        continue;
257537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      isExtern = info->O->getPlainRelocationExternal(RE);
257637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (isExtern) {
257737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        symbol_iterator RelocSym = Reloc.getSymbol();
257837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Symbol = *RelocSym;
257937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
258037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reloc_found = true;
258137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
258237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
258337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
258437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If there is an external relocation entry for a symbol in this section
258537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // at this section_offset then use that symbol's value for the n_value
258637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // and return its name.
258737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *SymbolName = nullptr;
258837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (reloc_found && isExtern) {
2589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    n_value = Symbol.getValue();
2590de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<StringRef> NameOrError = Symbol.getName();
2591de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!NameOrError) {
2592de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
2593de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
2594de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(NameOrError.takeError(), OS, "");
2595de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
2596de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
2597de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    StringRef Name = *NameOrError;
2599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Name.empty()) {
2600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SymbolName = Name.data();
260137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return SymbolName;
260237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
260337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
260437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
260537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // TODO: For fully linked images, look through the external relocation
260637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // entries off the dynamic symtab command. For these the r_offset is from the
260737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // start of the first writeable segment in the Mach-O file.  So the offset
260837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // to this section from that segment is passed to this routine by the caller,
260937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // as the database_offset. Which is the difference of the section's starting
261037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // address and the first writable segment.
261137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
261237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // NOTE: need add passing the database_offset to this routine.
261337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // We did not find an external relocation entry so look up the ReferenceValue
26150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // as an address of a symbol and if found return that symbol's name.
2616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
261737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
261837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SymbolName;
261937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
262037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic const char *get_symbol_32(uint32_t sect_offset, SectionRef S,
26220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                 DisassembleInfo *info,
26230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                 uint32_t ReferenceValue) {
26240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t n_value64;
26250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue);
26260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
26270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
262837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// These are structs in the Objective-C meta data and read to produce the
262937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// comments for disassembly.  While these are part of the ABI they are no
263037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// public defintions.  So the are here not in include/llvm/Support/MachO.h .
263137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
263237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The cfstring object in a 64-bit Mach-O file.
263337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct cfstring64_t {
263437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t isa;        // class64_t * (64-bit pointer)
263537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t flags;      // flag bits
263637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t characters; // char * (64-bit pointer)
263737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t length;     // number of non-NULL characters in above
263837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
263937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
264037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The class object in a 64-bit Mach-O file.
264137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct class64_t {
264237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t isa;        // class64_t * (64-bit pointer)
264337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t superclass; // class64_t * (64-bit pointer)
264437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t cache;      // Cache (64-bit pointer)
264537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t vtable;     // IMP * (64-bit pointer)
264637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t data;       // class_ro64_t * (64-bit pointer)
264737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
264837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct class32_t {
26500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t isa;        /* class32_t * (32-bit pointer) */
26510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t superclass; /* class32_t * (32-bit pointer) */
26520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t cache;      /* Cache (32-bit pointer) */
26530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t vtable;     /* IMP * (32-bit pointer) */
26540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t data;       /* class_ro32_t * (32-bit pointer) */
26550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
26560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
265737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct class_ro64_t {
265837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t flags;
265937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t instanceStart;
266037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t instanceSize;
266137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t reserved;
266237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t ivarLayout;     // const uint8_t * (64-bit pointer)
266337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t name;           // const char * (64-bit pointer)
266437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t baseMethods;    // const method_list_t * (64-bit pointer)
266537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t baseProtocols;  // const protocol_list_t * (64-bit pointer)
266637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t ivars;          // const ivar_list_t * (64-bit pointer)
266737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t weakIvarLayout; // const uint8_t * (64-bit pointer)
266837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t baseProperties; // const struct objc_property_list (64-bit pointer)
266937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
267037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct class_ro32_t {
26720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t flags;
26730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceStart;
26740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceSize;
26750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivarLayout;     /* const uint8_t * (32-bit pointer) */
26760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;           /* const char * (32-bit pointer) */
26770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t baseMethods;    /* const method_list_t * (32-bit pointer) */
26780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t baseProtocols;  /* const protocol_list_t * (32-bit pointer) */
26790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivars;          /* const ivar_list_t * (32-bit pointer) */
26800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */
26810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t baseProperties; /* const struct objc_property_list *
26820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                   (32-bit pointer) */
26830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
26840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
26850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/* Values for class_ro{64,32}_t->flags */
26860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define RO_META (1 << 0)
26870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define RO_ROOT (1 << 1)
26880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define RO_HAS_CXX_STRUCTORS (1 << 2)
26890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
26900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct method_list64_t {
26910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
26920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
26930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct method64_t first;  These structures follow inline */
26940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
26950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
26960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct method_list32_t {
26970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
26980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
26990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct method32_t first;  These structures follow inline */
27000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct method64_t {
27030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t name;  /* SEL (64-bit pointer) */
27040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t types; /* const char * (64-bit pointer) */
27050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t imp;   /* IMP (64-bit pointer) */
27060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct method32_t {
27090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;  /* SEL (32-bit pointer) */
27100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t types; /* const char * (32-bit pointer) */
27110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t imp;   /* IMP (32-bit pointer) */
27120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct protocol_list64_t {
27150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t count; /* uintptr_t (a 64-bit value) */
27160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct protocol64_t * list[0];  These pointers follow inline */
27170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct protocol_list32_t {
27200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count; /* uintptr_t (a 32-bit value) */
27210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct protocol32_t * list[0];  These pointers follow inline */
27220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct protocol64_t {
27250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t isa;                     /* id * (64-bit pointer) */
27260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t name;                    /* const char * (64-bit pointer) */
27270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t protocols;               /* struct protocol_list64_t *
27280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                    (64-bit pointer) */
27290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t instanceMethods;         /* method_list_t * (64-bit pointer) */
27300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t classMethods;            /* method_list_t * (64-bit pointer) */
27310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */
27320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t optionalClassMethods;    /* method_list_t * (64-bit pointer) */
27330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t instanceProperties;      /* struct objc_property_list *
27340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                       (64-bit pointer) */
27350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct protocol32_t {
27380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t isa;                     /* id * (32-bit pointer) */
27390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;                    /* const char * (32-bit pointer) */
27400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocols;               /* struct protocol_list_t *
27410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                    (32-bit pointer) */
27420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceMethods;         /* method_list_t * (32-bit pointer) */
27430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t classMethods;            /* method_list_t * (32-bit pointer) */
27440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */
27450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t optionalClassMethods;    /* method_list_t * (32-bit pointer) */
27460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceProperties;      /* struct objc_property_list *
27470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                       (32-bit pointer) */
27480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct ivar_list64_t {
27510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
27520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
27530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct ivar64_t first;  These structures follow inline */
27540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct ivar_list32_t {
27570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
27580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
27590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct ivar32_t first;  These structures follow inline */
27600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct ivar64_t {
27630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t offset; /* uintptr_t * (64-bit pointer) */
27640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t name;   /* const char * (64-bit pointer) */
27650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t type;   /* const char * (64-bit pointer) */
27660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t alignment;
27670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t size;
27680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct ivar32_t {
27710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset; /* uintptr_t * (32-bit pointer) */
27720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;   /* const char * (32-bit pointer) */
27730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t type;   /* const char * (32-bit pointer) */
27740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t alignment;
27750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t size;
27760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_property_list64 {
27790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
27800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
27810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct objc_property64 first;  These structures follow inline */
27820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_property_list32 {
27850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t entsize;
27860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t count;
27870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /* struct objc_property32 first;  These structures follow inline */
27880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_property64 {
27910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t name;       /* const char * (64-bit pointer) */
27920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t attributes; /* const char * (64-bit pointer) */
27930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
27950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_property32 {
27960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;       /* const char * (32-bit pointer) */
27970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t attributes; /* const char * (32-bit pointer) */
27980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
27990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct category64_t {
28010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t name;               /* const char * (64-bit pointer) */
28020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t cls;                /* struct class_t * (64-bit pointer) */
28030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t instanceMethods;    /* struct method_list_t * (64-bit pointer) */
28040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t classMethods;       /* struct method_list_t * (64-bit pointer) */
28050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t protocols;          /* struct protocol_list_t * (64-bit pointer) */
28060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t instanceProperties; /* struct objc_property_list *
28070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  (64-bit pointer) */
28080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct category32_t {
28110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;               /* const char * (32-bit pointer) */
28120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t cls;                /* struct class_t * (32-bit pointer) */
28130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceMethods;    /* struct method_list_t * (32-bit pointer) */
28140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t classMethods;       /* struct method_list_t * (32-bit pointer) */
28150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocols;          /* struct protocol_list_t * (32-bit pointer) */
28160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instanceProperties; /* struct objc_property_list *
28170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  (32-bit pointer) */
28180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_image_info64 {
28210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t version;
28220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t flags;
28230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_image_info32 {
28250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t version;
28260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t flags;
28270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct imageInfo_t {
28290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t version;
28300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t flags;
28310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/* masks for objc_image_info.flags */
28330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define OBJC_IMAGE_IS_REPLACEMENT (1 << 0)
28340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define OBJC_IMAGE_SUPPORTS_GC (1 << 1)
28350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct message_ref64 {
28370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t imp; /* IMP (64-bit pointer) */
28380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t sel; /* SEL (64-bit pointer) */
28390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct message_ref32 {
28420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t imp; /* IMP (32-bit pointer) */
28430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t sel; /* SEL (32-bit pointer) */
28440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar// Objective-C 1 (32-bit only) meta data structs.
28470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_module_t {
28490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t version;
28500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t size;
28510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;   /* char * (32-bit pointer) */
28520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t symtab; /* struct objc_symtab * (32-bit pointer) */
28530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_symtab_t {
28560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t sel_ref_cnt;
28570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t refs; /* SEL * (32-bit pointer) */
28580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint16_t cls_def_cnt;
28590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint16_t cat_def_cnt;
28600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // uint32_t defs[1];        /* void * (32-bit pointer) variable size */
28610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_class_t {
28640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t isa;         /* struct objc_class * (32-bit pointer) */
28650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t super_class; /* struct objc_class * (32-bit pointer) */
28660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;        /* const char * (32-bit pointer) */
28670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t version;
28680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t info;
28690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t instance_size;
28700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivars;       /* struct objc_ivar_list * (32-bit pointer) */
28710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t methodLists; /* struct objc_method_list ** (32-bit pointer) */
28720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t cache;       /* struct objc_cache * (32-bit pointer) */
28730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocols;   /* struct objc_protocol_list * (32-bit pointer) */
28740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define CLS_GETINFO(cls, infomask) ((cls)->info & (infomask))
28770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar// class is not a metaclass
28780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define CLS_CLASS 0x1
28790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar// class is a metaclass
28800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#define CLS_META 0x2
28810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_category_t {
28830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t category_name;    /* char * (32-bit pointer) */
28840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t class_name;       /* char * (32-bit pointer) */
28850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instance_methods; /* struct objc_method_list * (32-bit pointer) */
28860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t class_methods;    /* struct objc_method_list * (32-bit pointer) */
28870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocols;        /* struct objc_protocol_list * (32-bit ptr) */
28880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_ivar_t {
28910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivar_name; /* char * (32-bit pointer) */
28920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivar_type; /* char * (32-bit pointer) */
28930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t ivar_offset;
28940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
28950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
28960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_ivar_list_t {
28970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t ivar_count;
28980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // struct objc_ivar_t ivar_list[1];          /* variable length structure */
28990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_method_list_t {
29020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t obsolete; /* struct objc_method_list * (32-bit pointer) */
29030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t method_count;
29040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // struct objc_method_t method_list[1];      /* variable length structure */
29050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_method_t {
29080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t method_name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
29090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t method_types; /* char * (32-bit pointer) */
29100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t method_imp;   /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
29110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                            (32-bit pointer) */
29120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_protocol_list_t {
29150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t next; /* struct objc_protocol_list * (32-bit pointer) */
29160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t count;
29170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // uint32_t list[1];   /* Protocol *, aka struct objc_protocol_t *
29180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  //                        (32-bit pointer) */
29190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_protocol_t {
29220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t isa;              /* struct objc_class * (32-bit pointer) */
29230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocol_name;    /* char * (32-bit pointer) */
29240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t protocol_list;    /* struct objc_protocol_list * (32-bit pointer) */
29250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t instance_methods; /* struct objc_method_description_list *
29260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                (32-bit pointer) */
29270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t class_methods;    /* struct objc_method_description_list *
29280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                (32-bit pointer) */
29290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_method_description_list_t {
29320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t count;
29330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // struct objc_method_description_t list[1];
29340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstruct objc_method_description_t {
29370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t name;  /* SEL, aka struct objc_selector * (32-bit pointer) */
29380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t types; /* char * (32-bit pointer) */
29390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar};
29400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
294137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesinline void swapStruct(struct cfstring64_t &cfs) {
294237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cfs.isa);
294337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cfs.flags);
294437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cfs.characters);
294537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cfs.length);
294637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
294737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
294837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesinline void swapStruct(struct class64_t &c) {
294937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(c.isa);
295037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(c.superclass);
295137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(c.cache);
295237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(c.vtable);
295337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(c.data);
295437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
295537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
29560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct class32_t &c) {
29570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.isa);
29580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.superclass);
29590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.cache);
29600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.vtable);
29610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.data);
29620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
29630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
296437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesinline void swapStruct(struct class_ro64_t &cro) {
296537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.flags);
296637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.instanceStart);
296737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.instanceSize);
296837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.reserved);
296937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.ivarLayout);
297037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.name);
297137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.baseMethods);
297237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.baseProtocols);
297337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.ivars);
297437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.weakIvarLayout);
297537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::swapByteOrder(cro.baseProperties);
297637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
297737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
29780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct class_ro32_t &cro) {
29790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.flags);
29800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.instanceStart);
29810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.instanceSize);
29820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.ivarLayout);
29830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.name);
29840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.baseMethods);
29850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.baseProtocols);
29860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.ivars);
29870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.weakIvarLayout);
29880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(cro.baseProperties);
29890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
29900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct method_list64_t &ml) {
29920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(ml.entsize);
29930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(ml.count);
29940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
29950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
29960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct method_list32_t &ml) {
29970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(ml.entsize);
29980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(ml.count);
29990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct method64_t &m) {
30020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.name);
30030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.types);
30040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.imp);
30050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct method32_t &m) {
30080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.name);
30090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.types);
30100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(m.imp);
30110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct protocol_list64_t &pl) {
30140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.count);
30150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct protocol_list32_t &pl) {
30180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.count);
30190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct protocol64_t &p) {
30220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.isa);
30230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.name);
30240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.protocols);
30250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.instanceMethods);
30260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.classMethods);
30270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.optionalInstanceMethods);
30280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.optionalClassMethods);
30290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.instanceProperties);
30300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct protocol32_t &p) {
30330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.isa);
30340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.name);
30350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.protocols);
30360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.instanceMethods);
30370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.classMethods);
30380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.optionalInstanceMethods);
30390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.optionalClassMethods);
30400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(p.instanceProperties);
30410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct ivar_list64_t &il) {
30440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(il.entsize);
30450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(il.count);
30460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct ivar_list32_t &il) {
30490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(il.entsize);
30500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(il.count);
30510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct ivar64_t &i) {
30540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.offset);
30550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.name);
30560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.type);
30570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.alignment);
30580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.size);
30590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct ivar32_t &i) {
30620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.offset);
30630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.name);
30640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.type);
30650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.alignment);
30660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(i.size);
30670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_property_list64 &pl) {
30700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.entsize);
30710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.count);
30720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_property_list32 &pl) {
30750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.entsize);
30760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(pl.count);
30770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_property64 &op) {
30800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(op.name);
30810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(op.attributes);
30820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_property32 &op) {
30850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(op.name);
30860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(op.attributes);
30870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct category64_t &c) {
30900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.name);
30910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.cls);
30920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.instanceMethods);
30930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.classMethods);
30940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.protocols);
30950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.instanceProperties);
30960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
30970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
30980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct category32_t &c) {
30990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.name);
31000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.cls);
31010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.instanceMethods);
31020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.classMethods);
31030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.protocols);
31040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(c.instanceProperties);
31050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_image_info64 &o) {
31080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.version);
31090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.flags);
31100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_image_info32 &o) {
31130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.version);
31140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.flags);
31150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct imageInfo_t &o) {
31180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.version);
31190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(o.flags);
31200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct message_ref64 &mr) {
31230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(mr.imp);
31240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(mr.sel);
31250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct message_ref32 &mr) {
31280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(mr.imp);
31290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(mr.sel);
31300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_module_t &module) {
31330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(module.version);
31340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(module.size);
31350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(module.name);
31360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(module.symtab);
31370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_symtab_t &symtab) {
31400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(symtab.sel_ref_cnt);
31410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(symtab.refs);
31420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(symtab.cls_def_cnt);
31430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(symtab.cat_def_cnt);
31440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_class_t &objc_class) {
31470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.isa);
31480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.super_class);
31490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.name);
31500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.version);
31510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.info);
31520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.instance_size);
31530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.ivars);
31540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.methodLists);
31550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.cache);
31560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_class.protocols);
31570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_category_t &objc_category) {
31600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_category.category_name);
31610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_category.class_name);
31620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_category.instance_methods);
31630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_category.class_methods);
31640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_category.protocols);
31650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_ivar_list_t &objc_ivar_list) {
31680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_ivar_list.ivar_count);
31690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_ivar_t &objc_ivar) {
31720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_ivar.ivar_name);
31730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_ivar.ivar_type);
31740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(objc_ivar.ivar_offset);
31750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_method_list_t &method_list) {
31780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(method_list.obsolete);
31790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(method_list.method_count);
31800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_method_t &method) {
31830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(method.method_name);
31840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(method.method_types);
31850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(method.method_imp);
31860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_protocol_list_t &protocol_list) {
31890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol_list.next);
31900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol_list.count);
31910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
31920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
31930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_protocol_t &protocol) {
31940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol.isa);
31950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol.protocol_name);
31960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol.protocol_list);
31970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol.instance_methods);
31980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(protocol.class_methods);
31990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
32000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
32010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_method_description_list_t &mdl) {
32020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(mdl.count);
32030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
32040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
32050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarinline void swapStruct(struct objc_method_description_t &md) {
32060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(md.name);
32070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::swapByteOrder(md.types);
32080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
32090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
321037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
321137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                 struct DisassembleInfo *info);
321237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
321337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_objc2_64bit_class_name() is used for disassembly and is passed a pointer
321437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// to an Objective-C class and returns the class name.  It is also passed the
321537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// address of the pointer, so when the pointer is zero as it can be in an .o
321637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// file, that is used to look for an external relocation entry with a symbol
321737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// name.
32184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *get_objc2_64bit_class_name(uint64_t pointer_value,
32194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                              uint64_t ReferenceValue,
32204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                              struct DisassembleInfo *info) {
322137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *r;
322237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t offset, left;
322337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SectionRef S;
322437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
322537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The pointer_value can be 0 in an object file and have a relocation
322637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // entry for the class symbol at the ReferenceValue (the address of the
322737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // pointer).
322837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (pointer_value == 0) {
322937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    r = get_pointer_64(ReferenceValue, offset, left, S, info);
323037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (r == nullptr || left < sizeof(uint64_t))
323137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return nullptr;
323237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t n_value;
323337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *symbol_name = get_symbol_64(offset, S, info, n_value);
323437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (symbol_name == nullptr)
323537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return nullptr;
323637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *class_name = strrchr(symbol_name, '$');
323737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (class_name != nullptr && class_name[1] == '_' && class_name[2] != '\0')
323837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return class_name + 2;
323937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
324037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return nullptr;
324137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
324237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
324337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The case were the pointer_value is non-zero and points to a class defined
324437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // in this Mach-O file.
324537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  r = get_pointer_64(pointer_value, offset, left, S, info);
324637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (r == nullptr || left < sizeof(struct class64_t))
324737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
324837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct class64_t c;
324937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  memcpy(&c, r, sizeof(struct class64_t));
325037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
325137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    swapStruct(c);
325237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (c.data == 0)
325337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
325437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  r = get_pointer_64(c.data, offset, left, S, info);
325537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (r == nullptr || left < sizeof(struct class_ro64_t))
325637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
325737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct class_ro64_t cro;
325837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  memcpy(&cro, r, sizeof(struct class_ro64_t));
325937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
326037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    swapStruct(cro);
326137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cro.name == 0)
326237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
326337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *name = get_pointer_64(cro.name, offset, left, S, info);
326437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return name;
326537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
326637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
326737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_objc2_64bit_cfstring_name is used for disassembly and is passed a
326837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// pointer to a cfstring and returns its name or nullptr.
32694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *get_objc2_64bit_cfstring_name(uint64_t ReferenceValue,
32704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                                 struct DisassembleInfo *info) {
327137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *r, *name;
327237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t offset, left;
327337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SectionRef S;
327437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct cfstring64_t cfs;
327537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t cfs_characters;
327637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
327737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  r = get_pointer_64(ReferenceValue, offset, left, S, info);
327837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (r == nullptr || left < sizeof(struct cfstring64_t))
327937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
328037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  memcpy(&cfs, r, sizeof(struct cfstring64_t));
328137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
328237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    swapStruct(cfs);
328337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cfs.characters == 0) {
328437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t n_value;
328537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *symbol_name = get_symbol_64(
328637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        offset + offsetof(struct cfstring64_t, characters), S, info, n_value);
328737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (symbol_name == nullptr)
328837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return nullptr;
328937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    cfs_characters = n_value;
329037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else
329137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    cfs_characters = cfs.characters;
329237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  name = get_pointer_64(cfs_characters, offset, left, S, info);
329337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
329437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return name;
329537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
329637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
329737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_objc2_64bit_selref() is used for disassembly and is passed a the address
329837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// of a pointer to an Objective-C selector reference when the pointer value is
329937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// zero as in a .o file and is likely to have a external relocation entry with
330037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// who's symbol's n_value is the real pointer to the selector name.  If that is
330137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the case the real pointer to the selector name is returned else 0 is
330237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// returned
33034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic uint64_t get_objc2_64bit_selref(uint64_t ReferenceValue,
33044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
330537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t offset, left;
330637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SectionRef S;
330737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
330837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *r = get_pointer_64(ReferenceValue, offset, left, S, info);
330937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (r == nullptr || left < sizeof(uint64_t))
331037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 0;
331137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t n_value;
331237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *symbol_name = get_symbol_64(offset, S, info, n_value);
331337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (symbol_name == nullptr)
331437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return 0;
331537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return n_value;
331637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
331737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
33180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic const SectionRef get_section(MachOObjectFile *O, const char *segname,
33190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                    const char *sectname) {
33200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
33210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SectName;
33220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Section.getName(SectName);
33230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    DataRefImpl Ref = Section.getRawDataRefImpl();
33240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SegName = O->getSectionFinalSegmentName(Ref);
33250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (SegName == segname && SectName == sectname)
33260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return Section;
33270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
33280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return SectionRef();
33290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
33300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void
33320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarwalk_pointer_list_64(const char *listname, const SectionRef S,
33330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                     MachOObjectFile *O, struct DisassembleInfo *info,
33340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                     void (*func)(uint64_t, struct DisassembleInfo *info)) {
33350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (S == SectionRef())
33360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
33370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
33390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
33400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
33410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = O->getSectionFinalSegmentName(Ref);
33420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
33430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef BytesStr;
33450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getContents(BytesStr);
33460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
33470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint64_t)) {
33490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t left = S.getSize() - i;
33500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t size = left < sizeof(uint64_t) ? left : sizeof(uint64_t);
33510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint64_t p = 0;
33520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&p, Contents + i, size);
33530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (i + sizeof(uint64_t) > S.getSize())
33540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << listname << " list pointer extends past end of (" << SegName
33550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << "," << SectName << ") section\n";
33560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("%016" PRIx64, S.getAddress() + i) << " ";
33570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (O->isLittleEndian() != sys::IsLittleEndianHost)
33590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(p);
33600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint64_t n_value = 0;
33620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const char *name = get_symbol_64(i, S, info, n_value, p);
33630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name == nullptr)
33640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      name = get_dyld_bind_info_symbolname(S.getAddress() + i, info);
33650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
33670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
33680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (p != 0)
33690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, p);
33700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
33710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, p);
33720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
33730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
33740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
33750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += n_value;
33770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (func)
33780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      func(p, info);
33790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
33800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
33810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void
33830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarwalk_pointer_list_32(const char *listname, const SectionRef S,
33840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                     MachOObjectFile *O, struct DisassembleInfo *info,
33850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                     void (*func)(uint32_t, struct DisassembleInfo *info)) {
33860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (S == SectionRef())
33870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
33880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
33900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
33910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
33920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = O->getSectionFinalSegmentName(Ref);
33930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
33940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef BytesStr;
33960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getContents(BytesStr);
33970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
33980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
33990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) {
34000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t left = S.getSize() - i;
34010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t);
34020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t p = 0;
34030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&p, Contents + i, size);
34040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (i + sizeof(uint32_t) > S.getSize())
34050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << listname << " list pointer extends past end of (" << SegName
34060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << "," << SectName << ") section\n";
34070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    uint32_t Address = S.getAddress() + i;
34080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("%08" PRIx32, Address) << " ";
34090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (O->isLittleEndian() != sys::IsLittleEndianHost)
34110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(p);
34120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx32, p);
34130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const char *name = get_symbol_32(i, S, info, p);
34150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
34160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
34170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
34180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (func)
34200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      func(p, info);
34210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
34220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
34230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_layout_map(const char *layout_map, uint32_t left) {
3425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (layout_map == nullptr)
3426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return;
34270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                layout map: ";
34280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  do {
34290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " ";
34300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    left--;
34310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    layout_map++;
34320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } while (*layout_map != '\0' && left != 0);
34330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
34340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
34350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_layout_map64(uint64_t p, struct DisassembleInfo *info) {
34370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
34380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
34390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *layout_map;
34400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (p == 0)
34420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
34430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  layout_map = get_pointer_64(p, offset, left, S, info);
34440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map(layout_map, left);
34450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
34460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_layout_map32(uint32_t p, struct DisassembleInfo *info) {
34480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
34490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
34500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *layout_map;
34510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (p == 0)
34530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
34540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  layout_map = get_pointer_32(p, offset, left, S, info);
34550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map(layout_map, left);
34560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
34570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_method_list64_t(uint64_t p, struct DisassembleInfo *info,
34590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  const char *indent) {
34600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct method_list64_t ml;
34610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct method64_t m;
34620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
34630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, i;
34640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
34650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
34660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t n_value;
34670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
34690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
34700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
34710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&ml, '\0', sizeof(struct method_list64_t));
34720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct method_list64_t)) {
34730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&ml, r, left);
34740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (method_list_t entends past the end of the section)\n";
34750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
34760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&ml, r, sizeof(struct method_list64_t));
34770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
34780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(ml);
34790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
34800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << indent << "\t\t     count " << ml.count << "\n";
34810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct method_list64_t);
34830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct method_list64_t);
34840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < ml.count; i++) {
34850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(p, offset, left, S, info);
34860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
34870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
34880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&m, '\0', sizeof(struct method64_t));
34890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct method64_t)) {
3490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      memcpy(&m, r, left);
3491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << indent << "   (method_t extends past the end of the section)\n";
34920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
34930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&m, r, sizeof(struct method64_t));
34940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
34950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(m);
34960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
34970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t      name ";
34980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct method64_t, name), S,
34990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, m.name);
35000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
35010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
35020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
35030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
35040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
35050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (m.name != 0)
35060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, m.name);
35070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
35080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, m.name);
35090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(m.name + n_value, xoffset, left, xS, info);
35100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
35110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
35120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
35130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t     types ";
35150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct method64_t, types), S,
35160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, m.types);
35170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
35180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
35190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
35200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
35210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
35220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (m.types != 0)
35230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, m.types);
35240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
35250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, m.types);
35260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(m.types + n_value, xoffset, left, xS, info);
35270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
35280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
35290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
35300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t       imp ";
35320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info,
35330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                         n_value, m.imp);
35340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && name == nullptr) {
35350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (n_value != 0) {
35360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value) << " ";
35370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (m.imp != 0)
35380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << "+ " << format("0x%" PRIx64, m.imp) << " ";
35390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      } else
35400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, m.imp) << " ";
35410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
35420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
35430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << name;
35440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
35450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct method64_t);
35470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct method64_t);
35480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
35490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
35500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_method_list32_t(uint64_t p, struct DisassembleInfo *info,
35520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                  const char *indent) {
35530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct method_list32_t ml;
35540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct method32_t m;
35550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *name;
35560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, i;
35570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
35580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
35600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
35610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
35620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&ml, '\0', sizeof(struct method_list32_t));
35630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct method_list32_t)) {
35640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&ml, r, left);
35650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (method_list_t entends past the end of the section)\n";
35660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
35670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&ml, r, sizeof(struct method_list32_t));
35680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
35690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(ml);
35700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << indent << "\t\t   entsize " << ml.entsize << "\n";
35710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << indent << "\t\t     count " << ml.count << "\n";
35720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct method_list32_t);
35740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct method_list32_t);
35750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < ml.count; i++) {
35760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, info);
35770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
35780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
35790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&m, '\0', sizeof(struct method32_t));
35800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct method32_t)) {
35810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&ml, r, left);
35820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << indent << "   (method_t entends past the end of the section)\n";
35830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
35840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&m, r, sizeof(struct method32_t));
35850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
35860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(m);
35870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t      name " << format("0x%" PRIx32, m.name);
35890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(m.name, xoffset, left, xS, info);
35900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
35910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
35920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
35930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
35940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t     types " << format("0x%" PRIx32, m.types);
35950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(m.types, xoffset, left, xS, info);
35960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
35970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
35980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
35990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << indent << "\t\t       imp " << format("0x%" PRIx32, m.imp);
36010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info,
36020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                         m.imp);
36030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
36040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
36050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
36060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct method32_t);
36080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct method32_t);
36090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
36100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
36110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool print_method_list(uint32_t p, struct DisassembleInfo *info) {
36130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left, xleft;
36140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
36150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_method_list_t method_list;
36160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_method_t method;
36170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *methods, *name, *SymbolName;
36180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t i;
36190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info, true);
36210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
36220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return true;
36230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
36250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left > sizeof(struct objc_method_list_t)) {
36260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&method_list, r, sizeof(struct objc_method_list_t));
36270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
36280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t objc_method_list extends past end of the section\n";
36290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&method_list, '\0', sizeof(struct objc_method_list_t));
36300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&method_list, r, left);
36310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
36320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
36330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(method_list);
36340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t         obsolete "
36360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, method_list.obsolete) << "\n";
36370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t     method_count " << method_list.method_count << "\n";
36380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  methods = r + sizeof(struct objc_method_list_t);
36400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < method_list.method_count; i++) {
36410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if ((i + 1) * sizeof(struct objc_method_t) > left) {
36420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t\t remaining method's extend past the of the section\n";
36430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      break;
36440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
36450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&method, methods + i * sizeof(struct objc_method_t),
36460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           sizeof(struct objc_method_t));
36470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
36480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(method);
36490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t      method_name "
36510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%08" PRIx32, method.method_name);
36520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose) {
36530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      name = get_pointer_32(method.method_name, offset, xleft, S, info, true);
36540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (name != nullptr)
36550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format(" %.*s", xleft, name);
36560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
36570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " (not in an __OBJC section)";
36580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
36590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
36600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t     method_types "
36620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%08" PRIx32, method.method_types);
36630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose) {
36640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      name = get_pointer_32(method.method_types, offset, xleft, S, info, true);
36650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (name != nullptr)
36660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format(" %.*s", xleft, name);
36670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
36680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " (not in an __OBJC section)";
36690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
36700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
36710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t       method_imp "
36730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%08" PRIx32, method.method_imp) << " ";
36740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose) {
36750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      SymbolName = GuessSymbolName(method.method_imp, info->AddrMap);
36760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (SymbolName != nullptr)
36770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << SymbolName;
36780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
36790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
36800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
36810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return false;
36820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
36830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) {
36850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct protocol_list64_t pl;
36860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t q, n_value;
36870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct protocol64_t pc;
36880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
36890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, i;
36900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
36910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
36920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
36930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
36940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
36950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
36960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&pl, '\0', sizeof(struct protocol_list64_t));
36970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct protocol_list64_t)) {
36980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&pl, r, left);
36990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (protocol_list_t entends past the end of the section)\n";
37000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
37010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&pl, r, sizeof(struct protocol_list64_t));
37020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
37030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(pl);
37040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << pl.count << "\n";
37050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct protocol_list64_t);
37070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct protocol_list64_t);
37080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < pl.count; i++) {
37090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(p, offset, left, S, info);
37100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
37110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
37120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    q = 0;
37130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(uint64_t)) {
37140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&q, r, left);
37150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (protocol_t * entends past the end of the section)\n";
37160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&q, r, sizeof(uint64_t));
37180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
37190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(q);
37200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t      list[" << i << "] ";
37220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset, S, info, n_value, q);
37230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
37240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
37250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
37260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
37270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
37280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (q != 0)
37290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, q);
37300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, q);
37320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (struct protocol_t *)\n";
37330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(q + n_value, offset, left, S, info);
37350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
37360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
37370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&pc, '\0', sizeof(struct protocol64_t));
37380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct protocol64_t)) {
37390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&pc, r, left);
37400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (protocol_t entends past the end of the section)\n";
37410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&pc, r, sizeof(struct protocol64_t));
37430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
37440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(pc);
37450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t      isa " << format("0x%" PRIx64, pc.isa) << "\n";
37470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name ";
37490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S,
37500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, pc.name);
37510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
37520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
37530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
37540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
37550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
37560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (pc.name != 0)
37570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, pc.name);
37580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, pc.name);
37600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info);
37610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
37620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
37630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
37640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n";
37660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t  instanceMethods ";
37680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name =
37690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods),
37700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                      S, info, n_value, pc.instanceMethods);
37710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
37720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
37730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
37740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
37750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
37760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (pc.instanceMethods != 0)
37770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, pc.instanceMethods);
37780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, pc.instanceMethods);
37800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (struct method_list_t *)\n";
37810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (pc.instanceMethods + n_value != 0)
37820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      print_method_list64_t(pc.instanceMethods + n_value, info, "\t");
37830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
37840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t     classMethods ";
37850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name =
37860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S,
37870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                      info, n_value, pc.classMethods);
37880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
37890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
37900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
37910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
37920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
37930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (pc.classMethods != 0)
37940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, pc.classMethods);
37950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
37960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, pc.classMethods);
37970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (struct method_list_t *)\n";
37980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (pc.classMethods + n_value != 0)
37990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      print_method_list64_t(pc.classMethods + n_value, info, "\t");
38000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t  optionalInstanceMethods "
38020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n";
38030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t     optionalClassMethods "
38040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx64, pc.optionalClassMethods) << "\n";
38050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t       instanceProperties "
38060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx64, pc.instanceProperties) << "\n";
38070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(uint64_t);
38090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(uint64_t);
38100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
38110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
38120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) {
38140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct protocol_list32_t pl;
38150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t q;
38160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct protocol32_t pc;
38170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
38180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, i;
38190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
38200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
38210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
38230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
38240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
38250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&pl, '\0', sizeof(struct protocol_list32_t));
38260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct protocol_list32_t)) {
38270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&pl, r, left);
38280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (protocol_list_t entends past the end of the section)\n";
38290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
38300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&pl, r, sizeof(struct protocol_list32_t));
38310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
38320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(pl);
38330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << pl.count << "\n";
38340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct protocol_list32_t);
38360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct protocol_list32_t);
38370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < pl.count; i++) {
38380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, info);
38390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
38400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
38410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    q = 0;
38420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(uint32_t)) {
38430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&q, r, left);
38440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (protocol_t * entends past the end of the section)\n";
38450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
38460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&q, r, sizeof(uint32_t));
38470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
38480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(q);
38490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t      list[" << i << "] " << format("0x%" PRIx32, q)
38500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << " (struct protocol_t *)\n";
38510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(q, offset, left, S, info);
38520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
38530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
38540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&pc, '\0', sizeof(struct protocol32_t));
38550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct protocol32_t)) {
38560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&pc, r, left);
38570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (protocol_t entends past the end of the section)\n";
38580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
38590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&pc, r, sizeof(struct protocol32_t));
38600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
38610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(pc);
38620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t      isa " << format("0x%" PRIx32, pc.isa) << "\n";
38630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name " << format("0x%" PRIx32, pc.name);
38640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(pc.name, xoffset, left, xS, info);
38650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
38660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
38670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
38680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n";
38690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t  instanceMethods "
38700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx32, pc.instanceMethods)
38710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << " (struct method_list_t *)\n";
38720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (pc.instanceMethods != 0)
38730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      print_method_list32_t(pc.instanceMethods, info, "\t");
38740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t     classMethods " << format("0x%" PRIx32, pc.classMethods)
38750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << " (struct method_list_t *)\n";
38760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (pc.classMethods != 0)
38770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      print_method_list32_t(pc.classMethods, info, "\t");
38780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t  optionalInstanceMethods "
38790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n";
38800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t     optionalClassMethods "
38810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx32, pc.optionalClassMethods) << "\n";
38820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t       instanceProperties "
38830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           << format("0x%" PRIx32, pc.instanceProperties) << "\n";
38840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(uint32_t);
38850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(uint32_t);
38860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
38870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
38880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
38890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_indent(uint32_t indent) {
38900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (uint32_t i = 0; i < indent;) {
38910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (indent - i >= 8) {
38920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t";
38930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      i += 8;
38940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else {
38950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      for (uint32_t j = i; j < indent; j++)
38960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " ";
38970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
38980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
38990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
39000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
39010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool print_method_description_list(uint32_t p, uint32_t indent,
39030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                          struct DisassembleInfo *info) {
39040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left, xleft;
39050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
39060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_method_description_list_t mdl;
39070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_method_description_t md;
39080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *list, *name;
39090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t i;
39100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info, true);
39120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
39130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return true;
39140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
39160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left > sizeof(struct objc_method_description_list_t)) {
39170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&mdl, r, sizeof(struct objc_method_description_list_t));
39180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
39190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
39200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " objc_method_description_list extends past end of the section\n";
39210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&mdl, '\0', sizeof(struct objc_method_description_list_t));
39220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&mdl, r, left);
39230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
39240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
39250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(mdl);
39260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
39280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "        count " << mdl.count << "\n";
39290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  list = r + sizeof(struct objc_method_description_list_t);
39310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < mdl.count; i++) {
39320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if ((i + 1) * sizeof(struct objc_method_description_t) > left) {
39330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      print_indent(indent);
39340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " remaining list entries extend past the of the section\n";
39350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      break;
39360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
39370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
39380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "        list[" << i << "]\n";
39390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&md, list + i * sizeof(struct objc_method_description_t),
39400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar           sizeof(struct objc_method_description_t));
39410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
39420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(md);
39430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
39450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "             name " << format("0x%08" PRIx32, md.name);
39460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose) {
39470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      name = get_pointer_32(md.name, offset, xleft, S, info, true);
39480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (name != nullptr)
39490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format(" %.*s", xleft, name);
39500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
39510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " (not in an __OBJC section)";
39520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
39530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
39540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
39560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "            types " << format("0x%08" PRIx32, md.types);
39570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose) {
39580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      name = get_pointer_32(md.types, offset, xleft, S, info, true);
39590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (name != nullptr)
39600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format(" %.*s", xleft, name);
39610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
39620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " (not in an __OBJC section)";
39630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
39640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
39650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
39660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return false;
39670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
39680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool print_protocol_list(uint32_t p, uint32_t indent,
39700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                struct DisassembleInfo *info);
39710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool print_protocol(uint32_t p, uint32_t indent,
39730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           struct DisassembleInfo *info) {
39740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
39750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
39760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_protocol_t protocol;
39770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *name;
39780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info, true);
39800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
39810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return true;
39820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
39840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left >= sizeof(struct objc_protocol_t)) {
39850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&protocol, r, sizeof(struct objc_protocol_t));
39860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
39870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
39880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "            Protocol extends past end of the section\n";
39890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&protocol, '\0', sizeof(struct objc_protocol_t));
39900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&protocol, r, left);
39910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
39920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
39930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(protocol);
39940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
39960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "              isa " << format("0x%08" PRIx32, protocol.isa)
39970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
39980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
39990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    protocol_name "
40010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, protocol.protocol_name);
40020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
40030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(protocol.protocol_name, offset, left, S, info, true);
40040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
40050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
40060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
40070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
40080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
40090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
40100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    protocol_list "
40130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, protocol.protocol_list);
40140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_protocol_list(protocol.protocol_list, indent + 4, info))
40150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
40160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << " instance_methods "
40190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, protocol.instance_methods);
40200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_method_description_list(protocol.instance_methods, indent, info))
40210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
40220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    class_methods "
40250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, protocol.class_methods);
40260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_method_description_list(protocol.class_methods, indent, info))
40270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
40280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return false;
40300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
40310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool print_protocol_list(uint32_t p, uint32_t indent,
40330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                struct DisassembleInfo *info) {
40340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left, l;
40350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
40360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_protocol_list_t protocol_list;
40370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *list;
40380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t i;
40390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info, true);
40410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
40420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return true;
40430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
40450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left > sizeof(struct objc_protocol_list_t)) {
40460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&protocol_list, r, sizeof(struct objc_protocol_list_t));
40470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
40480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t objc_protocol_list_t extends past end of the section\n";
40490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&protocol_list, '\0', sizeof(struct objc_protocol_list_t));
40500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&protocol_list, r, left);
40510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
40520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
40530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(protocol_list);
40540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "         next " << format("0x%08" PRIx32, protocol_list.next)
40570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
40580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_indent(indent);
40590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "        count " << protocol_list.count << "\n";
40600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  list = r + sizeof(struct objc_protocol_list_t);
40620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < protocol_list.count; i++) {
40630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if ((i + 1) * sizeof(uint32_t) > left) {
40640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t\t remaining list entries extend past the of the section\n";
40650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      break;
40660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
40670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&l, list + i * sizeof(uint32_t), sizeof(uint32_t));
40680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
40690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      sys::swapByteOrder(l);
40700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_indent(indent);
40720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "      list[" << i << "] " << format("0x%08" PRIx32, l);
40730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (print_protocol(l, indent, info))
40740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "(not in an __OBJC section)\n";
40750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
40760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return false;
40770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
40780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) {
40800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct ivar_list64_t il;
40810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct ivar64_t i;
40820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
40830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, j;
40840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
40850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name, *ivar_offset_p;
40860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t ivar_offset, n_value;
40870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
40880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
40890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
40900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
40910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&il, '\0', sizeof(struct ivar_list64_t));
40920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct ivar_list64_t)) {
40930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&il, r, left);
40940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (ivar_list_t entends past the end of the section)\n";
40950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
40960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&il, r, sizeof(struct ivar_list64_t));
40970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
40980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(il);
40990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    entsize " << il.entsize << "\n";
41000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << il.count << "\n";
41010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct ivar_list64_t);
41030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct ivar_list64_t);
41040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (j = 0; j < il.count; j++) {
41050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(p, offset, left, S, info);
41060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
41070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
41080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&i, '\0', sizeof(struct ivar64_t));
41090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct ivar64_t)) {
41100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&i, r, left);
41110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (ivar_t entends past the end of the section)\n";
41120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
41130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&i, r, sizeof(struct ivar64_t));
41140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
41150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(i);
41160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t   offset ";
41180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, offset), S,
41190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, i.offset);
41200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
41210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
41220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
41230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
41240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
41250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (i.offset != 0)
41260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, i.offset);
41270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
41280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, i.offset);
41290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    ivar_offset_p = get_pointer_64(i.offset + n_value, xoffset, left, xS, info);
41300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
41310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
41320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
41330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        sys::swapByteOrder(ivar_offset);
41340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << ivar_offset << "\n";
41350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
41360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\n";
41370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name ";
41390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, name), S, info,
41400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             n_value, i.name);
41410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
41420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
41430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
41440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
41450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
41460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (i.name != 0)
41470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, i.name);
41480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
41490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, i.name);
41500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(i.name + n_value, xoffset, left, xS, info);
41510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
41520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
41530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
41540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     type ";
41560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct ivar64_t, type), S, info,
41570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             n_value, i.name);
41580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(i.type + n_value, xoffset, left, xS, info);
41590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
41600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
41610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
41620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
41630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
41640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (i.type != 0)
41650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, i.type);
41660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
41670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, i.type);
41680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
41690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
41700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
41710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\talignment " << i.alignment << "\n";
41730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     size " << i.size << "\n";
41740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct ivar64_t);
41760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct ivar64_t);
41770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
41780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
41790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) {
41810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct ivar_list32_t il;
41820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct ivar32_t i;
41830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
41840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, j;
41850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
41860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *ivar_offset_p;
41870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t ivar_offset;
41880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
41890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
41900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
41910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
41920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&il, '\0', sizeof(struct ivar_list32_t));
41930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct ivar_list32_t)) {
41940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&il, r, left);
41950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (ivar_list_t entends past the end of the section)\n";
41960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
41970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&il, r, sizeof(struct ivar_list32_t));
41980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
41990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(il);
42000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    entsize " << il.entsize << "\n";
42010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << il.count << "\n";
42020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct ivar_list32_t);
42040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct ivar_list32_t);
42050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (j = 0; j < il.count; j++) {
42060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, info);
42070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
42080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
42090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&i, '\0', sizeof(struct ivar32_t));
42100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct ivar32_t)) {
42110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&i, r, left);
42120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (ivar_t entends past the end of the section)\n";
42130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
42140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&i, r, sizeof(struct ivar32_t));
42150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
42160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(i);
42170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t   offset " << format("0x%" PRIx32, i.offset);
42190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info);
42200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) {
42210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset));
42220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
42230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        sys::swapByteOrder(ivar_offset);
42240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << ivar_offset << "\n";
42250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
42260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\n";
42270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name " << format("0x%" PRIx32, i.name);
42290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(i.name, xoffset, left, xS, info);
42300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
42310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
42320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
42330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     type " << format("0x%" PRIx32, i.type);
42350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(i.type, xoffset, left, xS, info);
42360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
42370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
42380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
42390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\talignment " << i.alignment << "\n";
42410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     size " << i.size << "\n";
42420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct ivar32_t);
42440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct ivar32_t);
42450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
42460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
42470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_objc_property_list64(uint64_t p,
42490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
42500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_property_list64 opl;
42510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_property64 op;
42520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
42530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, j;
42540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
42550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
42560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t n_value;
42570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
42590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
42600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
42610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&opl, '\0', sizeof(struct objc_property_list64));
42620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct objc_property_list64)) {
42630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&opl, r, left);
42640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (objc_property_list entends past the end of the section)\n";
42650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
42660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&opl, r, sizeof(struct objc_property_list64));
42670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
42680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(opl);
42690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    entsize " << opl.entsize << "\n";
42700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << opl.count << "\n";
42710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct objc_property_list64);
42730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct objc_property_list64);
42740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (j = 0; j < opl.count; j++) {
42750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(p, offset, left, S, info);
42760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
42770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
42780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&op, '\0', sizeof(struct objc_property64));
42790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct objc_property64)) {
42800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&op, r, left);
42810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (objc_property entends past the end of the section)\n";
42820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
42830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&op, r, sizeof(struct objc_property64));
42840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
42850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(op);
42860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
42870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name ";
42880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct objc_property64, name), S,
42890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, op.name);
42900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
42910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
42920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
42930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
42940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
42950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (op.name != 0)
42960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, op.name);
42970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
42980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, op.name);
42990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(op.name + n_value, xoffset, left, xS, info);
43000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
43010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
43020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
43030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\tattributes ";
43050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name =
43060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        get_symbol_64(offset + offsetof(struct objc_property64, attributes), S,
43070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                      info, n_value, op.attributes);
43080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
43090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
43100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
43110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
43120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
43130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (op.attributes != 0)
43140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, op.attributes);
43150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
43160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, op.attributes);
43170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(op.attributes + n_value, xoffset, left, xS, info);
43180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
43190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
43200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
43210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct objc_property64);
43230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct objc_property64);
43240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
43250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
43260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_objc_property_list32(uint32_t p,
43280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
43290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_property_list32 opl;
43300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_property32 op;
43310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
43320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left, j;
43330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
43340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
43350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
43370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
43380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
43390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&opl, '\0', sizeof(struct objc_property_list32));
43400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct objc_property_list32)) {
43410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&opl, r, left);
43420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (objc_property_list entends past the end of the section)\n";
43430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
43440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&opl, r, sizeof(struct objc_property_list32));
43450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
43460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(opl);
43470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    entsize " << opl.entsize << "\n";
43480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                      count " << opl.count << "\n";
43490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p += sizeof(struct objc_property_list32);
43510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset += sizeof(struct objc_property_list32);
43520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (j = 0; j < opl.count; j++) {
43530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, info);
43540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
43550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
43560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&op, '\0', sizeof(struct objc_property32));
43570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct objc_property32)) {
43580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&op, r, left);
43590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (objc_property entends past the end of the section)\n";
43600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
43610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&op, r, sizeof(struct objc_property32));
43620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
43630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(op);
43640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\t     name " << format("0x%" PRIx32, op.name);
43660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(op.name, xoffset, left, xS, info);
43670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
43680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
43690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
43700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes);
43720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(op.attributes, xoffset, left, xS, info);
43730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
43740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
43750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
43760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p += sizeof(struct objc_property32);
43780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct objc_property32);
43790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
43800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
43810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic bool print_class_ro64_t(uint64_t p, struct DisassembleInfo *info,
43830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                               bool &is_meta_class) {
43840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct class_ro64_t cro;
43850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
43860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left;
43870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
43880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
43890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t n_value;
43900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
43910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
43920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr || left < sizeof(struct class_ro64_t))
4393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
43940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&cro, '\0', sizeof(struct class_ro64_t));
43950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct class_ro64_t)) {
43960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&cro, r, left);
43970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (class_ro_t entends past the end of the section)\n";
43980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
43990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&cro, r, sizeof(struct class_ro64_t));
44000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
44010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(cro);
44020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
44030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_META)
44040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_META";
44050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_ROOT)
44060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_ROOT";
44070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_HAS_CXX_STRUCTORS)
44080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_HAS_CXX_STRUCTORS";
44090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
44100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "            instanceStart " << cro.instanceStart << "\n";
44110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "             instanceSize " << cro.instanceSize << "\n";
44120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                 reserved " << format("0x%" PRIx32, cro.reserved)
44130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
44140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "               ivarLayout " << format("0x%" PRIx64, cro.ivarLayout)
44150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
44160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map64(cro.ivarLayout, info);
44170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
44180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                     name ";
44190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, name), S,
44200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           info, n_value, cro.name);
44210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
44220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
44230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
44240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
44250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
44260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.name != 0)
44270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.name);
44280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
44290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.name);
44300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_pointer_64(cro.name + n_value, xoffset, left, xS, info);
44310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
44320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format(" %.*s", left, name);
44330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
44340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
44350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "              baseMethods ";
44360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, baseMethods),
44370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           S, info, n_value, cro.baseMethods);
44380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
44390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
44400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
44410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
44420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
44430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.baseMethods != 0)
44440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.baseMethods);
44450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
44460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.baseMethods);
44470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << " (struct method_list_t *)\n";
44480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseMethods + n_value != 0)
44490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list64_t(cro.baseMethods + n_value, info, "");
44500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
44510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "            baseProtocols ";
44520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name =
44530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_64(offset + offsetof(struct class_ro64_t, baseProtocols), S,
44540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                    info, n_value, cro.baseProtocols);
44550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
44560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
44570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
44580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
44590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
44600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.baseProtocols != 0)
44610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.baseProtocols);
44620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
44630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.baseProtocols);
44640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
44650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseProtocols + n_value != 0)
44660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_protocol_list64_t(cro.baseProtocols + n_value, info);
44670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
44680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    ivars ";
44690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S,
44700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           info, n_value, cro.ivars);
44710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
44720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
44730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
44740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
44750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
44760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.ivars != 0)
44770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.ivars);
44780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
44790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.ivars);
44800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
44810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.ivars + n_value != 0)
44820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_ivar_list64_t(cro.ivars + n_value, info);
44830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
44840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           weakIvarLayout ";
44850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name =
44860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_64(offset + offsetof(struct class_ro64_t, weakIvarLayout), S,
44870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                    info, n_value, cro.weakIvarLayout);
44880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
44890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
44900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
44910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
44920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
44930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.weakIvarLayout != 0)
44940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.weakIvarLayout);
44950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
44960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.weakIvarLayout);
44970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
44980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map64(cro.weakIvarLayout + n_value, info);
44990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           baseProperties ";
45010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name =
45020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_64(offset + offsetof(struct class_ro64_t, baseProperties), S,
45030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                    info, n_value, cro.baseProperties);
45040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
45050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
45060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
45070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
45080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
45090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (cro.baseProperties != 0)
45100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, cro.baseProperties);
45110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
45120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, cro.baseProperties);
45130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
45140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseProperties + n_value != 0)
45150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_objc_property_list64(cro.baseProperties + n_value, info);
45160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  is_meta_class = (cro.flags & RO_META) != 0;
4518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
45190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
45200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic bool print_class_ro32_t(uint32_t p, struct DisassembleInfo *info,
45220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                               bool &is_meta_class) {
45230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct class_ro32_t cro;
45240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
45250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left;
45260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
45270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
45280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
45300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
4531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
45320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&cro, '\0', sizeof(struct class_ro32_t));
45330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct class_ro32_t)) {
45340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&cro, r, left);
45350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (class_ro_t entends past the end of the section)\n";
45360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
45370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&cro, r, sizeof(struct class_ro32_t));
45380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
45390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(cro);
45400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    flags " << format("0x%" PRIx32, cro.flags);
45410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_META)
45420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_META";
45430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_ROOT)
45440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_ROOT";
45450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.flags & RO_HAS_CXX_STRUCTORS)
45460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RO_HAS_CXX_STRUCTORS";
45470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
45480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "            instanceStart " << cro.instanceStart << "\n";
45490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "             instanceSize " << cro.instanceSize << "\n";
45500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "               ivarLayout " << format("0x%" PRIx32, cro.ivarLayout)
45510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
45520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map32(cro.ivarLayout, info);
45530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                     name " << format("0x%" PRIx32, cro.name);
45550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_pointer_32(cro.name, xoffset, left, xS, info);
45560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
45570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format(" %.*s", left, name);
45580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
45590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "              baseMethods "
45610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%" PRIx32, cro.baseMethods)
45620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << " (struct method_list_t *)\n";
45630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseMethods != 0)
45640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list32_t(cro.baseMethods, info, "");
45650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "            baseProtocols "
45670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%" PRIx32, cro.baseProtocols) << "\n";
45680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseProtocols != 0)
45690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_protocol_list32_t(cro.baseProtocols, info);
45700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "                    ivars " << format("0x%" PRIx32, cro.ivars)
45710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
45720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.ivars != 0)
45730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_ivar_list32_t(cro.ivars, info);
45740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           weakIvarLayout "
45750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%" PRIx32, cro.weakIvarLayout) << "\n";
45760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  print_layout_map32(cro.weakIvarLayout, info);
45770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           baseProperties "
45780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%" PRIx32, cro.baseProperties) << "\n";
45790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (cro.baseProperties != 0)
45800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_objc_property_list32(cro.baseProperties, info);
4581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  is_meta_class = (cro.flags & RO_META) != 0;
4582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
45830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
45840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_class64_t(uint64_t p, struct DisassembleInfo *info) {
45860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct class64_t c;
45870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
45880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
45890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
45900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
45910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t isa_n_value, n_value;
45920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
45930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
45940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr || left < sizeof(struct class64_t))
45950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
45960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&c, '\0', sizeof(struct class64_t));
45970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct class64_t)) {
45980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, left);
45990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (class_t entends past the end of the section)\n";
46000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
46010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, sizeof(struct class64_t));
46020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
46030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(c);
46040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           isa " << format("0x%" PRIx64, c.isa);
46060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_64(offset + offsetof(struct class64_t, isa), S, info,
46070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       isa_n_value, c.isa);
46080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    superclass " << format("0x%" PRIx64, c.superclass);
46130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_64(offset + offsetof(struct class64_t, superclass), S, info,
46140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       n_value, c.superclass);
46150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "         cache " << format("0x%" PRIx64, c.cache);
46200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_64(offset + offsetof(struct class64_t, cache), S, info,
46210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       n_value, c.cache);
46220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "        vtable " << format("0x%" PRIx64, c.vtable);
46270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_64(offset + offsetof(struct class64_t, vtable), S, info,
46280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       n_value, c.vtable);
46290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_64(offset + offsetof(struct class64_t, data), S, info,
46340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       n_value, c.data);
46350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "          data ";
46360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
46370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && name != nullptr)
46380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << name;
46390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
46400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
46410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.data != 0)
46420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.data);
46430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
46440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.data);
46450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << " (struct class_ro_t *)";
46460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // This is a Swift class if some of the low bits of the pointer are set.
46480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if ((c.data + n_value) & 0x7)
46490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " Swift class";
46500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  bool is_meta_class;
4652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class))
4653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return;
46540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!is_meta_class &&
4656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      c.isa + isa_n_value != p &&
4657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      c.isa + isa_n_value != 0 &&
4658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      info->depth < 100) {
4659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      info->depth++;
4660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << "Meta Class\n";
4661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      print_class64_t(c.isa + isa_n_value, info);
46620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
46630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
46640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_class32_t(uint32_t p, struct DisassembleInfo *info) {
46660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct class32_t c;
46670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
46680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
46690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
46700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
46710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
46730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
46740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
46750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&c, '\0', sizeof(struct class32_t));
46760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct class32_t)) {
46770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, left);
46780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (class_t entends past the end of the section)\n";
46790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
46800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, sizeof(struct class32_t));
46810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
46820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(c);
46830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "           isa " << format("0x%" PRIx32, c.isa);
46850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name =
46860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa);
46870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    superclass " << format("0x%" PRIx32, c.superclass);
46920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info,
46930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       c.superclass);
46940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
46950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
46960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
46970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
46980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "         cache " << format("0x%" PRIx32, c.cache);
46990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info,
47000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       c.cache);
47010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
47020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
47030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "        vtable " << format("0x%" PRIx32, c.vtable);
47060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info,
47070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       c.vtable);
47080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
47090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
47100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name =
47130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data);
47140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "          data " << format("0x%" PRIx32, c.data)
47150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << " (struct class_ro_t *)";
47160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // This is a Swift class if some of the low bits of the pointer are set.
47180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.data & 0x3)
47190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " Swift class";
47200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  bool is_meta_class;
4722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!print_class_ro32_t(c.data & ~0x3, info, is_meta_class))
4723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return;
47240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!is_meta_class) {
47260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "Meta Class\n";
47270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_class32_t(c.isa, info);
47280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
47290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
47300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_objc_class_t(struct objc_class_t *objc_class,
47320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                               struct DisassembleInfo *info) {
47330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left, xleft;
47340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *p, *ivar_list;
47350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
47360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  int32_t i;
47370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_ivar_list_t objc_ivar_list;
47380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_ivar_t ivar;
47390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t      isa " << format("0x%08" PRIx32, objc_class->isa);
47410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose && CLS_GETINFO(objc_class, CLS_META)) {
47420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(objc_class->isa, offset, left, S, info, true);
47430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
47440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
47450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
47460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
47470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
47480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t      super_class "
47510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_class->super_class);
47520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
47530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(objc_class->super_class, offset, left, S, info, true);
47540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
47550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
47560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
47570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
47580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
47590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t     name " << format("0x%08" PRIx32, objc_class->name);
47620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
47630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(objc_class->name, offset, left, S, info, true);
47640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
47650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
47660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
47670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
47680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
47690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t  version " << format("0x%08" PRIx32, objc_class->version)
47720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
47730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t     info " << format("0x%08" PRIx32, objc_class->info);
47750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
47760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (CLS_GETINFO(objc_class, CLS_CLASS))
47770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " CLS_CLASS";
47780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else if (CLS_GETINFO(objc_class, CLS_META))
47790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " CLS_META";
47800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
47810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
47820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t    instance_size "
47840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_class->instance_size) << "\n";
47850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
47860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p = get_pointer_32(objc_class->ivars, offset, left, S, info, true);
47870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t    ivars " << format("0x%08" PRIx32, objc_class->ivars);
47880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (p != nullptr) {
47890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left > sizeof(struct objc_ivar_list_t)) {
47900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\n";
47910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&objc_ivar_list, p, sizeof(struct objc_ivar_list_t));
47920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else {
47930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (entends past the end of the section)\n";
47940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memset(&objc_ivar_list, '\0', sizeof(struct objc_ivar_list_t));
47950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&objc_ivar_list, p, left);
47960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
47970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
47980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(objc_ivar_list);
47990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\t\t       ivar_count " << objc_ivar_list.ivar_count << "\n";
48000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    ivar_list = p + sizeof(struct objc_ivar_list_t);
48010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    for (i = 0; i < objc_ivar_list.ivar_count; i++) {
48020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if ((i + 1) * sizeof(struct objc_ivar_t) > left) {
48030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "\t\t remaining ivar's extend past the of the section\n";
48040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        break;
48050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
48060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&ivar, ivar_list + i * sizeof(struct objc_ivar_t),
48070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             sizeof(struct objc_ivar_t));
48080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
48090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        swapStruct(ivar);
48100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t\t\tivar_name " << format("0x%08" PRIx32, ivar.ivar_name);
48120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose) {
48130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        name = get_pointer_32(ivar.ivar_name, offset, xleft, S, info, true);
48140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (name != nullptr)
48150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << format(" %.*s", xleft, name);
48160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        else
48170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << " (not in an __OBJC section)";
48180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
48190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\n";
48200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t\t\tivar_type " << format("0x%08" PRIx32, ivar.ivar_type);
48220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose) {
48230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        name = get_pointer_32(ivar.ivar_type, offset, xleft, S, info, true);
48240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (name != nullptr)
48250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << format(" %.*s", xleft, name);
48260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        else
48270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << " (not in an __OBJC section)";
48280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
48290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\n";
48300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\t\t      ivar_offset "
48320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << format("0x%08" PRIx32, ivar.ivar_offset) << "\n";
48330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
48340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
48350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
48360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
48370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t  methods " << format("0x%08" PRIx32, objc_class->methodLists);
48390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_method_list(objc_class->methodLists, info))
48400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
48410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t    cache " << format("0x%08" PRIx32, objc_class->cache)
48430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
48440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\tprotocols " << format("0x%08" PRIx32, objc_class->protocols);
48460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_protocol_list(objc_class->protocols, 16, info))
48470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
48480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
48490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_objc_objc_category_t(struct objc_category_t *objc_category,
48510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
48520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
48530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
48540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S;
48550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t       category name "
48570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_category->category_name);
48580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
48590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(objc_category->category_name, offset, left, S, info,
48600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                          true);
48610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
48620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
48630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
48640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
48650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
48660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
48670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t\t  class name "
48690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_category->class_name);
48700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->verbose) {
48710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name =
48720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        get_pointer_32(objc_category->class_name, offset, left, S, info, true);
48730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
48740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
48750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
48760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
48770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
48780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
48790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t    instance methods "
48810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_category->instance_methods);
48820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_method_list(objc_category->instance_methods, info))
48830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
48840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\t       class methods "
48860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << format("0x%08" PRIx32, objc_category->class_methods);
48870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (print_method_list(objc_category->class_methods, info))
48880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (not in an __OBJC section)\n";
48890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
48900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_category64_t(uint64_t p, struct DisassembleInfo *info) {
48920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct category64_t c;
48930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
48940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, xoffset, left;
48950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
48960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
48970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t n_value;
48980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
48990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
49000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
49010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
49020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&c, '\0', sizeof(struct category64_t));
49030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct category64_t)) {
49040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, left);
49050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (category_t entends past the end of the section)\n";
49060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, sizeof(struct category64_t));
49080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
49090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(c);
49100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "              name ";
49120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct category64_t, name), S,
49130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           info, n_value, c.name);
49140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
49170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
49180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
49190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.name != 0)
49200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.name);
49210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.name);
49230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_pointer_64(c.name + n_value, xoffset, left, xS, info);
49240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (name != nullptr)
49250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format(" %.*s", left, name);
49260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
49270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "               cls ";
49290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct category64_t, cls), S, info,
49300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           n_value, c.cls);
49310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
49340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
49350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
49360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.cls != 0)
49370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.cls);
49380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.cls);
49400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
49410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.cls + n_value != 0)
49420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_class64_t(c.cls + n_value, info);
49430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "   instanceMethods ";
49450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name =
49460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_64(offset + offsetof(struct category64_t, instanceMethods), S,
49470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                    info, n_value, c.instanceMethods);
49480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
49510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
49520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
49530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.instanceMethods != 0)
49540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.instanceMethods);
49550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.instanceMethods);
49570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
49580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.instanceMethods + n_value != 0)
49590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list64_t(c.instanceMethods + n_value, info, "");
49600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "      classMethods ";
49620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct category64_t, classMethods),
49630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           S, info, n_value, c.classMethods);
49640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
49670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
49680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
49690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.classMethods != 0)
49700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.classMethods);
49710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.classMethods);
49730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
49740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.classMethods + n_value != 0)
49750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list64_t(c.classMethods + n_value, info, "");
49760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "         protocols ";
49780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name = get_symbol_64(offset + offsetof(struct category64_t, protocols), S,
49790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                           info, n_value, c.protocols);
49800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
49830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
49840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
49850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.protocols != 0)
49860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.protocols);
49870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
49880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.protocols);
49890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
49900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.protocols + n_value != 0)
49910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_protocol_list64_t(c.protocols + n_value, info);
49920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
49930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "instanceProperties ";
49940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sym_name =
49950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      get_symbol_64(offset + offsetof(struct category64_t, instanceProperties),
49960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                    S, info, n_value, c.instanceProperties);
49970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (n_value != 0) {
49980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->verbose && sym_name != nullptr)
49990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << sym_name;
50000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
50010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value);
50020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (c.instanceProperties != 0)
50030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " + " << format("0x%" PRIx64, c.instanceProperties);
50040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
50050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << format("0x%" PRIx64, c.instanceProperties);
50060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
50070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.instanceProperties + n_value != 0)
50080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_objc_property_list64(c.instanceProperties + n_value, info);
50090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
50100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_category32_t(uint32_t p, struct DisassembleInfo *info) {
50120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct category32_t c;
50130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
50140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t offset, left;
50150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
50160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name;
50170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
50190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
50200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
50210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&c, '\0', sizeof(struct category32_t));
50220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct category32_t)) {
50230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, left);
50240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (category_t entends past the end of the section)\n";
50250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
50260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&c, r, sizeof(struct category32_t));
50270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
50280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(c);
50290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "              name " << format("0x%" PRIx32, c.name);
50310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info,
50320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                       c.name);
5033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (name)
50340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " " << name;
50350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
50360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "               cls " << format("0x%" PRIx32, c.cls) << "\n";
50380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.cls != 0)
50390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_class32_t(c.cls, info);
50400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "   instanceMethods " << format("0x%" PRIx32, c.instanceMethods)
50410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
50420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.instanceMethods != 0)
50430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list32_t(c.instanceMethods, info, "");
50440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "      classMethods " << format("0x%" PRIx32, c.classMethods)
50450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
50460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.classMethods != 0)
50470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_method_list32_t(c.classMethods, info, "");
50480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "         protocols " << format("0x%" PRIx32, c.protocols) << "\n";
50490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.protocols != 0)
50500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_protocol_list32_t(c.protocols, info);
50510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties)
50520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar         << "\n";
50530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (c.instanceProperties != 0)
50540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_objc_property_list32(c.instanceProperties, info);
50550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
50560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_message_refs64(SectionRef S, struct DisassembleInfo *info) {
50580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t i, left, offset, xoffset;
50590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t p, n_value;
50600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct message_ref64 mr;
50610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *sym_name;
50620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
50630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef xS;
50640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (S == SectionRef())
50660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
50670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
50690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
50700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
50710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
50720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
50730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset = 0;
50740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
50750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p = S.getAddress() + i;
50760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_64(p, offset, left, S, info);
50770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
50780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
50790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&mr, '\0', sizeof(struct message_ref64));
50800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct message_ref64)) {
50810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&mr, r, left);
50820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (message_ref entends past the end of the section)\n";
50830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
50840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&mr, r, sizeof(struct message_ref64));
50850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
50860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(mr);
50870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
50880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "  imp ";
50890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_symbol_64(offset + offsetof(struct message_ref64, imp), S, info,
50900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                         n_value, mr.imp);
50910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
50920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, n_value) << " ";
50930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (mr.imp != 0)
50940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "+ " << format("0x%" PRIx64, mr.imp) << " ";
50950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
50960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, mr.imp) << " ";
50970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
50980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
50990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
51000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "  sel ";
51020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    sym_name = get_symbol_64(offset + offsetof(struct message_ref64, sel), S,
51030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                             info, n_value, mr.sel);
51040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (n_value != 0) {
51050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (info->verbose && sym_name != nullptr)
51060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << sym_name;
51070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      else
51080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << format("0x%" PRIx64, n_value);
51090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (mr.sel != 0)
51100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << " + " << format("0x%" PRIx64, mr.sel);
51110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
51120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%" PRIx64, mr.sel);
51130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_64(mr.sel + n_value, xoffset, left, xS, info);
51140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
51150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format(" %.*s", left, name);
51160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
51170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct message_ref64);
51190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
51200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
51210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_message_refs32(SectionRef S, struct DisassembleInfo *info) {
51230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t i, left, offset, xoffset, p;
51240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct message_ref32 mr;
51250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *name, *r;
51260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef xS;
51270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (S == SectionRef())
51290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
51300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
51320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
51330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
51340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
51350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
51360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  offset = 0;
51370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) {
51380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p = S.getAddress() + i;
51390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, info);
51400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
51410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return;
51420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&mr, '\0', sizeof(struct message_ref32));
51430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct message_ref32)) {
51440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&mr, r, left);
51450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (message_ref entends past the end of the section)\n";
51460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
51470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&mr, r, sizeof(struct message_ref32));
51480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
51490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(mr);
51500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "  imp " << format("0x%" PRIx32, mr.imp);
51520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info,
51530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                         mr.imp);
51540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
51550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
51560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
51570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "  sel " << format("0x%" PRIx32, mr.sel);
51590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(mr.sel, xoffset, left, xS, info);
51600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
51610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " " << name;
51620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
51630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    offset += sizeof(struct message_ref32);
51650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
51660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
51670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
51680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_image_info64(SectionRef S, struct DisassembleInfo *info) {
51690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t left, offset, swift_version;
51700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint64_t p;
51710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_image_info64 o;
51720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
51730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
5174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (S == SectionRef())
5175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return;
5176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
51770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
51780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
51790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
51800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
51810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
51820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p = S.getAddress();
51830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_64(p, offset, left, S, info);
51840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
51850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
51860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&o, '\0', sizeof(struct objc_image_info64));
51870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct objc_image_info64)) {
51880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, left);
51890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (objc_image_info entends past the end of the section)\n";
51900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
51910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, sizeof(struct objc_image_info64));
51920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
51930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(o);
51940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "  version " << o.version << "\n";
51950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    flags " << format("0x%" PRIx32, o.flags);
51960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
51970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " OBJC_IMAGE_IS_REPLACEMENT";
51980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
51990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " OBJC_IMAGE_SUPPORTS_GC";
52000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  swift_version = (o.flags >> 8) & 0xff;
52010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (swift_version != 0) {
52020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (swift_version == 1)
52030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " Swift 1.0";
52040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else if (swift_version == 2)
52050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " Swift 1.1";
52060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
52070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " unknown future Swift version (" << swift_version << ")";
52080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
52090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
52100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
52110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
52120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_image_info32(SectionRef S, struct DisassembleInfo *info) {
52130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t left, offset, swift_version, p;
52140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_image_info32 o;
52150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
52160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
5217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (S == SectionRef())
5218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
52200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
52210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
52220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
52230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
52240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
52250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p = S.getAddress();
52260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
52270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
52280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
52290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&o, '\0', sizeof(struct objc_image_info32));
52300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct objc_image_info32)) {
52310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, left);
52320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "   (objc_image_info entends past the end of the section)\n";
52330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
52340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, sizeof(struct objc_image_info32));
52350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
52360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(o);
52370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "  version " << o.version << "\n";
52380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    flags " << format("0x%" PRIx32, o.flags);
52390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & OBJC_IMAGE_IS_REPLACEMENT)
52400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " OBJC_IMAGE_IS_REPLACEMENT";
52410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & OBJC_IMAGE_SUPPORTS_GC)
52420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " OBJC_IMAGE_SUPPORTS_GC";
52430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  swift_version = (o.flags >> 8) & 0xff;
52440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (swift_version != 0) {
52450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (swift_version == 1)
52460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " Swift 1.0";
52470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else if (swift_version == 2)
52480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " Swift 1.1";
52490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
52500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " unknown future Swift version (" << swift_version << ")";
52510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
52520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
52530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
52540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
52550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void print_image_info(SectionRef S, struct DisassembleInfo *info) {
52560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t left, offset, p;
52570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct imageInfo_t o;
52580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r;
52590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
52600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SectName;
52610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S.getName(SectName);
52620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  DataRefImpl Ref = S.getRawDataRefImpl();
52630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  StringRef SegName = info->O->getSectionFinalSegmentName(Ref);
52640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Contents of (" << SegName << "," << SectName << ") section\n";
52650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  p = S.getAddress();
52660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  r = get_pointer_32(p, offset, left, S, info);
52670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (r == nullptr)
52680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return;
52690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  memset(&o, '\0', sizeof(struct imageInfo_t));
52700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (left < sizeof(struct imageInfo_t)) {
52710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, left);
52720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " (imageInfo entends past the end of the section)\n";
52730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else
52740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memcpy(&o, r, sizeof(struct imageInfo_t));
52750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
52760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    swapStruct(o);
52770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "  version " << o.version << "\n";
52780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "    flags " << format("0x%" PRIx32, o.flags);
52790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & 0x1)
52800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "  F&C";
52810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & 0x2)
52820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " GC";
52830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (o.flags & 0x4)
52840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " GC-only";
52850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  else
52860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << " RR";
52870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "\n";
52880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
52890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
52900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
52910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SymbolAddressMap AddrMap;
52920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (verbose)
52930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    CreateSymbolAddressMap(O, &AddrMap);
52940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
52950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  std::vector<SectionRef> Sections;
52960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
52970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SectName;
52980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Section.getName(SectName);
52990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Sections.push_back(Section);
53000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
53010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct DisassembleInfo info;
53030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // Set up the block of info used by the Symbolizer call backs.
53040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.verbose = verbose;
53050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.O = O;
53060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.AddrMap = &AddrMap;
53070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.Sections = &Sections;
53080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.class_name = nullptr;
53090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.selector_name = nullptr;
53100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.method = nullptr;
53110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.demangled_name = nullptr;
53120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.bindtable = nullptr;
53130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_addr = 0;
53140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_inst = 0;
53150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
5316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.depth = 0;
5317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef CL = get_section(O, "__OBJC2", "__class_list");
5318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (CL == SectionRef())
5319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CL = get_section(O, "__DATA", "__objc_classlist");
5320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = CL;
5321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  walk_pointer_list_64("class", CL, O, &info, print_class64_t);
5322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
5324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (CR == SectionRef())
5325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CR = get_section(O, "__DATA", "__objc_classrefs");
5326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = CR;
5327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  walk_pointer_list_64("class refs", CR, O, &info, nullptr);
5328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
5330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (SR == SectionRef())
5331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SR = get_section(O, "__DATA", "__objc_superrefs");
5332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = SR;
5333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  walk_pointer_list_64("super refs", SR, O, &info, nullptr);
5334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef CA = get_section(O, "__OBJC2", "__category_list");
5336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (CA == SectionRef())
5337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CA = get_section(O, "__DATA", "__objc_catlist");
5338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = CA;
5339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  walk_pointer_list_64("category", CA, O, &info, print_category64_t);
5340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
5342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (PL == SectionRef())
5343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PL = get_section(O, "__DATA", "__objc_protolist");
5344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = PL;
5345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  walk_pointer_list_64("protocol", PL, O, &info, nullptr);
5346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
5348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (MR == SectionRef())
5349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MR = get_section(O, "__DATA", "__objc_msgrefs");
5350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = MR;
5351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  print_message_refs64(MR, &info);
5352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SectionRef II = get_section(O, "__OBJC2", "__image_info");
5354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (II == SectionRef())
5355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    II = get_section(O, "__DATA", "__objc_imageinfo");
5356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  info.S = II;
5357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  print_image_info64(II, &info);
53580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (info.bindtable != nullptr)
53600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    delete info.bindtable;
53610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
53620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
53640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SymbolAddressMap AddrMap;
53650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (verbose)
53660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    CreateSymbolAddressMap(O, &AddrMap);
53670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  std::vector<SectionRef> Sections;
53690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
53700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SectName;
53710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Section.getName(SectName);
53720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Sections.push_back(Section);
53730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
53740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct DisassembleInfo info;
53760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // Set up the block of info used by the Symbolizer call backs.
53770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.verbose = verbose;
53780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.O = O;
53790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.AddrMap = &AddrMap;
53800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.Sections = &Sections;
53810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.class_name = nullptr;
53820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.selector_name = nullptr;
53830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.method = nullptr;
53840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.demangled_name = nullptr;
53850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.bindtable = nullptr;
53860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_addr = 0;
53870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_inst = 0;
53880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef CL = get_section(O, "__OBJC2", "__class_list");
53900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (CL != SectionRef()) {
53910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CL;
53920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("class", CL, O, &info, print_class32_t);
53930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
53940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef CL = get_section(O, "__DATA", "__objc_classlist");
53950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CL;
53960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("class", CL, O, &info, print_class32_t);
53970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
53980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
53990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
54000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (CR != SectionRef()) {
54010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CR;
54020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("class refs", CR, O, &info, nullptr);
54030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef CR = get_section(O, "__DATA", "__objc_classrefs");
54050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CR;
54060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("class refs", CR, O, &info, nullptr);
54070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
54100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (SR != SectionRef()) {
54110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = SR;
54120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("super refs", SR, O, &info, nullptr);
54130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef SR = get_section(O, "__DATA", "__objc_superrefs");
54150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = SR;
54160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("super refs", SR, O, &info, nullptr);
54170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef CA = get_section(O, "__OBJC2", "__category_list");
54200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (CA != SectionRef()) {
54210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CA;
54220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("category", CA, O, &info, print_category32_t);
54230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef CA = get_section(O, "__DATA", "__objc_catlist");
54250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = CA;
54260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("category", CA, O, &info, print_category32_t);
54270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
54300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (PL != SectionRef()) {
54310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = PL;
54320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("protocol", PL, O, &info, nullptr);
54330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef PL = get_section(O, "__DATA", "__objc_protolist");
54350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = PL;
54360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    walk_pointer_list_32("protocol", PL, O, &info, nullptr);
54370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
54400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (MR != SectionRef()) {
54410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = MR;
54420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_message_refs32(MR, &info);
54430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef MR = get_section(O, "__DATA", "__objc_msgrefs");
54450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = MR;
54460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_message_refs32(MR, &info);
54470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef II = get_section(O, "__OBJC2", "__image_info");
54500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (II != SectionRef()) {
54510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = II;
54520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_image_info32(II, &info);
54530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  } else {
54540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    const SectionRef II = get_section(O, "__DATA", "__objc_imageinfo");
54550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    info.S = II;
54560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_image_info32(II, &info);
54570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
54590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {
54610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t i, j, p, offset, xoffset, left, defs_left, def;
54620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *r, *name, *defs;
54630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_module_t module;
54640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SectionRef S, xS;
54650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_symtab_t symtab;
54660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_class_t objc_class;
54670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_category_t objc_category;
54680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  outs() << "Objective-C segment\n";
54700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  S = get_section(O, "__OBJC", "__module_info");
54710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (S == SectionRef())
54720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return false;
54730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SymbolAddressMap AddrMap;
54750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (verbose)
54760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    CreateSymbolAddressMap(O, &AddrMap);
54770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  std::vector<SectionRef> Sections;
54790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
54800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SectName;
54810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Section.getName(SectName);
54820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Sections.push_back(Section);
54830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
54840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct DisassembleInfo info;
54860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // Set up the block of info used by the Symbolizer call backs.
54870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.verbose = verbose;
54880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.O = O;
54890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.AddrMap = &AddrMap;
54900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.Sections = &Sections;
54910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.class_name = nullptr;
54920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.selector_name = nullptr;
54930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.method = nullptr;
54940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.demangled_name = nullptr;
54950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.bindtable = nullptr;
54960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_addr = 0;
54970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_inst = 0;
54980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
54990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (i = 0; i < S.getSize(); i += sizeof(struct objc_module_t)) {
55000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    p = S.getAddress() + i;
55010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(p, offset, left, S, &info, true);
55020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
55030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      return true;
55040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&module, '\0', sizeof(struct objc_module_t));
55050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct objc_module_t)) {
55060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&module, r, left);
55070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "   (module extends past end of __module_info section)\n";
55080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
55090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&module, r, sizeof(struct objc_module_t));
55100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (O->isLittleEndian() != sys::IsLittleEndianHost)
55110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(module);
55120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
55130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "Module " << format("0x%" PRIx32, p) << "\n";
55140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "    version " << module.version << "\n";
55150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "       size " << module.size << "\n";
55160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "       name ";
55170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    name = get_pointer_32(module.name, xoffset, left, xS, &info, true);
55180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (name != nullptr)
55190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("%.*s", left, name);
55200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else
55210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << format("0x%08" PRIx32, module.name)
55220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << "(not in an __OBJC section)";
55230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
55240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
55250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(module.symtab, xoffset, left, xS, &info, true);
55260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (module.symtab == 0 || r == nullptr) {
55270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "     symtab " << format("0x%08" PRIx32, module.symtab)
55280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << " (not in an __OBJC section)\n";
55290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      continue;
55300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
55310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "     symtab " << format("0x%08" PRIx32, module.symtab) << "\n";
55320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&symtab, '\0', sizeof(struct objc_symtab_t));
55330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    defs_left = 0;
55340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    defs = nullptr;
55350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct objc_symtab_t)) {
55360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&symtab, r, left);
55370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\tsymtab extends past end of an __OBJC section)\n";
55380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else {
55390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&symtab, r, sizeof(struct objc_symtab_t));
55400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (left > sizeof(struct objc_symtab_t)) {
55410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        defs_left = left - sizeof(struct objc_symtab_t);
55420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        defs = r + sizeof(struct objc_symtab_t);
55430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
55440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
55450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (O->isLittleEndian() != sys::IsLittleEndianHost)
55460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(symtab);
55470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
55480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\tsel_ref_cnt " << symtab.sel_ref_cnt << "\n";
55490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    r = get_pointer_32(symtab.refs, xoffset, left, xS, &info, true);
55500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\trefs " << format("0x%08" PRIx32, symtab.refs);
55510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (r == nullptr)
55520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << " (not in an __OBJC section)";
55530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\n";
55540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\tcls_def_cnt " << symtab.cls_def_cnt << "\n";
55550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "\tcat_def_cnt " << symtab.cat_def_cnt << "\n";
55560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (symtab.cls_def_cnt > 0)
55570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\tClass Definitions\n";
55580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    for (j = 0; j < symtab.cls_def_cnt; j++) {
55590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if ((j + 1) * sizeof(uint32_t) > defs_left) {
55600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "\t(remaining class defs entries entends past the end of the "
55610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar               << "section)\n";
55620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        break;
55630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
55640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&def, defs + j * sizeof(uint32_t), sizeof(uint32_t));
55650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (O->isLittleEndian() != sys::IsLittleEndianHost)
55660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        sys::swapByteOrder(def);
55670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
55680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      r = get_pointer_32(def, xoffset, left, xS, &info, true);
55690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\tdefs[" << j << "] " << format("0x%08" PRIx32, def);
55700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (r != nullptr) {
55710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (left > sizeof(struct objc_class_t)) {
55720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << "\n";
55730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memcpy(&objc_class, r, sizeof(struct objc_class_t));
55740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        } else {
55750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << " (entends past the end of the section)\n";
55760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memset(&objc_class, '\0', sizeof(struct objc_class_t));
55770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memcpy(&objc_class, r, left);
55780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        }
55790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (O->isLittleEndian() != sys::IsLittleEndianHost)
55800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          swapStruct(objc_class);
55810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        print_objc_class_t(&objc_class, &info);
55820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      } else {
55830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "(not in an __OBJC section)\n";
55840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
55850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
55860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (CLS_GETINFO(&objc_class, CLS_CLASS)) {
55870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "\tMeta Class";
55880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        r = get_pointer_32(objc_class.isa, xoffset, left, xS, &info, true);
55890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (r != nullptr) {
55900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          if (left > sizeof(struct objc_class_t)) {
55910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            outs() << "\n";
55920c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            memcpy(&objc_class, r, sizeof(struct objc_class_t));
55930c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          } else {
55940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            outs() << " (entends past the end of the section)\n";
55950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            memset(&objc_class, '\0', sizeof(struct objc_class_t));
55960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            memcpy(&objc_class, r, left);
55970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          }
55980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          if (O->isLittleEndian() != sys::IsLittleEndianHost)
55990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            swapStruct(objc_class);
56000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          print_objc_class_t(&objc_class, &info);
56010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        } else {
56020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << "(not in an __OBJC section)\n";
56030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        }
56040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
56050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
56060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (symtab.cat_def_cnt > 0)
56070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\tCategory Definitions\n";
56080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    for (j = 0; j < symtab.cat_def_cnt; j++) {
56090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if ((j + symtab.cls_def_cnt + 1) * sizeof(uint32_t) > defs_left) {
56100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "\t(remaining category defs entries entends past the end of "
56110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar               << "the section)\n";
56120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        break;
56130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
56140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&def, defs + (j + symtab.cls_def_cnt) * sizeof(uint32_t),
56150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             sizeof(uint32_t));
56160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (O->isLittleEndian() != sys::IsLittleEndianHost)
56170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        sys::swapByteOrder(def);
56180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      r = get_pointer_32(def, xoffset, left, xS, &info, true);
56200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "\tdefs[" << j + symtab.cls_def_cnt << "] "
56210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             << format("0x%08" PRIx32, def);
56220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (r != nullptr) {
56230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (left > sizeof(struct objc_category_t)) {
56240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << "\n";
56250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memcpy(&objc_category, r, sizeof(struct objc_category_t));
56260c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        } else {
56270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          outs() << " (entends past the end of the section)\n";
56280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memset(&objc_category, '\0', sizeof(struct objc_category_t));
56290c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          memcpy(&objc_category, r, left);
56300c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        }
56310c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (O->isLittleEndian() != sys::IsLittleEndianHost)
56320c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          swapStruct(objc_category);
56330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        print_objc_objc_category_t(&objc_category, &info);
56340c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      } else {
56350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        outs() << "(not in an __OBJC section)\n";
56360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      }
56370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
56380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
56390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const SectionRef II = get_section(O, "__OBJC", "__image_info");
56400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (II != SectionRef())
56410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    print_image_info(II, &info);
56420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56430c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return true;
56440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
56450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void DumpProtocolSection(MachOObjectFile *O, const char *sect,
56470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                uint32_t size, uint32_t addr) {
56480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SymbolAddressMap AddrMap;
56490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  CreateSymbolAddressMap(O, &AddrMap);
56500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  std::vector<SectionRef> Sections;
56520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (const SectionRef &Section : O->sections()) {
56530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    StringRef SectName;
56540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Section.getName(SectName);
56550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Sections.push_back(Section);
56560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
56570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct DisassembleInfo info;
56590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // Set up the block of info used by the Symbolizer call backs.
56600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.verbose = true;
56610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.O = O;
56620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.AddrMap = &AddrMap;
56630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.Sections = &Sections;
56640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.class_name = nullptr;
56650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.selector_name = nullptr;
56660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.method = nullptr;
56670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.demangled_name = nullptr;
56680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.bindtable = nullptr;
56690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_addr = 0;
56700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  info.adrp_inst = 0;
56710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
56720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  const char *p;
56730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  struct objc_protocol_t protocol;
56740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  uint32_t left, paddr;
56750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) {
56760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    memset(&protocol, '\0', sizeof(struct objc_protocol_t));
56770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    left = size - (p - sect);
56780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (left < sizeof(struct objc_protocol_t)) {
56790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "Protocol extends past end of __protocol section\n";
56800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&protocol, p, left);
56810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    } else
56820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      memcpy(&protocol, p, sizeof(struct objc_protocol_t));
56830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (O->isLittleEndian() != sys::IsLittleEndianHost)
56840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      swapStruct(protocol);
56850c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    paddr = addr + (p - sect);
56860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    outs() << "Protocol " << format("0x%" PRIx32, paddr);
56870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (print_protocol(paddr, 0, &info))
56880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      outs() << "(not in an __OBJC section)\n";
56890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
56900c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
56910c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
5692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef HAVE_LIBXAR
5693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarinline void swapStruct(struct xar_header &xar) {
5694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.magic);
5695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.size);
5696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.version);
5697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.toc_length_compressed);
5698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.toc_length_uncompressed);
5699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::swapByteOrder(xar.cksum_alg);
5700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
5701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void PrintModeVerbose(uint32_t mode) {
5703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  switch(mode & S_IFMT){
5704de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFDIR:
5705de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "d";
5706de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5707de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFCHR:
5708de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "c";
5709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5710de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFBLK:
5711de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "b";
5712de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5713de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFREG:
5714de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5715de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5716de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFLNK:
5717de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "l";
5718de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5719de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case S_IFSOCK:
5720de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "s";
5721de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  default:
5723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "?";
5724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
5725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /* owner permissions */
5728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & S_IREAD)
5729de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "r";
5730de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & S_IWRITE)
5733de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "w";
5734de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5735de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5736de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & S_ISUID)
5737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "s";
5738de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else if(mode & S_IEXEC)
5739de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "x";
5740de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5741de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5742de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5743de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /* group permissions */
5744de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & (S_IREAD >> 3))
5745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "r";
5746de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5747de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5748de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & (S_IWRITE >> 3))
5749de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "w";
5750de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5751de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5752de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & S_ISGID)
5753de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "s";
5754de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else if(mode & (S_IEXEC >> 3))
5755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "x";
5756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5758de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5759de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  /* other permissions */
5760de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & (S_IREAD >> 6))
5761de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "r";
5762de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5763de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5764de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & (S_IWRITE >> 6))
5765de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "w";
5766de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5767de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5768de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(mode & S_ISVTX)
5769de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "t";
5770de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else if(mode & (S_IEXEC >> 6))
5771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "x";
5772de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5773de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "-";
5774de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
5775de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5776de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
5777de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_iter_t xi;
5778de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_file_t xf;
5779de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_iter_t xp;
5780de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const char *key, *type, *mode, *user, *group, *size, *mtime, *name, *m;
5781de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  char *endp;
5782de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t mode_value;
5783de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5784de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xi = xar_iter_new();
5785de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!xi) {
5786de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << "Can't obtain an xar iterator for xar archive "
5787de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           << XarFilename << "\n";
5788de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5789de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5790de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5791de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Go through the xar's files.
5792de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for (xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)) {
5793de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    xp = xar_iter_new();
5794de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(!xp){
5795de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      errs() << "Can't obtain an xar iterator for xar archive "
5796de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar             << XarFilename << "\n";
5797de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return;
5798de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5799de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    type = nullptr;
5800de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    mode = nullptr;
5801de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    user = nullptr;
5802de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    group = nullptr;
5803de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    size = nullptr;
5804de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    mtime = nullptr;
5805de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    name = nullptr;
5806de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5807de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const char *val = nullptr;
5808de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      xar_prop_get(xf, key, &val);
5809de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#if 0 // Useful for debugging.
5810de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "key: " << key << " value: " << val << "\n";
5811de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
5812de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "type") == 0)
5813de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        type = val;
5814de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "mode") == 0)
5815de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        mode = val;
5816de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "user") == 0)
5817de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        user = val;
5818de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "group") == 0)
5819de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        group = val;
5820de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "data/size") == 0)
5821de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        size = val;
5822de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "mtime") == 0)
5823de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        mtime = val;
5824de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "name") == 0)
5825de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        name = val;
5826de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5827de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(mode != nullptr){
5828de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      mode_value = strtoul(mode, &endp, 8);
5829de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(*endp != '\0')
5830de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "(mode: \"" << mode << "\" contains non-octal chars) ";
5831de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(type, "file") == 0)
5832de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        mode_value |= S_IFREG;
5833de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      PrintModeVerbose(mode_value);
5834de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << " ";
5835de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5836de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(user != nullptr)
5837de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format("%10s/", user);
5838de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(group != nullptr)
5839de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format("%-10s ", group);
5840de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(size != nullptr)
5841de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format("%7s ", size);
5842de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(mtime != nullptr){
5843de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      for(m = mtime; *m != 'T' && *m != '\0'; m++)
5844de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << *m;
5845de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(*m == 'T')
5846de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        m++;
5847de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << " ";
5848de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      for( ; *m != 'Z' && *m != '\0'; m++)
5849de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << *m;
5850de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << " ";
5851de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5852de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(name != nullptr)
5853de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << name;
5854de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "\n";
5855de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5856de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
5857de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5858de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
5859de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                uint32_t size, bool verbose,
5860de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                bool PrintXarHeader, bool PrintXarFileHeaders,
5861de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                std::string XarMemberName) {
5862de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(size < sizeof(struct xar_header)) {
5863de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "size of (__LLVM,__bundle) section too small (smaller than size "
5864de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              "of struct xar_header)\n";
5865de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5866de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5867de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  struct xar_header XarHeader;
5868de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  memcpy(&XarHeader, sect, sizeof(struct xar_header));
5869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (sys::IsLittleEndianHost)
5870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    swapStruct(XarHeader);
5871de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (PrintXarHeader) {
5872de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!XarMemberName.empty())
5873de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "In xar member " << XarMemberName << ": ";
5874de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else
5875de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "For (__LLVM,__bundle) section: ";
5876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "xar header\n";
5877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (XarHeader.magic == XAR_HEADER_MAGIC)
5878de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "                  magic XAR_HEADER_MAGIC\n";
5879de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else
5880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "                  magic "
5881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar             << format_hex(XarHeader.magic, 10, true)
5882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar             << " (not XAR_HEADER_MAGIC)\n";
5883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "                   size " << XarHeader.size << "\n";
5884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "                version " << XarHeader.version << "\n";
5885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "  toc_length_compressed " << XarHeader.toc_length_compressed
5886de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           << "\n";
5887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "toc_length_uncompressed " << XarHeader.toc_length_uncompressed
5888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           << "\n";
5889de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "              cksum_alg ";
5890de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    switch (XarHeader.cksum_alg) {
5891de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      case XAR_CKSUM_NONE:
5892de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "XAR_CKSUM_NONE\n";
5893de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        break;
5894de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      case XAR_CKSUM_SHA1:
5895de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "XAR_CKSUM_SHA1\n";
5896de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        break;
5897de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      case XAR_CKSUM_MD5:
5898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "XAR_CKSUM_MD5\n";
5899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        break;
5900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef XAR_CKSUM_SHA256
5901de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      case XAR_CKSUM_SHA256:
5902de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "XAR_CKSUM_SHA256\n";
5903de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        break;
5904de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
5905de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef XAR_CKSUM_SHA512
5906de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      case XAR_CKSUM_SHA512:
5907de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "XAR_CKSUM_SHA512\n";
5908de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        break;
5909de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
5910de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      default:
5911de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << XarHeader.cksum_alg << "\n";
5912de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5913de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5914de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5915de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<128> XarFilename;
5916de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int FD;
5917de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::error_code XarEC =
5918de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      sys::fs::createTemporaryFile("llvm-objdump", "xar", FD, XarFilename);
5919de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (XarEC) {
5920de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << XarEC.message() << "\n";
5921de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5922de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5923de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  tool_output_file XarFile(XarFilename, FD);
5924de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  raw_fd_ostream &XarOut = XarFile.os();
5925de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  StringRef XarContents(sect, size);
5926de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  XarOut << XarContents;
5927de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  XarOut.close();
5928de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (XarOut.has_error())
5929de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5930de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5931de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_t xar = xar_open(XarFilename.c_str(), READ);
5932de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!xar) {
5933de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << "Can't create temporary xar archive " << XarFilename << "\n";
5934de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5935de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5936de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5937de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SmallString<128> TocFilename;
5938de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::error_code TocEC =
5939de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      sys::fs::createTemporaryFile("llvm-objdump", "toc", TocFilename);
5940de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (TocEC) {
5941de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << TocEC.message() << "\n";
5942de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5943de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5944de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_serialize(xar, TocFilename.c_str());
5945de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5946de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (PrintXarFileHeaders) {
5947de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!XarMemberName.empty())
5948de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "In xar member " << XarMemberName << ": ";
5949de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else
5950de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "For (__LLVM,__bundle) section: ";
5951de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "xar archive files:\n";
5952de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    PrintXarFilesSummary(XarFilename.c_str(), xar);
5953de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5954de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5955de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
5956de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MemoryBuffer::getFileOrSTDIN(TocFilename.c_str());
5957de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (std::error_code EC = FileOrErr.getError()) {
5958de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << EC.message() << "\n";
5959de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5960de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5961de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
5962de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5963de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!XarMemberName.empty())
5964de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "In xar member " << XarMemberName << ": ";
5965de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
5966de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "For (__LLVM,__bundle) section: ";
5967de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  outs() << "xar table of contents:\n";
5968de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  outs() << Buffer->getBuffer() << "\n";
5969de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5970de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // TODO: Go through the xar's files.
5971de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_iter_t xi = xar_iter_new();
5972de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if(!xi){
5973de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    errs() << "Can't obtain an xar iterator for xar archive "
5974de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           << XarFilename.c_str() << "\n";
5975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    xar_close(xar);
5976de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
5977de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  for(xar_file_t xf = xar_file_first(xar, xi); xf; xf = xar_file_next(xi)){
5979de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const char *key;
5980de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    xar_iter_t xp;
5981de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const char *member_name, *member_type, *member_size_string;
5982de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    size_t member_size;
5983de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5984de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    xp = xar_iter_new();
5985de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if(!xp){
5986de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      errs() << "Can't obtain an xar iterator for xar archive "
5987de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	     << XarFilename.c_str() << "\n";
5988de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      xar_close(xar);
5989de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return;
5990de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
5991de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    member_name = NULL;
5992de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    member_type = NULL;
5993de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    member_size_string = NULL;
5994de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5995de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const char *val = nullptr;
5996de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      xar_prop_get(xf, key, &val);
5997de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#if 0 // Useful for debugging.
5998de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << "key: " << key << " value: " << val << "\n";
5999de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
6000de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "name") == 0)
6001de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	member_name = val;
6002de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "type") == 0)
6003de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	member_type = val;
6004de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if(strcmp(key, "data/size") == 0)
6005de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	member_size_string = val;
6006de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
6007de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    /*
6008de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar     * If we find a file with a name, date/size and type properties
6009de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar     * and with the type being "file" see if that is a xar file.
6010de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar     */
6011de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (member_name != NULL && member_type != NULL &&
6012de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        strcmp(member_type, "file") == 0 &&
6013de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        member_size_string != NULL){
6014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // Extract the file into a buffer.
6015de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      char *endptr;
6016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      member_size = strtoul(member_size_string, &endptr, 10);
6017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (*endptr == '\0' && member_size != 0) {
6018de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	char *buffer = (char *) ::operator new (member_size);
6019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	if (xar_extract_tobuffersz(xar, xf, &buffer, &member_size) == 0) {
6020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#if 0 // Useful for debugging.
6021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  outs() << "xar member: " << member_name << " extracted\n";
6022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
6023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          // Set the XarMemberName we want to see printed in the header.
6024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  std::string OldXarMemberName;
6025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  // If XarMemberName is already set this is nested. So
6026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  // save the old name and create the nested name.
6027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  if (!XarMemberName.empty()) {
6028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    OldXarMemberName = XarMemberName;
6029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            XarMemberName =
6030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar             (Twine("[") + XarMemberName + "]" + member_name).str();
6031de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  } else {
6032de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    OldXarMemberName = "";
6033de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    XarMemberName = member_name;
6034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  }
6035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  // See if this is could be a xar file (nested).
6036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  if (member_size >= sizeof(struct xar_header)) {
6037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#if 0 // Useful for debugging.
6038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    outs() << "could be a xar file: " << member_name << "\n";
6039de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif
6040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    memcpy((char *)&XarHeader, buffer, sizeof(struct xar_header));
6041de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            if (sys::IsLittleEndianHost)
6042de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	      swapStruct(XarHeader);
6043de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	    if(XarHeader.magic == XAR_HEADER_MAGIC)
6044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	      DumpBitcodeSection(O, buffer, member_size, verbose,
6045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                 PrintXarHeader, PrintXarFileHeaders,
6046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar		                 XarMemberName);
6047de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  }
6048de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	  XarMemberName = OldXarMemberName;
6049de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	}
6050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        delete buffer;
6051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6052de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
6053de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    xar_iter_free(xp);
6054de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  xar_close(xar);
6056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
6057de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif // defined(HAVE_LIBXAR)
6058de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
60590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarstatic void printObjcMetaData(MachOObjectFile *O, bool verbose) {
60600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (O->is64Bit())
60610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    printObjc2_64bit_MetaData(O, verbose);
60620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  else {
60630c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    MachO::mach_header H;
60640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    H = O->getHeader();
60650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (H.cputype == MachO::CPU_TYPE_ARM)
60660c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      printObjc2_32bit_MetaData(O, verbose);
60670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    else {
60680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      // This is the 32-bit non-arm cputype case.  Which is normally
60690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      // the first Objective-C ABI.  But it may be the case of a
60700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      // binary for the iOS simulator which is the second Objective-C
60710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      // ABI.  In that case printObjc1_32bit_MetaData() will determine that
60720c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      // and return false.
6073f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!printObjc1_32bit_MetaData(O, verbose))
60740c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        printObjc2_32bit_MetaData(O, verbose);
60750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    }
60760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
60770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
60780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
607937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// GuessLiteralPointer returns a string which for the item in the Mach-O file
608037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// for the address passed in as ReferenceValue for printing as a comment with
608137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the instruction and also returns the corresponding type of that item
608237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// indirectly through ReferenceType.
608337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
608437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// If ReferenceValue is an address of literal cstring then a pointer to the
608537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// cstring is returned and ReferenceType is set to
608637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr .
608737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
608837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// If ReferenceValue is an address of an Objective-C CFString, Selector ref or
608937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Class ref that name is returned and the ReferenceType is set accordingly.
609037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
609137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Lastly, literals which are Symbol address in a literal pool are looked for
609237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// and if found the symbol name is returned and ReferenceType is set to
609337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr .
609437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
609537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// If there is no item in the Mach-O file for the address passed in as
609637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// ReferenceValue nullptr is returned and ReferenceType is unchanged.
60974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *GuessLiteralPointer(uint64_t ReferenceValue,
60984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                       uint64_t ReferencePC,
60994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                       uint64_t *ReferenceType,
61004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                       struct DisassembleInfo *info) {
610137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // First see if there is an external relocation entry at the ReferencePC.
6102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (info->O->getHeader().filetype == MachO::MH_OBJECT) {
6103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t sect_addr = info->S.getAddress();
6104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t sect_offset = ReferencePC - sect_addr;
6105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool reloc_found = false;
6106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DataRefImpl Rel;
6107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachO::any_relocation_info RE;
6108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isExtern = false;
6109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SymbolRef Symbol;
6110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (const RelocationRef &Reloc : info->S.relocations()) {
6111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t RelocOffset = Reloc.getOffset();
6112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RelocOffset == sect_offset) {
6113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Rel = Reloc.getRawDataRefImpl();
6114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RE = info->O->getRelocation(Rel);
6115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (info->O->isRelocationScattered(RE))
6116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          continue;
6117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        isExtern = info->O->getPlainRelocationExternal(RE);
6118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (isExtern) {
6119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          symbol_iterator RelocSym = Reloc.getSymbol();
6120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Symbol = *RelocSym;
6121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        }
6122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        reloc_found = true;
6123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
612437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
612537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
6126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If there is an external relocation entry for a symbol in a section
6127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // then used that symbol's value for the value of the reference.
6128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (reloc_found && isExtern) {
6129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (info->O->getAnyRelocationPCRel(RE)) {
6130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned Type = info->O->getAnyRelocationType(RE);
6131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (Type == MachO::X86_64_RELOC_SIGNED) {
6132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          ReferenceValue = Symbol.getValue();
6133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        }
613437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
613537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
613637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
613737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
613837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Look for literals such as Objective-C CFStrings refs, Selector refs,
613937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Message refs and Class refs.
614037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool classref, selref, msgref, cfstring;
614137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t pointer_value = GuessPointerPointer(ReferenceValue, info, classref,
614237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                               selref, msgref, cfstring);
61434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (classref && pointer_value == 0) {
614437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Note the ReferenceValue is a pointer into the __objc_classrefs section.
614537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // And the pointer_value in that section is typically zero as it will be
614637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // set by dyld as part of the "bind information".
614737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *name = get_dyld_bind_info_symbolname(ReferenceValue, info);
614837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (name != nullptr) {
614937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
615037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const char *class_name = strrchr(name, '$');
615137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (class_name != nullptr && class_name[1] == '_' &&
615237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          class_name[2] != '\0') {
615337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        info->class_name = class_name + 2;
615437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return name;
615537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
615637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
615737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
615837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (classref) {
616037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref;
616137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *name =
616237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        get_objc2_64bit_class_name(pointer_value, ReferenceValue, info);
616337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (name != nullptr)
616437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->class_name = name;
616537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
616637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      name = "bad class ref";
616737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return name;
616837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
616937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (cfstring) {
617137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref;
617237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *name = get_objc2_64bit_cfstring_name(ReferenceValue, info);
617337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return name;
617437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
617537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (selref && pointer_value == 0)
617737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    pointer_value = get_objc2_64bit_selref(ReferenceValue, info);
617837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
617937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (pointer_value != 0)
618037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ReferenceValue = pointer_value;
618137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
618237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *name = GuessCstringPointer(ReferenceValue, info);
618337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (name) {
61844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (pointer_value != 0 && selref) {
618537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref;
618637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->selector_name = name;
61874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    } else if (pointer_value != 0 && msgref) {
618837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->class_name = nullptr;
618937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref;
619037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->selector_name = name;
619137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else
619237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
619337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return name;
619437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
619537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
619637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Lastly look for an indirect symbol with this ReferenceValue which is in
619737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // a literal pool.  If found return that symbol name.
619837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  name = GuessIndirectSymbol(ReferenceValue, info);
619937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (name) {
620037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
620137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return name;
620237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
620337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
620437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return nullptr;
620537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
620637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
620737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolizerSymbolLookUp is the symbol lookup function passed when creating
620837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// the Symbolizer.  It looks up the ReferenceValue using the info passed via the
620937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// pointer to the struct DisassembleInfo that was passed when MCSymbolizer
621037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// is created and returns the symbol name that matches the ReferenceValue or
621137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// nullptr if none.  The ReferenceType is passed in for the IN type of
621237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// reference the instruction is making from the values in defined in the header
621337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// "llvm-c/Disassembler.h".  On return the ReferenceType can set to a specific
621437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Out type and the ReferenceName will also be set which is added as a comment
621537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// to the disassembled instruction.
621637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
621737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if HAVE_CXXABI_H
621837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// If the symbol name is a C++ mangled name then the demangled name is
621937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// returned through ReferenceName and ReferenceType is set to
622037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// LLVMDisassembler_ReferenceType_DeMangled_Name .
622137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
622237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
622337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// When this is called to get a symbol name for a branch target then the
622437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
622537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolValue will be looked for in the indirect symbol table to determine if
622637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// it is an address for a symbol stub.  If so then the symbol name for that
622737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// stub is returned indirectly through ReferenceName and then ReferenceType is
622837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
622937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
623037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// When this is called with an value loaded via a PC relative load then
623137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// ReferenceType will be LLVMDisassembler_ReferenceType_In_PCrel_Load then the
623237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// SymbolValue is checked to be an address of literal pointer, symbol pointer,
623337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// or an Objective-C meta data reference.  If so the output ReferenceType is
623437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// set to correspond to that as well as setting the ReferenceName.
62354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic const char *SymbolizerSymbolLookUp(void *DisInfo,
62364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                          uint64_t ReferenceValue,
62374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                          uint64_t *ReferenceType,
62384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                          uint64_t ReferencePC,
62394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                          const char **ReferenceName) {
624037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct DisassembleInfo *info = (struct DisassembleInfo *)DisInfo;
624137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If no verbose symbolic information is wanted then just return nullptr.
62424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (!info->verbose) {
624337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName = nullptr;
624437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
624537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return nullptr;
624637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
624737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap);
624937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
625037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (*ReferenceType == LLVMDisassembler_ReferenceType_In_Branch) {
625137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName = GuessIndirectSymbol(ReferenceValue, info);
625237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (*ReferenceName != nullptr) {
625337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      method_reference(info, ReferenceType, ReferenceName);
625437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
625537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
625637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else
625737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if HAVE_CXXABI_H
625837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
625937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->demangled_name != nullptr)
626037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        free(info->demangled_name);
626137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int status;
626237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->demangled_name =
626337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
626437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (info->demangled_name != nullptr) {
626537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *ReferenceName = info->demangled_name;
626637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
626737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      } else
626837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
626937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else
627037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
627137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
627237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
627337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName =
627437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
627537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (*ReferenceName)
627637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      method_reference(info, ReferenceType, ReferenceName);
627737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
627837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
627937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is arm64 and the reference is an adrp instruction save the
628037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // instruction, passed in ReferenceValue and the address of the instruction
628137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // for use later if we see and add immediate instruction.
628237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (info->O->getArch() == Triple::aarch64 &&
628337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
628437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    info->adrp_inst = ReferenceValue;
628537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    info->adrp_addr = ReferencePC;
628637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolName = nullptr;
628737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName = nullptr;
628837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
628937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is arm64 and reference is an add immediate instruction and we
629037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // have
629137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // seen an adrp instruction just before it and the adrp's Xd register
629237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // matches
629337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // this add's Xn register reconstruct the value being referenced and look to
629437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // see if it is a literal pointer.  Note the add immediate instruction is
629537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // passed in ReferenceValue.
629637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (info->O->getArch() == Triple::aarch64 &&
629737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
629837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             ReferencePC - 4 == info->adrp_addr &&
629937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             (info->adrp_inst & 0x9f000000) == 0x90000000 &&
630037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
630137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t addxri_inst;
630237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t adrp_imm, addxri_imm;
630337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
630437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    adrp_imm =
630537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
630637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (info->adrp_inst & 0x0200000)
630737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      adrp_imm |= 0xfffffffffc000000LL;
630837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
630937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    addxri_inst = ReferenceValue;
631037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    addxri_imm = (addxri_inst >> 10) & 0xfff;
631137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (((addxri_inst >> 22) & 0x3) == 1)
631237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      addxri_imm <<= 12;
631337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
631437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
631537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     (adrp_imm << 12) + addxri_imm;
631637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
631737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName =
631837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
631937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (*ReferenceName == nullptr)
632037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
632137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is arm64 and the reference is a load register instruction and we
632237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // have seen an adrp instruction just before it and the adrp's Xd register
632337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // matches this add's Xn register reconstruct the value being referenced and
632437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // look to see if it is a literal pointer.  Note the load register
632537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // instruction is passed in ReferenceValue.
632637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (info->O->getArch() == Triple::aarch64 &&
632737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXui &&
632837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             ReferencePC - 4 == info->adrp_addr &&
632937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             (info->adrp_inst & 0x9f000000) == 0x90000000 &&
633037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             (info->adrp_inst & 0x1f) == ((ReferenceValue >> 5) & 0x1f)) {
633137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t ldrxui_inst;
633237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t adrp_imm, ldrxui_imm;
633337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
633437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    adrp_imm =
633537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ((info->adrp_inst & 0x00ffffe0) >> 3) | ((info->adrp_inst >> 29) & 0x3);
633637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (info->adrp_inst & 0x0200000)
633737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      adrp_imm |= 0xfffffffffc000000LL;
633837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
633937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ldrxui_inst = ReferenceValue;
634037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ldrxui_imm = (ldrxui_inst >> 10) & 0xfff;
634137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
634237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ReferenceValue = (info->adrp_addr & 0xfffffffffffff000LL) +
634337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     (adrp_imm << 12) + (ldrxui_imm << 3);
634437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
634537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName =
634637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
634737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (*ReferenceName == nullptr)
634837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
634937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
635037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this arm64 and is an load register (PC-relative) instruction the
635137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // ReferenceValue is the PC plus the immediate value.
635237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (info->O->getArch() == Triple::aarch64 &&
635337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           (*ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_LDRXl ||
635437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            *ReferenceType == LLVMDisassembler_ReferenceType_In_ARM64_ADR)) {
635537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName =
635637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
635737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (*ReferenceName == nullptr)
635837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
635937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
636037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#if HAVE_CXXABI_H
636137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
636237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (info->demangled_name != nullptr)
636337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      free(info->demangled_name);
636437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int status;
636537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    info->demangled_name =
636637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
636737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (info->demangled_name != nullptr) {
636837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceName = info->demangled_name;
636937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
637037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
637137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
637237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
637337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
637437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceName = nullptr;
637537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
637637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
637737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
637837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SymbolName;
637937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
638037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
638137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// \brief Emits the comments that are stored in the CommentStream.
638237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Each comment in the CommentStream must end with a newline.
638337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void emitComments(raw_svector_ostream &CommentStream,
638437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         SmallString<128> &CommentsToEmit,
638537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         formatted_raw_ostream &FormattedOS,
638637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         const MCAsmInfo &MAI) {
638737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Flush the stream before taking its content.
638837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Comments = CommentsToEmit.str();
638937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Get the default information for printing a comment.
639037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *CommentBegin = MAI.getCommentString();
639137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned CommentColumn = MAI.getCommentColumn();
639237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool IsFirst = true;
639337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  while (!Comments.empty()) {
639437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!IsFirst)
639537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      FormattedOS << '\n';
639637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Emit a line of comments.
639737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FormattedOS.PadToColumn(CommentColumn);
639837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    size_t Position = Comments.find('\n');
639937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
640037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Move after the newline character.
640137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Comments = Comments.substr(Position + 1);
640237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    IsFirst = false;
640337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
640437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  FormattedOS.flush();
640537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
640637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Tell the comment stream that the vector changed underneath it.
640737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CommentsToEmit.clear();
640837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
640937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
6411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                             StringRef DisSegName, StringRef DisSectName) {
641237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *McpuDefault = nullptr;
641337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const Target *ThumbTarget = nullptr;
641437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
64150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!TheTarget) {
64160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    // GetTarget prints out stuff.
64170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
64180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
641937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (MCPU.empty() && McpuDefault)
642037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MCPU = McpuDefault;
642137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
642236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
642337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<const MCInstrInfo> ThumbInstrInfo;
642437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ThumbTarget)
642537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbInstrInfo.reset(ThumbTarget->createMCInstrInfo());
642637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
642737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Package up features to be passed to target/subtarget
642837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::string FeaturesStr;
642937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (MAttrs.size()) {
643037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SubtargetFeatures Features;
643137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (unsigned i = 0; i != MAttrs.size(); ++i)
643237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Features.AddFeature(MAttrs[i]);
643337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FeaturesStr = Features.getString();
643437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
64350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
64360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Set up disassembler.
643736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCRegisterInfo> MRI(
643836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCRegInfo(TripleName));
643936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCAsmInfo> AsmInfo(
64404a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola      TheTarget->createMCAsmInfo(*MRI, TripleName));
644136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCSubtargetInfo> STI(
644237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
6443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
644437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCDisassembler> DisAsm(
644537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TheTarget->createMCDisassembler(*STI, Ctx));
644637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCSymbolizer> Symbolizer;
644737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct DisassembleInfo SymbolizerInfo;
644837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCRelocationInfo> RelInfo(
644937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TheTarget->createMCRelocationInfo(TripleName, Ctx));
645037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (RelInfo) {
645137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Symbolizer.reset(TheTarget->createMCSymbolizer(
645237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        TripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        &SymbolizerInfo, &Ctx, std::move(RelInfo)));
645437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DisAsm->setSymbolizer(std::move(Symbolizer));
645537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
64560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
645736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
64580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      Triple(TripleName), AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI));
645937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Set the display preference for hex vs. decimal immediates.
646037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  IP->setPrintImmHex(PrintImmHex);
646137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Comment stream and backing vector.
646237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallString<128> CommentsToEmit;
646337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  raw_svector_ostream CommentStream(CommentsToEmit);
6464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // FIXME: Setting the CommentStream in the InstPrinter is problematic in that
6465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // if it is done then arm64 comments for string literals don't get printed
6466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // and some constant get printed instead and not setting it causes intel
6467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // (32-bit and 64-bit) comments printed with different spacing before the
6468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // comment causing different diffs with the 'C' disassembler library API.
6469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // IP->setCommentStream(CommentStream);
6470a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer
647137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!AsmInfo || !STI || !DisAsm || !IP) {
64723773fb46ba530f69530d1c4bafb7885528a27391Michael J. Spencer    errs() << "error: couldn't initialize disassembler for target "
6473a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer           << TripleName << '\n';
64740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
64750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
64760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
6477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Set up separate thumb disassembler if needed.
647837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<const MCRegisterInfo> ThumbMRI;
647937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<const MCAsmInfo> ThumbAsmInfo;
648037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<const MCSubtargetInfo> ThumbSTI;
648137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCDisassembler> ThumbDisAsm;
648237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCInstPrinter> ThumbIP;
648337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCContext> ThumbCtx;
648437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCSymbolizer> ThumbSymbolizer;
648537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct DisassembleInfo ThumbSymbolizerInfo;
648637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MCRelocationInfo> ThumbRelInfo;
648737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ThumbTarget) {
648837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbMRI.reset(ThumbTarget->createMCRegInfo(ThumbTripleName));
648937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbAsmInfo.reset(
649037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ThumbTarget->createMCAsmInfo(*ThumbMRI, ThumbTripleName));
649137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSTI.reset(
649237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ThumbTarget->createMCSubtargetInfo(ThumbTripleName, MCPU, FeaturesStr));
649337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbCtx.reset(new MCContext(ThumbAsmInfo.get(), ThumbMRI.get(), nullptr));
649437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbDisAsm.reset(ThumbTarget->createMCDisassembler(*ThumbSTI, *ThumbCtx));
649537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MCContext *PtrThumbCtx = ThumbCtx.get();
649637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbRelInfo.reset(
649737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ThumbTarget->createMCRelocationInfo(ThumbTripleName, *PtrThumbCtx));
649837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ThumbRelInfo) {
649937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ThumbSymbolizer.reset(ThumbTarget->createMCSymbolizer(
650037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ThumbTripleName, SymbolizerGetOpInfo, SymbolizerSymbolLookUp,
6501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          &ThumbSymbolizerInfo, PtrThumbCtx, std::move(ThumbRelInfo)));
650237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ThumbDisAsm->setSymbolizer(std::move(ThumbSymbolizer));
650337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
650437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int ThumbAsmPrinterVariant = ThumbAsmInfo->getAssemblerDialect();
650537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbIP.reset(ThumbTarget->createMCInstPrinter(
65060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        Triple(ThumbTripleName), ThumbAsmPrinterVariant, *ThumbAsmInfo,
65070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        *ThumbInstrInfo, *ThumbMRI));
650837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Set the display preference for hex vs. decimal immediates.
650937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbIP->setPrintImmHex(PrintImmHex);
651037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
651137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
651237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ThumbTarget && (!ThumbAsmInfo || !ThumbSTI || !ThumbDisAsm || !ThumbIP)) {
651337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "error: couldn't initialize disassembler for target "
651437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ThumbTripleName << '\n';
651537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
651637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
651737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
65185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  MachO::mach_header Header = MachOOF->getHeader();
65190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
6520ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // FIXME: Using the -cfg command line option, this code used to be able to
6521ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // annotate relocations with the referenced symbol's name, and if this was
6522ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // inside a __[cf]string section, the data it points to. This is now replaced
6523ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
6524481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SectionRef> Sections;
6525481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SymbolRef> Symbols;
65260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  SmallVector<uint64_t, 8> FoundFns;
652754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseSegmentAddress;
65280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
65296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  getSectionsAndSymbols(MachOOF, Sections, Symbols, FoundFns,
653054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                        BaseSegmentAddress);
65310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
65320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Sort the symbols by address, just in case they didn't come in that way.
6533481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
65340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
653554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  // Build a data in code table that is sorted on by the address of each entry.
653654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseAddress = 0;
65375510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  if (Header.filetype == MachO::MH_OBJECT)
653837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    BaseAddress = Sections[0].getAddress();
653954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  else
654054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    BaseAddress = BaseSegmentAddress;
654154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  DiceTable Dices;
654254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
654336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       DI != DE; ++DI) {
654454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    uint32_t Offset;
654554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    DI->getOffset(Offset);
654654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
654754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  }
654854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  array_pod_sort(Dices.begin(), Dices.end());
654954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
65500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#ifndef NDEBUG
65510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
65520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#else
65530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = nulls();
65540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#endif
65550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
655636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DIContext> diContext;
6557da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola  ObjectFile *DbgObj = MachOOF;
65588c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  // Try to find debug info and set up the DIContext for it.
65598c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  if (UseDbg) {
65608c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // A separate DSym file path was specified, parse it as a macho file,
65618c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // get the sections and supply it to the section name parsing machinery.
65628c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    if (!DSYMFile.empty()) {
656337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
6564c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          MemoryBuffer::getFileOrSTDIN(DSYMFile);
656537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (std::error_code EC = BufOrErr.getError()) {
6566c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
65678c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer        return;
65688c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      }
656937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DbgObj =
657037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
657137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              .get()
657237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              .release();
65738c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    }
65748c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
6575d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    // Setup the DIContext
65766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    diContext.reset(new DWARFContextInMemory(*DbgObj));
65778c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  }
65788c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
6579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (FilterSections.size() == 0)
6580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "(" << DisSegName << "," << DisSectName << ") section\n";
6581ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
6582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
6583481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
6584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Sections[SectIdx].getName(SectName) || SectName != DisSectName)
6585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
65860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
6587cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
6588ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
6589f16c2bb320f4d5b33dfaf8df8865f547e6d66005Rafael Espindola    StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
6590ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (SegmentName != DisSegName)
6591cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola      continue;
6592cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola
659337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef BytesStr;
659437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Sections[SectIdx].getContents(BytesStr);
659537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
659637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            BytesStr.size());
659737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SectAddress = Sections[SectIdx].getAddress();
659837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
65990b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    bool symbolTableWorked = false;
66000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
660137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Create a map of symbol addresses to symbol names for use by
660237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // the SymbolizerSymbolLookUp() routine.
660337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolAddressMap AddrMap;
66044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    bool DisSymNameFound = false;
660537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (const SymbolRef &Symbol : MachOOF->symbols()) {
6606de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<SymbolRef::Type> STOrErr = Symbol.getType();
6607de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!STOrErr) {
6608de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
6609de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
6610de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(STOrErr.takeError(), OS, "");
6611de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
6612de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
6613de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6614de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      SymbolRef::Type ST = *STOrErr;
661537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
661637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ST == SymbolRef::ST_Other) {
6617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint64_t Address = Symbol.getValue();
6618de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Expected<StringRef> SymNameOrErr = Symbol.getName();
6619de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!SymNameOrErr) {
6620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          std::string Buf;
6621de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          raw_string_ostream OS(Buf);
6622de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          logAllUnhandledErrors(SymNameOrErr.takeError(), OS, "");
6623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          OS.flush();
6624de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          report_fatal_error(Buf);
6625de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        }
6626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        StringRef SymName = *SymNameOrErr;
662737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        AddrMap[Address] = SymName;
66284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        if (!DisSymName.empty() && DisSymName == SymName)
66294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          DisSymNameFound = true;
663037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
663137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
66324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (!DisSymName.empty() && !DisSymNameFound) {
66334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      outs() << "Can't find -dis-symname: " << DisSymName << "\n";
66344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return;
66354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
663637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Set up the block of info used by the Symbolizer call backs.
66374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    SymbolizerInfo.verbose = !NoSymbolicOperands;
663837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.O = MachOOF;
663937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.S = Sections[SectIdx];
664037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.AddrMap = &AddrMap;
664137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.Sections = &Sections;
664237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.class_name = nullptr;
664337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.selector_name = nullptr;
664437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.method = nullptr;
664537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.demangled_name = nullptr;
664637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.bindtable = nullptr;
664737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.adrp_addr = 0;
664837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SymbolizerInfo.adrp_inst = 0;
664937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Same for the ThumbSymbolizer
66504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    ThumbSymbolizerInfo.verbose = !NoSymbolicOperands;
665137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.O = MachOOF;
665237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.S = Sections[SectIdx];
665337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.AddrMap = &AddrMap;
665437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.Sections = &Sections;
665537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.class_name = nullptr;
665637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.selector_name = nullptr;
665737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.method = nullptr;
665837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.demangled_name = nullptr;
665937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.bindtable = nullptr;
666037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.adrp_addr = 0;
666137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ThumbSymbolizerInfo.adrp_inst = 0;
666237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned int Arch = MachOOF->getArch();
6664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
666537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Disassemble symbol by symbol.
666637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
6667de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName();
6668de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!SymNameOrErr) {
6669de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
6670de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
6671de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(SymNameOrErr.takeError(), OS, "");
6672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
6673de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
6674de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StringRef SymName = *SymNameOrErr;
6676481837a743be2bd4723d96f304abba93140dc206Owen Anderson
6677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<SymbolRef::Type> STOrErr = Symbols[SymIdx].getType();
6678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!STOrErr) {
6679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        std::string Buf;
6680de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        raw_string_ostream OS(Buf);
6681de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        logAllUnhandledErrors(STOrErr.takeError(), OS, "");
6682de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        OS.flush();
6683de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        report_fatal_error(Buf);
6684de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      SymbolRef::Type ST = *STOrErr;
6686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
6687481837a743be2bd4723d96f304abba93140dc206Owen Anderson        continue;
6688481837a743be2bd4723d96f304abba93140dc206Owen Anderson
6689a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Make sure the symbol is defined in this section.
669037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      bool containsSym = Sections[SectIdx].containsSymbol(Symbols[SymIdx]);
6691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!containsSym) {
6692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!DisSymName.empty() && DisSymName == SymName) {
6693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          outs() << "-dis-symname: " << DisSymName << " not in the section\n";
6694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          return;
6695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar	}
6696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        continue;
6697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // The __mh_execute_header is special and we need to deal with that fact
6699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // this symbol is before the start of the (__TEXT,__text) section and at the
6700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // address of the start of the __TEXT segment.  This is because this symbol
6701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // is an N_SECT symbol in the (__TEXT,__text) but its address is before the
6702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // start of the section in a standard MH_EXECUTE filetype.
6703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!DisSymName.empty() && DisSymName == "__mh_execute_header") {
6704de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        outs() << "-dis-symname: __mh_execute_header not in any section\n";
6705de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return;
6706de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
6707de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // When this code is trying to disassemble a symbol at a time and in the case
6708de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // there is only the __mh_execute_header symbol left as in a stripped
6709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // executable, we need to deal with this by ignoring this symbol so the whole
6710de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // section is disassembled and this symbol is then not displayed.
6711de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (SymName == "__mh_execute_header")
67120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        continue;
67130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
67144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      // If we are only disassembling one symbol see if this is that symbol.
67154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (!DisSymName.empty() && DisSymName != SymName)
67164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        continue;
67174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
6718a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Start at the address of the symbol relative to the section's address.
6719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t Start = Symbols[SymIdx].getValue();
672037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t SectionAddress = Sections[SectIdx].getAddress();
6721ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      Start -= SectionAddress;
6722481837a743be2bd4723d96f304abba93140dc206Owen Anderson
6723a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Stop disassembling either at the beginning of the next symbol or at
6724a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // the end of the section.
672541854aea66ade4dea16a80bc8ef7ddf6c379d21fKevin Enderby      bool containsNextSym = false;
6726481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t NextSym = 0;
672737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t NextSymIdx = SymIdx + 1;
6728481837a743be2bd4723d96f304abba93140dc206Owen Anderson      while (Symbols.size() > NextSymIdx) {
6729de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Expected<SymbolRef::Type> STOrErr = Symbols[NextSymIdx].getType();
6730de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!STOrErr) {
6731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          std::string Buf;
6732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          raw_string_ostream OS(Buf);
6733de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          logAllUnhandledErrors(STOrErr.takeError(), OS, "");
6734de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          OS.flush();
6735de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          report_fatal_error(Buf);
6736de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        }
6737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        SymbolRef::Type NextSymType = *STOrErr;
6738481837a743be2bd4723d96f304abba93140dc206Owen Anderson        if (NextSymType == SymbolRef::ST_Function) {
673937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          containsNextSym =
674037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
6741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          NextSym = Symbols[NextSymIdx].getValue();
6742ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich          NextSym -= SectionAddress;
6743481837a743be2bd4723d96f304abba93140dc206Owen Anderson          break;
6744481837a743be2bd4723d96f304abba93140dc206Owen Anderson        }
6745481837a743be2bd4723d96f304abba93140dc206Owen Anderson        ++NextSymIdx;
6746481837a743be2bd4723d96f304abba93140dc206Owen Anderson      }
67470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
674837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t SectSize = Sections[SectIdx].getSize();
674937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t End = containsNextSym ? NextSym : SectSize;
6750481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t Size;
67510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
67520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      symbolTableWorked = true;
67530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
675437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      DataRefImpl Symb = Symbols[SymIdx].getRawDataRefImpl();
6755de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      bool IsThumb = MachOOF->getSymbolFlags(Symb) & SymbolRef::SF_Thumb;
6756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
6757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // We only need the dedicated Thumb target if there's a real choice
6758de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // (i.e. we're not targeting M-class) and the function is Thumb.
6759de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      bool UseThumbTarget = IsThumb && ThumbTarget;
676037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6761ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      outs() << SymName << ":\n";
6762ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      DILineInfo lastLine;
6763ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      for (uint64_t Index = Start; Index < End; Index += Size) {
6764ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        MCInst Inst;
6765ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
676637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint64_t PC = SectAddress + Index;
67674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        if (!NoLeadingAddr) {
67684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          if (FullLeadingAddr) {
67694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            if (MachOOF->is64Bit())
67704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar              outs() << format("%016" PRIx64, PC);
67714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            else
67724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar              outs() << format("%08" PRIx64, PC);
67734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          } else {
67744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            outs() << format("%8" PRIx64 ":", PC);
67754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          }
677637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
6777de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!NoShowRawInsn || Arch == Triple::arm)
677837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          outs() << "\t";
677954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
678054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // Check the data in code table here to see if this is data not an
678154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // instruction to be disassembled.
678254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        DiceTable Dice;
678337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Dice.push_back(std::make_pair(PC, DiceRef()));
678437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        dice_table_iterator DTI =
678537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            std::search(Dices.begin(), Dices.end(), Dice.begin(), Dice.end(),
678637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                        compareDiceTableEntries);
678737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (DTI != Dices.end()) {
678854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Length;
678954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getLength(Length);
679054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Kind;
679154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getKind(Kind);
67924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          Size = DumpDataInCode(Bytes.data() + Index, Length, Kind);
679337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if ((Kind == MachO::DICE_KIND_JUMP_TABLE8) &&
679437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              (PC == (DTI->first + Length - 1)) && (Length & 1))
679537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Size++;
679654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          continue;
679754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        }
679854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
679937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        SmallVector<char, 64> AnnotationsBytes;
680037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        raw_svector_ostream Annotations(AnnotationsBytes);
680137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
680237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        bool gotInst;
6803de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (UseThumbTarget)
680437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          gotInst = ThumbDisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
680537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                PC, DebugOut, Annotations);
680637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        else
680737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          gotInst = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index), PC,
680837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                           DebugOut, Annotations);
680937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (gotInst) {
6810de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (!NoShowRawInsn || Arch == Triple::arm) {
6811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            dumpBytes(makeArrayRef(Bytes.data() + Index, Size), outs());
681237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
681337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          formatted_raw_ostream FormattedOS(outs());
681437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          StringRef AnnotationsStr = Annotations.str();
6815de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (UseThumbTarget)
68160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            ThumbIP->printInst(&Inst, FormattedOS, AnnotationsStr, *ThumbSTI);
681737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          else
68180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            IP->printInst(&Inst, FormattedOS, AnnotationsStr, *STI);
681937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          emitComments(CommentStream, CommentsToEmit, FormattedOS, *AsmInfo);
6820ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
6821ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          // Print debug info.
6822ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          if (diContext) {
682337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            DILineInfo dli = diContext->getLineInfoForAddress(PC);
6824ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            // Print valid line info if it changed.
6825dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            if (dli != lastLine && dli.Line != 0)
6826dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
6827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     << dli.Column;
6828ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            lastLine = dli;
68290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
6830ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          outs() << "\n";
6831ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        } else {
683237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          unsigned int Arch = MachOOF->getArch();
683337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (Arch == Triple::x86_64 || Arch == Triple::x86) {
683437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            outs() << format("\t.byte 0x%02x #bad opcode\n",
683537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             *(Bytes.data() + Index) & 0xff);
683637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Size = 1; // skip exactly one illegible byte and move on.
6837de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else if (Arch == Triple::aarch64 ||
6838de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     (Arch == Triple::arm && !IsThumb)) {
683937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
684037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              (*(Bytes.data() + Index + 1) & 0xff) << 8 |
684137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              (*(Bytes.data() + Index + 2) & 0xff) << 16 |
684237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              (*(Bytes.data() + Index + 3) & 0xff) << 24;
684337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            outs() << format("\t.long\t0x%08x\n", opcode);
684437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Size = 4;
6845de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else if (Arch == Triple::arm) {
6846de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            assert(IsThumb && "ARM mode should have been dealt with above");
6847de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            uint32_t opcode = (*(Bytes.data() + Index) & 0xff) |
6848de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              (*(Bytes.data() + Index + 1) & 0xff) << 8;
6849de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            outs() << format("\t.short\t0x%04x\n", opcode);
6850de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            Size = 2;
6851de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          } else{
685237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errs() << "llvm-objdump: warning: invalid instruction encoding\n";
685337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (Size == 0)
685437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              Size = 1; // skip illegible bytes
685537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
68560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
68570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
68580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
6859ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    if (!symbolTableWorked) {
686037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Reading the symbol table didn't work, disassemble the whole section.
686137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t SectAddress = Sections[SectIdx].getAddress();
686237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t SectSize = Sections[SectIdx].getSize();
686359c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t InstSize;
686459c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
6865f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        MCInst Inst;
6866f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling
686737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        uint64_t PC = SectAddress + Index;
686837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (DisAsm->getInstruction(Inst, InstSize, Bytes.slice(Index), PC,
6869f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling                                   DebugOut, nulls())) {
68704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          if (!NoLeadingAddr) {
68714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            if (FullLeadingAddr) {
68724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar              if (MachOOF->is64Bit())
68734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                outs() << format("%016" PRIx64, PC);
68744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar              else
68754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                outs() << format("%08" PRIx64, PC);
68764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            } else {
68774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar              outs() << format("%8" PRIx64 ":", PC);
68784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            }
687937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
6880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (!NoShowRawInsn || Arch == Triple::arm) {
688137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            outs() << "\t";
6882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            dumpBytes(makeArrayRef(Bytes.data() + Index, InstSize), outs());
688337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
68840c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          IP->printInst(&Inst, outs(), "", *STI);
6885f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          outs() << "\n";
6886f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        } else {
688737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          unsigned int Arch = MachOOF->getArch();
688837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if (Arch == Triple::x86_64 || Arch == Triple::x86) {
688937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            outs() << format("\t.byte 0x%02x #bad opcode\n",
689037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             *(Bytes.data() + Index) & 0xff);
689137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            InstSize = 1; // skip exactly one illegible byte and move on.
689237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          } else {
689337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            errs() << "llvm-objdump: warning: invalid instruction encoding\n";
689437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            if (InstSize == 0)
689537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              InstSize = 1; // skip illegible bytes
689637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
6897f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        }
689859c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      }
689959c15e920c9873804f3150d0c13357696f09e300Kevin Enderby    }
6900ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // The TripleName's need to be reset if we are called again for a different
6901ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // archtecture.
6902ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    TripleName = "";
6903ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ThumbTripleName = "";
6904ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
690537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SymbolizerInfo.method != nullptr)
690637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      free(SymbolizerInfo.method);
690737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SymbolizerInfo.demangled_name != nullptr)
690837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      free(SymbolizerInfo.demangled_name);
690937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SymbolizerInfo.bindtable != nullptr)
691037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      delete SymbolizerInfo.bindtable;
691137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ThumbSymbolizerInfo.method != nullptr)
691237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      free(ThumbSymbolizerInfo.method);
691337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ThumbSymbolizerInfo.demangled_name != nullptr)
691437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      free(ThumbSymbolizerInfo.demangled_name);
691537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ThumbSymbolizerInfo.bindtable != nullptr)
691637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      delete ThumbSymbolizerInfo.bindtable;
691737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
691837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
691937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
692037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
692137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// __compact_unwind section dumping
692237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
692337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
692437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace {
692537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
692637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinestemplate <typename T> static uint64_t readNext(const char *&Buf) {
692737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  using llvm::support::little;
692837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  using llvm::support::unaligned;
692937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
693037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t Val = support::endian::read<T, little, unaligned>(Buf);
693137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Buf += sizeof(T);
693237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return Val;
693337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
693437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
693537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstruct CompactUnwindEntry {
693637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t OffsetInSection;
693737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
693837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t FunctionAddr;
693937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Length;
694037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t CompactEncoding;
694137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t PersonalityAddr;
694237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t LSDAAddr;
694337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
694437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RelocationRef FunctionReloc;
694537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RelocationRef PersonalityReloc;
694637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RelocationRef LSDAReloc;
694737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
694837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CompactUnwindEntry(StringRef Contents, unsigned Offset, bool Is64)
694937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      : OffsetInSection(Offset) {
695037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Is64)
695137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      read<uint64_t>(Contents.data() + Offset);
695237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
695337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      read<uint32_t>(Contents.data() + Offset);
695437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
695537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
695637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate:
695737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  template <typename UIntPtr> void read(const char *Buf) {
695837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FunctionAddr = readNext<UIntPtr>(Buf);
695937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Length = readNext<uint32_t>(Buf);
696037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CompactEncoding = readNext<uint32_t>(Buf);
696137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PersonalityAddr = readNext<UIntPtr>(Buf);
696237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    LSDAAddr = readNext<UIntPtr>(Buf);
696337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
696437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
696537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
696637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
696737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Given a relocation from __compact_unwind, consisting of the RelocationRef
696837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// and data being relocated, determine the best base Name and Addend to use for
696937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// display purposes.
697037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines///
697137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// 1. An Extern relocation will directly reference a symbol (and the data is
697237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines///    then already an addend), so use that.
697337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// 2. Otherwise the data is an offset in the object file's layout; try to find
697437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//     a symbol before it in the same section, and use the offset from there.
697537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// 3. Finally, if all that fails, fall back to an offset from the start of the
697637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines///    referenced section.
697737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void findUnwindRelocNameAddend(const MachOObjectFile *Obj,
697837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                      std::map<uint64_t, SymbolRef> &Symbols,
697937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                      const RelocationRef &Reloc, uint64_t Addr,
698037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                      StringRef &Name, uint64_t &Addend) {
698137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Reloc.getSymbol() != Obj->symbol_end()) {
6982de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<StringRef> NameOrErr = Reloc.getSymbol()->getName();
6983de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!NameOrErr) {
6984de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
6985de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
6986de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(NameOrErr.takeError(), OS, "");
6987de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
6988de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
6989de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
6990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Name = *NameOrErr;
699137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Addend = Addr;
699237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
699337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
699437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
699537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto RE = Obj->getRelocation(Reloc.getRawDataRefImpl());
69966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SectionRef RelocSection = Obj->getAnyRelocationSection(RE);
699737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
699837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t SectionAddr = RelocSection.getAddress();
699937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
700037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto Sym = Symbols.upper_bound(Addr);
700137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Sym == Symbols.begin()) {
700237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // The first symbol in the object is after this reference, the best we can
700337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // do is section-relative notation.
700437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RelocSection.getName(Name);
700537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Addend = Addr - SectionAddr;
700637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
700737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
700837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
700937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Go back one so that SymbolAddress <= Addr.
701037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  --Sym;
701137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7012de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto SectOrErr = Sym->second.getSection();
7013de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!SectOrErr) {
7014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::string Buf;
7015de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    raw_string_ostream OS(Buf);
7016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
7017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    OS.flush();
7018de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    report_fatal_error(Buf);
7019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
7020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  section_iterator SymSection = *SectOrErr;
702137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (RelocSection == *SymSection) {
702237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // There's a valid symbol in the same section before this reference.
7023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<StringRef> NameOrErr = Sym->second.getName();
7024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!NameOrErr) {
7025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
7026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
7027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(NameOrErr.takeError(), OS, "");
7028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
7029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(Buf);
7030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
7031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Name = *NameOrErr;
703237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Addend = Addr - Sym->first;
703337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
703437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
703537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
703637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // There is a symbol before this reference, but it's in a different
703737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // section. Probably not helpful to mention it, so use the section name.
703837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RelocSection.getName(Name);
703937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Addend = Addr - SectionAddr;
704037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
704137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
704237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void printUnwindRelocDest(const MachOObjectFile *Obj,
704337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 std::map<uint64_t, SymbolRef> &Symbols,
704437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 const RelocationRef &Reloc, uint64_t Addr) {
704537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Name;
704637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t Addend;
704737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!Reloc.getObject())
704937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
705037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
705137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend);
705237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
705337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << Name;
705437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Addend)
705537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " + " << format("0x%" PRIx64, Addend);
705637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
705737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
705837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void
705937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesprintMachOCompactUnwindSection(const MachOObjectFile *Obj,
706037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               std::map<uint64_t, SymbolRef> &Symbols,
706137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               const SectionRef &CompactUnwind) {
706237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
706337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Obj->isLittleEndian() &&
706437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "There should not be a big-endian .o with __compact_unwind");
706537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
706637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Is64 = Obj->is64Bit();
706737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t PointerSize = Is64 ? sizeof(uint64_t) : sizeof(uint32_t);
706837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t EntrySize = 3 * PointerSize + 2 * sizeof(uint32_t);
706937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
707037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Contents;
707137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CompactUnwind.getContents(Contents);
707237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
707337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<CompactUnwindEntry, 4> CompactUnwinds;
707437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
707537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // First populate the initial raw offsets, encodings and so on from the entry.
707637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned Offset = 0; Offset < Contents.size(); Offset += EntrySize) {
707737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CompactUnwindEntry Entry(Contents.data(), Offset, Is64);
707837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CompactUnwinds.push_back(Entry);
707937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
708037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
708137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Next we need to look at the relocations to find out what objects are
708237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // actually being referred to.
708337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const RelocationRef &Reloc : CompactUnwind.relocations()) {
7084f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t RelocAddress = Reloc.getOffset();
708537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
708637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t EntryIdx = RelocAddress / EntrySize;
708737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize;
708837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CompactUnwindEntry &Entry = CompactUnwinds[EntryIdx];
708937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
709037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (OffsetInEntry == 0)
709137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Entry.FunctionReloc = Reloc;
709237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (OffsetInEntry == PointerSize + 2 * sizeof(uint32_t))
709337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Entry.PersonalityReloc = Reloc;
709437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (OffsetInEntry == 2 * PointerSize + 2 * sizeof(uint32_t))
709537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Entry.LSDAReloc = Reloc;
709637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
709737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Unexpected relocation in __compact_unwind section");
709837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
709937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
710037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Finally, we're ready to print the data we've gathered.
710137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Contents of __compact_unwind section:\n";
710237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Entry : CompactUnwinds) {
710337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "  Entry at offset "
710437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format("0x%" PRIx32, Entry.OffsetInSection) << ":\n";
710537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
710637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // 1. Start of the region this entry applies to.
710737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    start:                " << format("0x%" PRIx64,
710837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                     Entry.FunctionAddr) << ' ';
710937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printUnwindRelocDest(Obj, Symbols, Entry.FunctionReloc, Entry.FunctionAddr);
711037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << '\n';
711137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
711237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // 2. Length of the region this entry applies to.
711337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    length:               " << format("0x%" PRIx32, Entry.Length)
711437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << '\n';
711537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // 3. The 32-bit compact encoding.
711637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    compact encoding:     "
711737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n';
711837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
711937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // 4. The personality function, if present.
7120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Entry.PersonalityReloc.getObject()) {
712137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "    personality function: "
712237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             << format("0x%" PRIx64, Entry.PersonalityAddr) << ' ';
712337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc,
712437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           Entry.PersonalityAddr);
712537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << '\n';
712637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
712737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
712837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // 5. This entry's language-specific data area.
7129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Entry.LSDAReloc.getObject()) {
713037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "    LSDA:                 " << format("0x%" PRIx64,
713137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                       Entry.LSDAAddr) << ' ';
713237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr);
713337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << '\n';
713437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
713537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
713637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
713737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
713837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
713937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// __unwind_info section dumping
714037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
714137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
714237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void printRegularSecondLevelUnwindPage(const char *PageStart) {
714337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *Pos = PageStart;
714437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Kind = readNext<uint32_t>(Pos);
714537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  (void)Kind;
714637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Kind == 2 && "kind for a regular 2nd level index should be 2");
714737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
714837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t EntriesStart = readNext<uint16_t>(Pos);
714937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t NumEntries = readNext<uint16_t>(Pos);
715037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
715137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = PageStart + EntriesStart;
715237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < NumEntries; ++i) {
715337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t FunctionOffset = readNext<uint32_t>(Pos);
715437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Encoding = readNext<uint32_t>(Pos);
715537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
715637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      [" << i << "]: "
715737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
715837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ", "
715937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "encoding=" << format("0x%08" PRIx32, Encoding) << '\n';
716037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
716137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
716237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
716337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void printCompressedSecondLevelUnwindPage(
716437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *PageStart, uint32_t FunctionBase,
716537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const SmallVectorImpl<uint32_t> &CommonEncodings) {
716637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *Pos = PageStart;
716737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Kind = readNext<uint32_t>(Pos);
716837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  (void)Kind;
716937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Kind == 3 && "kind for a compressed 2nd level index should be 3");
717037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
717137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t EntriesStart = readNext<uint16_t>(Pos);
717237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t NumEntries = readNext<uint16_t>(Pos);
717337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
717437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t EncodingsStart = readNext<uint16_t>(Pos);
717537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  readNext<uint16_t>(Pos);
717637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const auto *PageEncodings = reinterpret_cast<const support::ulittle32_t *>(
717737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PageStart + EncodingsStart);
717837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
717937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = PageStart + EntriesStart;
718037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < NumEntries; ++i) {
718137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Entry = readNext<uint32_t>(Pos);
718237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t FunctionOffset = FunctionBase + (Entry & 0xffffff);
718337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t EncodingIdx = Entry >> 24;
718437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
718537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Encoding;
718637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (EncodingIdx < CommonEncodings.size())
718737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Encoding = CommonEncodings[EncodingIdx];
718837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
718937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Encoding = PageEncodings[EncodingIdx - CommonEncodings.size()];
719037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
719137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      [" << i << "]: "
719237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
719337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ", "
719437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "encoding[" << EncodingIdx
719537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "]=" << format("0x%08" PRIx32, Encoding) << '\n';
719637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
719737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
719837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
719937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void printMachOUnwindInfoSection(const MachOObjectFile *Obj,
720037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                        std::map<uint64_t, SymbolRef> &Symbols,
720137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                        const SectionRef &UnwindInfo) {
720237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
720337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Obj->isLittleEndian() &&
720437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "There should not be a big-endian .o with __unwind_info");
720537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
720637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Contents of __unwind_info section:\n";
720737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
720837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Contents;
720937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  UnwindInfo.getContents(Contents);
721037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *Pos = Contents.data();
721137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
721237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
721337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Section header
721437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
721537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
721637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Version = readNext<uint32_t>(Pos);
721737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Version:                                   "
721837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, Version) << '\n';
721937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Version == 1 && "only understand version 1");
722037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
722137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t CommonEncodingsStart = readNext<uint32_t>(Pos);
722237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Common encodings array section offset:     "
722337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, CommonEncodingsStart) << '\n';
722437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t NumCommonEncodings = readNext<uint32_t>(Pos);
722537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Number of common encodings in array:       "
722637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, NumCommonEncodings) << '\n';
722737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
722837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t PersonalitiesStart = readNext<uint32_t>(Pos);
722937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Personality function array section offset: "
723037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, PersonalitiesStart) << '\n';
723137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t NumPersonalities = readNext<uint32_t>(Pos);
723237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Number of personality functions in array:  "
723337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, NumPersonalities) << '\n';
723437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
723537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t IndicesStart = readNext<uint32_t>(Pos);
723637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Index array section offset:                "
723737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, IndicesStart) << '\n';
723837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t NumIndices = readNext<uint32_t>(Pos);
723937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Number of indices in array:                "
724037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         << format("0x%" PRIx32, NumIndices) << '\n';
724137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
724237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
724337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // A shared list of common encodings
724437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
724537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
724637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // These occupy indices in the range [0, N] whenever an encoding is referenced
724737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // from a compressed 2nd level index table. In practice the linker only
724837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // creates ~128 of these, so that indices are available to embed encodings in
724937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // the 2nd level index.
725037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
725137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<uint32_t, 64> CommonEncodings;
725237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Common encodings: (count = " << NumCommonEncodings << ")\n";
725337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = Contents.data() + CommonEncodingsStart;
725437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < NumCommonEncodings; ++i) {
725537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Encoding = readNext<uint32_t>(Pos);
725637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CommonEncodings.push_back(Encoding);
725737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
725837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    encoding[" << i << "]: " << format("0x%08" PRIx32, Encoding)
725937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << '\n';
726037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
726137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
726237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
726337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Personality functions used in this executable
726437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
726537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
726637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // There should be only a handful of these (one per source language,
726737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // roughly). Particularly since they only get 2 bits in the compact encoding.
726837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
726937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Personality functions: (count = " << NumPersonalities << ")\n";
727037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = Contents.data() + PersonalitiesStart;
727137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < NumPersonalities; ++i) {
727237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t PersonalityFn = readNext<uint32_t>(Pos);
727337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    personality[" << i + 1
727437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "]: " << format("0x%08" PRIx32, PersonalityFn) << '\n';
727537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
727637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
727737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
727837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The level 1 index entries
727937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
728037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
728137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // These specify an approximate place to start searching for the more detailed
728237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // information, sorted by PC.
728337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
728437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct IndexEntry {
728537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t FunctionOffset;
728637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SecondLevelPageStart;
728737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t LSDAStart;
728837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  };
728937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
729037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<IndexEntry, 4> IndexEntries;
729137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
729237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Top level indices: (count = " << NumIndices << ")\n";
729337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = Contents.data() + IndicesStart;
729437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < NumIndices; ++i) {
729537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    IndexEntry Entry;
729637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
729737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Entry.FunctionOffset = readNext<uint32_t>(Pos);
729837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Entry.SecondLevelPageStart = readNext<uint32_t>(Pos);
729937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Entry.LSDAStart = readNext<uint32_t>(Pos);
730037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    IndexEntries.push_back(Entry);
730137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
730237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    [" << i << "]: "
730337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "function offset=" << format("0x%08" PRIx32, Entry.FunctionOffset)
730437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ", "
730537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "2nd level page offset="
730637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format("0x%08" PRIx32, Entry.SecondLevelPageStart) << ", "
730737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "LSDA offset=" << format("0x%08" PRIx32, Entry.LSDAStart) << '\n';
730837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
730937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
731037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
731137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Next come the LSDA tables
731237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
731337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
731437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The LSDA layout is rather implicit: it's a contiguous array of entries from
731537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // the first top-level index's LSDAOffset to the last (sentinel).
731637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
731737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  LSDA descriptors:\n";
731837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Pos = Contents.data() + IndexEntries[0].LSDAStart;
731937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int NumLSDAs = (IndexEntries.back().LSDAStart - IndexEntries[0].LSDAStart) /
732037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 (2 * sizeof(uint32_t));
732137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (int i = 0; i < NumLSDAs; ++i) {
732237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t FunctionOffset = readNext<uint32_t>(Pos);
732337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t LSDAOffset = readNext<uint32_t>(Pos);
732437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    [" << i << "]: "
732537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "function offset=" << format("0x%08" PRIx32, FunctionOffset)
732637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ", "
732737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "LSDA offset=" << format("0x%08" PRIx32, LSDAOffset) << '\n';
732837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
732937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
733037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
733137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Finally, the 2nd level indices
733237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //===----------------------------------
733337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
733437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Generally these are 4K in size, and have 2 possible forms:
733537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //   + Regular stores up to 511 entries with disparate encodings
733637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //   + Compressed stores up to 1021 entries if few enough compact encoding
733737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //     values are used.
733837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  Second level indices:\n";
733937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned i = 0; i < IndexEntries.size() - 1; ++i) {
734037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // The final sentinel top-level index has no associated 2nd level page
734137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (IndexEntries[i].SecondLevelPageStart == 0)
734237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
734337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
734437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    Second level index[" << i << "]: "
734537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "offset in section="
734637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format("0x%08" PRIx32, IndexEntries[i].SecondLevelPageStart)
734737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ", "
734837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "base function offset="
734937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format("0x%08" PRIx32, IndexEntries[i].FunctionOffset) << '\n';
735037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
735137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Pos = Contents.data() + IndexEntries[i].SecondLevelPageStart;
735237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t Kind = *reinterpret_cast<const support::ulittle32_t *>(Pos);
735337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Kind == 2)
735437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printRegularSecondLevelUnwindPage(Pos);
735537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (Kind == 3)
735637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printCompressedSecondLevelUnwindPage(Pos, IndexEntries[i].FunctionOffset,
735737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                           CommonEncodings);
735837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
735937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Do not know how to print this kind of 2nd level page");
736037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
736137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
736237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
736337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOUnwindInfo(const MachOObjectFile *Obj) {
736437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::map<uint64_t, SymbolRef> Symbols;
736537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const SymbolRef &SymRef : Obj->symbols()) {
736637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Discard any undefined or absolute symbols. They're not going to take part
736737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // in the convenience lookup for unwind info and just take up resources.
7368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto SectOrErr = SymRef.getSection();
7369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!SectOrErr) {
7370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // TODO: Actually report errors helpfully.
7371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      consumeError(SectOrErr.takeError());
7372de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      continue;
7373de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
7374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    section_iterator Section = *SectOrErr;
737537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Section == Obj->section_end())
737637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
737737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t Addr = SymRef.getValue();
737937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Symbols.insert(std::make_pair(Addr, SymRef));
738037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
738137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
738237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
738337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectName;
738437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Section.getName(SectName);
738537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SectName == "__compact_unwind")
738637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printMachOCompactUnwindSection(Obj, Symbols, Section);
738737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (SectName == "__unwind_info")
738837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      printMachOUnwindInfoSection(Obj, Symbols, Section);
738937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
739037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
739137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
739237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintMachHeader(uint32_t magic, uint32_t cputype,
739337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            uint32_t cpusubtype, uint32_t filetype,
739437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            uint32_t ncmds, uint32_t sizeofcmds, uint32_t flags,
739537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            bool verbose) {
739637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Mach header\n";
739737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      magic cputype cpusubtype  caps    filetype ncmds "
739837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "sizeofcmds      flags\n";
739937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (verbose) {
740037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (magic == MachO::MH_MAGIC)
740137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "   MH_MAGIC";
740237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (magic == MachO::MH_MAGIC_64)
740337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "MH_MAGIC_64";
740437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
740537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format(" 0x%08" PRIx32, magic);
740637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (cputype) {
740737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_I386:
740837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "    I386";
740937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
741037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_I386_ALL:
741137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        ALL";
741237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
741337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
741437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
741537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
741637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
741737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
741837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_X86_64:
741937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  X86_64";
7420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
7421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::CPU_SUBTYPE_X86_64_ALL:
7422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "        ALL";
7423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
7424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case MachO::CPU_SUBTYPE_X86_64_H:
7425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "    Haswell";
7426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
7427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      default:
7428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
7430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
743137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
743237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_ARM:
743337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "     ARM";
743437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
743537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_ALL:
743637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        ALL";
743737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
743837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V4T:
743937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        V4T";
744037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
744137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V5TEJ:
744237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "      V5TEJ";
744337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
744437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_XSCALE:
744537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "     XSCALE";
744637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
744737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V6:
744837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "         V6";
744937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
745037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V6M:
745137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        V6M";
745237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
745337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V7:
745437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "         V7";
745537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
745637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V7EM:
745737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "       V7EM";
745837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
745937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V7K:
746037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        V7K";
746137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
746237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V7M:
746337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        V7M";
746437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
746537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM_V7S:
746637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        V7S";
746737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
746837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
746937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
747037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
747137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
747237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
747337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_ARM64:
747437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "   ARM64";
747537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
747637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_ARM64_ALL:
747737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        ALL";
747837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
747937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
748037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
748137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
748237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
748337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
748437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_POWERPC:
748537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "     PPC";
748637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
748737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_POWERPC_ALL:
748837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        ALL";
748937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
749037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
749137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
749237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
749337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
749437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
749537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::CPU_TYPE_POWERPC64:
749637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "   PPC64";
749737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      switch (cpusubtype & ~MachO::CPU_SUBTYPE_MASK) {
749837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case MachO::CPU_SUBTYPE_POWERPC_ALL:
749937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "        ALL";
750037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
750137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
750237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
750337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
750437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
750537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
7506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    default:
7507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format(" %7d", cputype);
7508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
7509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      break;
751037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
751137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((cpusubtype & MachO::CPU_SUBTYPE_MASK) == MachO::CPU_SUBTYPE_LIB64) {
751237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " LIB64";
751337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
751437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format("  0x%02" PRIx32,
751537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
751637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
751737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (filetype) {
751837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_OBJECT:
751937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "      OBJECT";
752037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
752137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_EXECUTE:
752237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "     EXECUTE";
752337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
752437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_FVMLIB:
752537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "      FVMLIB";
752637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
752737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_CORE:
752837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "        CORE";
752937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
753037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_PRELOAD:
753137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "     PRELOAD";
753237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
753337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_DYLIB:
753437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "       DYLIB";
753537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
753637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_DYLIB_STUB:
753737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  DYLIB_STUB";
753837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
753937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_DYLINKER:
754037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "    DYLINKER";
754137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
754237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_BUNDLE:
754337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "      BUNDLE";
754437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
754537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_DSYM:
754637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "        DSYM";
754737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
754837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::MH_KEXT_BUNDLE:
754937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  KEXTBUNDLE";
755037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
755137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
755237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format("  %10u", filetype);
755337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
755437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
755537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %5u", ncmds);
755637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %10u", sizeofcmds);
755737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t f = flags;
755837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_NOUNDEFS) {
755937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "   NOUNDEFS";
756037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_NOUNDEFS;
756137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
756237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_INCRLINK) {
756337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " INCRLINK";
756437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_INCRLINK;
756537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
756637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_DYLDLINK) {
756737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " DYLDLINK";
756837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_DYLDLINK;
756937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
757037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_BINDATLOAD) {
757137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " BINDATLOAD";
757237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_BINDATLOAD;
757337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
757437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_PREBOUND) {
757537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " PREBOUND";
757637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_PREBOUND;
757737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
757837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_SPLIT_SEGS) {
757937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " SPLIT_SEGS";
758037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_SPLIT_SEGS;
758137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
758237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_LAZY_INIT) {
758337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " LAZY_INIT";
758437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_LAZY_INIT;
758537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
758637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_TWOLEVEL) {
758737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " TWOLEVEL";
758837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_TWOLEVEL;
758937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
759037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_FORCE_FLAT) {
759137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " FORCE_FLAT";
759237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_FORCE_FLAT;
759337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
759437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_NOMULTIDEFS) {
759537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " NOMULTIDEFS";
759637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_NOMULTIDEFS;
759737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
759837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_NOFIXPREBINDING) {
759937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " NOFIXPREBINDING";
760037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_NOFIXPREBINDING;
760137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
760237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_PREBINDABLE) {
760337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " PREBINDABLE";
760437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_PREBINDABLE;
760537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
760637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_ALLMODSBOUND) {
760737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " ALLMODSBOUND";
760837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_ALLMODSBOUND;
760937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
761037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_SUBSECTIONS_VIA_SYMBOLS) {
761137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " SUBSECTIONS_VIA_SYMBOLS";
761237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
761337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
761437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_CANONICAL) {
761537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " CANONICAL";
761637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_CANONICAL;
761737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
761837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_WEAK_DEFINES) {
761937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " WEAK_DEFINES";
762037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_WEAK_DEFINES;
762137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
762237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_BINDS_TO_WEAK) {
762337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " BINDS_TO_WEAK";
762437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_BINDS_TO_WEAK;
762537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
762637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_ALLOW_STACK_EXECUTION) {
762737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " ALLOW_STACK_EXECUTION";
762837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_ALLOW_STACK_EXECUTION;
762937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
763037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_DEAD_STRIPPABLE_DYLIB) {
763137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " DEAD_STRIPPABLE_DYLIB";
763237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_DEAD_STRIPPABLE_DYLIB;
763337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
763437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_PIE) {
763537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " PIE";
763637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_PIE;
763737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
763837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_NO_REEXPORTED_DYLIBS) {
763937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " NO_REEXPORTED_DYLIBS";
764037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_NO_REEXPORTED_DYLIBS;
764137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
764237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_HAS_TLV_DESCRIPTORS) {
764337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " MH_HAS_TLV_DESCRIPTORS";
764437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_HAS_TLV_DESCRIPTORS;
764537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
764637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_NO_HEAP_EXECUTION) {
764737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " MH_NO_HEAP_EXECUTION";
764837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_NO_HEAP_EXECUTION;
764937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
765037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f & MachO::MH_APP_EXTENSION_SAFE) {
765137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " APP_EXTENSION_SAFE";
765237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      f &= ~MachO::MH_APP_EXTENSION_SAFE;
765337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
765437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (f != 0 || flags == 0)
765537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format(" 0x%08" PRIx32, f);
765637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
765737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" 0x%08" PRIx32, magic);
765837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %7d", cputype);
765937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
766037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format("  0x%02" PRIx32,
766137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     (cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
766237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format("  %10u", filetype);
766337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %5u", ncmds);
766437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" %10u", sizeofcmds);
766537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format(" 0x%08" PRIx32, flags);
766637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
766737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "\n";
766837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
766937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
767037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintSegmentCommand(uint32_t cmd, uint32_t cmdsize,
767137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                StringRef SegName, uint64_t vmaddr,
767237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                uint64_t vmsize, uint64_t fileoff,
767337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                uint64_t filesize, uint32_t maxprot,
767437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                uint32_t initprot, uint32_t nsects,
767537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                uint32_t flags, uint32_t object_size,
767637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                bool verbose) {
767737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t expected_cmdsize;
767837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cmd == MachO::LC_SEGMENT) {
767937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_SEGMENT\n";
768037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize = nsects;
768137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize *= sizeof(struct MachO::section);
768237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize += sizeof(struct MachO::segment_command);
768337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
768437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_SEGMENT_64\n";
768537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize = nsects;
768637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize *= sizeof(struct MachO::section_64);
768737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    expected_cmdsize += sizeof(struct MachO::segment_command_64);
768837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
768937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  cmdsize " << cmdsize;
769037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cmdsize != expected_cmdsize)
769137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Inconsistent size\n";
769237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
769337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
769437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  segname " << SegName << "\n";
769537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cmd == MachO::LC_SEGMENT_64) {
769637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "   vmaddr " << format("0x%016" PRIx64, vmaddr) << "\n";
769737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "   vmsize " << format("0x%016" PRIx64, vmsize) << "\n";
769837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
7699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "   vmaddr " << format("0x%08" PRIx64, vmaddr) << "\n";
7700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "   vmsize " << format("0x%08" PRIx64, vmsize) << "\n";
770137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
770237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  fileoff " << fileoff;
770337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fileoff > object_size)
770437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
770537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
770637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
770737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " filesize " << filesize;
770837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fileoff + filesize > object_size)
770937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
771037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
771137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
771237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (verbose) {
771337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((maxprot &
771437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
771537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           MachO::VM_PROT_EXECUTE)) != 0)
771637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  maxprot ?" << format("0x%08" PRIx32, maxprot) << "\n";
771737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
7718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << "  maxprot ";
7719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((maxprot & MachO::VM_PROT_READ) ? "r" : "-");
7720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((maxprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((maxprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
772237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
772337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((initprot &
772437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         ~(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE |
772537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           MachO::VM_PROT_EXECUTE)) != 0)
772637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  initprot ?" << format("0x%08" PRIx32, initprot) << "\n";
772737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
7728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << "  initprot ";
7729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((initprot & MachO::VM_PROT_READ) ? "r" : "-");
7730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((initprot & MachO::VM_PROT_WRITE) ? "w" : "-");
7731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << ((initprot & MachO::VM_PROT_EXECUTE) ? "x\n" : "-\n");
773237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
773337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
773437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "  maxprot " << format("0x%08" PRIx32, maxprot) << "\n";
773537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " initprot " << format("0x%08" PRIx32, initprot) << "\n";
773637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
773737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   nsects " << nsects << "\n";
773837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (verbose) {
773937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    flags";
774037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (flags == 0)
774137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " (none)\n";
774237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
774337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (flags & MachO::SG_HIGHVM) {
774437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " HIGHVM";
774537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        flags &= ~MachO::SG_HIGHVM;
774637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
774737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (flags & MachO::SG_FVMLIB) {
774837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " FVMLIB";
774937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        flags &= ~MachO::SG_FVMLIB;
775037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
775137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (flags & MachO::SG_NORELOC) {
775237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " NORELOC";
775337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        flags &= ~MachO::SG_NORELOC;
775437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
775537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (flags & MachO::SG_PROTECTED_VERSION_1) {
775637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " PROTECTED_VERSION_1";
775737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        flags &= ~MachO::SG_PROTECTED_VERSION_1;
775837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
775937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (flags)
776037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format(" 0x%08" PRIx32, flags) << " (unknown flags)\n";
776137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
776237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "\n";
776337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
776437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
776537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "    flags " << format("0x%" PRIx32, flags) << "\n";
776637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
776737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
776837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
776937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintSection(const char *sectname, const char *segname,
777037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         uint64_t addr, uint64_t size, uint32_t offset,
777137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         uint32_t align, uint32_t reloff, uint32_t nreloc,
777237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         uint32_t flags, uint32_t reserved1, uint32_t reserved2,
777337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         uint32_t cmd, const char *sg_segname,
777437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         uint32_t filetype, uint32_t object_size,
777537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         bool verbose) {
777637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Section\n";
777737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  sectname " << format("%.16s\n", sectname);
777837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   segname " << format("%.16s", segname);
777937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (filetype != MachO::MH_OBJECT && strncmp(sg_segname, segname, 16) != 0)
778037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (does not match segment)\n";
778137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
778237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
778337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (cmd == MachO::LC_SEGMENT_64) {
778437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      addr " << format("0x%016" PRIx64, addr) << "\n";
778537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      size " << format("0x%016" PRIx64, size);
778637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
7787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "      addr " << format("0x%08" PRIx64, addr) << "\n";
7788ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "      size " << format("0x%08" PRIx64, size);
778937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
779037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if ((flags & MachO::S_ZEROFILL) != 0 && offset + size > object_size)
779137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
779237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
779337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
779437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    offset " << offset;
779537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (offset > object_size)
779637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
779737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
779837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
779937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t align_shifted = 1 << align;
780037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     align 2^" << align << " (" << align_shifted << ")\n";
780137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    reloff " << reloff;
780237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (reloff > object_size)
780337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
780437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
780537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
780637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    nreloc " << nreloc;
780737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (reloff + nreloc * sizeof(struct MachO::relocation_info) > object_size)
780837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
780937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
781037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
781137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t section_type = flags & MachO::SECTION_TYPE;
781237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (verbose) {
781337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      type";
781437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_type == MachO::S_REGULAR)
781537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_REGULAR\n";
781637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_ZEROFILL)
781737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_ZEROFILL\n";
781837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_CSTRING_LITERALS)
781937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_CSTRING_LITERALS\n";
782037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_4BYTE_LITERALS)
782137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_4BYTE_LITERALS\n";
782237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_8BYTE_LITERALS)
782337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_8BYTE_LITERALS\n";
782437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_16BYTE_LITERALS)
782537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_16BYTE_LITERALS\n";
782637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_LITERAL_POINTERS)
782737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_LITERAL_POINTERS\n";
782837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS)
782937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_NON_LAZY_SYMBOL_POINTERS\n";
783037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_LAZY_SYMBOL_POINTERS)
783137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_LAZY_SYMBOL_POINTERS\n";
783237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_SYMBOL_STUBS)
783337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_SYMBOL_STUBS\n";
783437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_MOD_INIT_FUNC_POINTERS)
783537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_MOD_INIT_FUNC_POINTERS\n";
783637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_MOD_TERM_FUNC_POINTERS)
783737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_MOD_TERM_FUNC_POINTERS\n";
783837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_COALESCED)
783937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_COALESCED\n";
784037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_INTERPOSING)
784137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_INTERPOSING\n";
784237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_DTRACE_DOF)
784337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_DTRACE_DOF\n";
784437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS)
784537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_LAZY_DYLIB_SYMBOL_POINTERS\n";
784637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_THREAD_LOCAL_REGULAR)
784737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_THREAD_LOCAL_REGULAR\n";
784837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_THREAD_LOCAL_ZEROFILL)
784937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_THREAD_LOCAL_ZEROFILL\n";
785037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_THREAD_LOCAL_VARIABLES)
785137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_THREAD_LOCAL_VARIABLES\n";
785237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
785337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_THREAD_LOCAL_VARIABLE_POINTERS\n";
785437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (section_type == MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS)
785537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n";
785637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
785737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format("0x%08" PRIx32, section_type) << "\n";
785837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "attributes";
785937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t section_attributes = flags & MachO::SECTION_ATTRIBUTES;
786037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_PURE_INSTRUCTIONS)
786137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " PURE_INSTRUCTIONS";
786237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_NO_TOC)
786337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " NO_TOC";
786437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_STRIP_STATIC_SYMS)
786537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " STRIP_STATIC_SYMS";
786637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_NO_DEAD_STRIP)
786737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " NO_DEAD_STRIP";
786837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_LIVE_SUPPORT)
786937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " LIVE_SUPPORT";
787037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_SELF_MODIFYING_CODE)
787137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " SELF_MODIFYING_CODE";
787237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_DEBUG)
787337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " DEBUG";
787437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_SOME_INSTRUCTIONS)
787537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " SOME_INSTRUCTIONS";
787637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_EXT_RELOC)
787737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " EXT_RELOC";
787837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes & MachO::S_ATTR_LOC_RELOC)
787937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " LOC_RELOC";
788037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (section_attributes == 0)
788137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " (none)";
788237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
788337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else
788437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "     flags " << format("0x%08" PRIx32, flags) << "\n";
788537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " reserved1 " << reserved1;
788637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (section_type == MachO::S_SYMBOL_STUBS ||
788737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      section_type == MachO::S_LAZY_SYMBOL_POINTERS ||
788837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      section_type == MachO::S_LAZY_DYLIB_SYMBOL_POINTERS ||
788937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      section_type == MachO::S_NON_LAZY_SYMBOL_POINTERS ||
789037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      section_type == MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
789137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (index into indirect symbol table)\n";
789237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
789337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
789437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " reserved2 " << reserved2;
789537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (section_type == MachO::S_SYMBOL_STUBS)
789637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (size of stubs)\n";
789737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
789837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
789937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
790037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
790137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintSymtabLoadCommand(MachO::symtab_command st, bool Is64Bit,
790237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                   uint32_t object_size) {
790337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     cmd LC_SYMTAB\n";
790437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " cmdsize " << st.cmdsize;
790537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (st.cmdsize != sizeof(struct MachO::symtab_command))
790637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
790737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
790837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
790937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  symoff " << st.symoff;
791037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (st.symoff > object_size)
791137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
791237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
791337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
791437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   nsyms " << st.nsyms;
791537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t big_size;
791637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Is64Bit) {
791737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size = st.nsyms;
791837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size *= sizeof(struct MachO::nlist_64);
791937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size += st.symoff;
792037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (big_size > object_size)
792137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " (past end of file)\n";
792237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
792337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\n";
792437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
792537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size = st.nsyms;
792637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size *= sizeof(struct MachO::nlist);
792737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    big_size += st.symoff;
792837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (big_size > object_size)
792937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " (past end of file)\n";
793037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
793137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "\n";
79320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
793337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  stroff " << st.stroff;
793437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (st.stroff > object_size)
793537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
793637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
793737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
793837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " strsize " << st.strsize;
793937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = st.stroff;
794037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += st.strsize;
794137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
794237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
794337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
794437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
794537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
794637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
794737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintDysymtabLoadCommand(MachO::dysymtab_command dyst,
794837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     uint32_t nsyms, uint32_t object_size,
794937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     bool Is64Bit) {
795037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "            cmd LC_DYSYMTAB\n";
795137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "        cmdsize " << dyst.cmdsize;
795237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.cmdsize != sizeof(struct MachO::dysymtab_command))
795337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
795437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
795537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
795637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      ilocalsym " << dyst.ilocalsym;
795737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.ilocalsym > nsyms)
795837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (greater than the number of symbols)\n";
795937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
796037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
796137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      nlocalsym " << dyst.nlocalsym;
796237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t big_size;
796337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.ilocalsym;
796437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.nlocalsym;
796537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > nsyms)
796637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past the end of the symbol table)\n";
796737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
796837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
796937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     iextdefsym " << dyst.iextdefsym;
797037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.iextdefsym > nsyms)
797137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (greater than the number of symbols)\n";
797237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
797337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
797437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     nextdefsym " << dyst.nextdefsym;
797537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.iextdefsym;
797637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.nextdefsym;
797737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > nsyms)
797837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past the end of the symbol table)\n";
797937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
798037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
798137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      iundefsym " << dyst.iundefsym;
798237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.iundefsym > nsyms)
798337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (greater than the number of symbols)\n";
798437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
798537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
798637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      nundefsym " << dyst.nundefsym;
798737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.iundefsym;
798837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.nundefsym;
798937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > nsyms)
799037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past the end of the symbol table)\n";
799137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
799237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
799337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "         tocoff " << dyst.tocoff;
799437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.tocoff > object_size)
799537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
799637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
799737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
799837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "           ntoc " << dyst.ntoc;
799937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.ntoc;
800037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size *= sizeof(struct MachO::dylib_table_of_contents);
800137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.tocoff;
800237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
800337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
800437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
800537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
800637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      modtaboff " << dyst.modtaboff;
800737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.modtaboff > object_size)
800837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
800937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
801037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
801137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "        nmodtab " << dyst.nmodtab;
801237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t modtabend;
801337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Is64Bit) {
801437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend = dyst.nmodtab;
801537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend *= sizeof(struct MachO::dylib_module_64);
801637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend += dyst.modtaboff;
801737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
801837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend = dyst.nmodtab;
801937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend *= sizeof(struct MachO::dylib_module);
802037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    modtabend += dyst.modtaboff;
802137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
802237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (modtabend > object_size)
802337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
802437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
802537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
802637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   extrefsymoff " << dyst.extrefsymoff;
802737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.extrefsymoff > object_size)
802837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
802937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
803037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
803137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    nextrefsyms " << dyst.nextrefsyms;
803237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.nextrefsyms;
803337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size *= sizeof(struct MachO::dylib_reference);
803437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.extrefsymoff;
803537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
803637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
803737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
803837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
803937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " indirectsymoff " << dyst.indirectsymoff;
804037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.indirectsymoff > object_size)
804137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
804237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
804337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
804437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  nindirectsyms " << dyst.nindirectsyms;
804537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.nindirectsyms;
804637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size *= sizeof(uint32_t);
804737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.indirectsymoff;
804837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
804937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
805037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
805137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
805237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      extreloff " << dyst.extreloff;
805337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.extreloff > object_size)
805437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
805537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
805637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
805737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "        nextrel " << dyst.nextrel;
805837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.nextrel;
805937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size *= sizeof(struct MachO::relocation_info);
806037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.extreloff;
806137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
806237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
806337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
806437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
806537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      locreloff " << dyst.locreloff;
806637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyst.locreloff > object_size)
806737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
806837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
806937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
807037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "        nlocrel " << dyst.nlocrel;
807137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dyst.nlocrel;
807237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size *= sizeof(struct MachO::relocation_info);
807337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dyst.locreloff;
807437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
807537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
807637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
807737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
807837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
807937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
808037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintDyldInfoLoadCommand(MachO::dyld_info_command dc,
808137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     uint32_t object_size) {
808237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.cmd == MachO::LC_DYLD_INFO)
808337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "            cmd LC_DYLD_INFO\n";
808437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
808537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "            cmd LC_DYLD_INFO_ONLY\n";
808637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "        cmdsize " << dc.cmdsize;
808737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.cmdsize != sizeof(struct MachO::dyld_info_command))
808837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
808937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
809037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
809137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     rebase_off " << dc.rebase_off;
809237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.rebase_off > object_size)
809337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
809437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
809537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
809637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    rebase_size " << dc.rebase_size;
809737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t big_size;
809837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dc.rebase_off;
809937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dc.rebase_size;
810037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
810137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
810237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
810337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
810437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "       bind_off " << dc.bind_off;
810537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.bind_off > object_size)
810637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
810737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
810837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
810937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      bind_size " << dc.bind_size;
811037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dc.bind_off;
811137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dc.bind_size;
811237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
811337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
811437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
811537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
811637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  weak_bind_off " << dc.weak_bind_off;
811737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.weak_bind_off > object_size)
811837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
811937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
812037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
812137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " weak_bind_size " << dc.weak_bind_size;
812237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dc.weak_bind_off;
812337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dc.weak_bind_size;
812437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
812537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
812637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
812737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
812837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  lazy_bind_off " << dc.lazy_bind_off;
812937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.lazy_bind_off > object_size)
813037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
813137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
813237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
813337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " lazy_bind_size " << dc.lazy_bind_size;
813437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dc.lazy_bind_off;
813537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dc.lazy_bind_size;
813637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
813737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
813837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
813937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
814037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     export_off " << dc.export_off;
814137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dc.export_off > object_size)
814237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
814337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
814437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
814537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    export_size " << dc.export_size;
814637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size = dc.export_off;
814737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += dc.export_size;
814837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
814937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
815037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
815137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
815237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
815337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
815437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintDyldLoadCommand(MachO::dylinker_command dyld,
815537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                 const char *Ptr) {
815637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyld.cmd == MachO::LC_ID_DYLINKER)
815737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_ID_DYLINKER\n";
815837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dyld.cmd == MachO::LC_LOAD_DYLINKER)
815937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_LOAD_DYLINKER\n";
816037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dyld.cmd == MachO::LC_DYLD_ENVIRONMENT)
816137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_DYLD_ENVIRONMENT\n";
816237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
816337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd ?(" << dyld.cmd << ")\n";
816437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      cmdsize " << dyld.cmdsize;
816537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyld.cmdsize < sizeof(struct MachO::dylinker_command))
816637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
816737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
816837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
816937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dyld.name >= dyld.cmdsize)
817037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "         name ?(bad offset " << dyld.name << ")\n";
817137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
817237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *P = (const char *)(Ptr) + dyld.name;
817337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "         name " << P << " (offset " << dyld.name << ")\n";
817437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
817537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
817637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
817737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintUuidLoadCommand(MachO::uuid_command uuid) {
817837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "     cmd LC_UUID\n";
817937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " cmdsize " << uuid.cmdsize;
818037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (uuid.cmdsize != sizeof(struct MachO::uuid_command))
818137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
818237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
818337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
818437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "    uuid ";
8185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (int i = 0; i < 16; ++i) {
8186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << format("%02" PRIX32, uuid.uuid[i]);
8187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (i == 3 || i == 5 || i == 7 || i == 9)
8188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      outs() << "-";
8189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
819037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "\n";
819137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
819237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintRpathLoadCommand(MachO::rpath_command rpath, const char *Ptr) {
8194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_RPATH\n";
8195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << rpath.cmdsize;
8196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (rpath.cmdsize < sizeof(struct MachO::rpath_command))
8197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (rpath.path >= rpath.cmdsize)
8201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "         path ?(bad offset " << rpath.path << ")\n";
8202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else {
8203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *P = (const char *)(Ptr) + rpath.path;
8204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "         path " << P << " (offset " << rpath.path << ")\n";
8205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
820837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintVersionMinLoadCommand(MachO::version_min_command vd) {
8209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  StringRef LoadCmdName;
8210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (vd.cmd) {
8211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MachO::LC_VERSION_MIN_MACOSX:
8212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadCmdName = "LC_VERSION_MIN_MACOSX";
8213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
8214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MachO::LC_VERSION_MIN_IPHONEOS:
8215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadCmdName = "LC_VERSION_MIN_IPHONEOS";
8216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
8217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MachO::LC_VERSION_MIN_TVOS:
8218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadCmdName = "LC_VERSION_MIN_TVOS";
8219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
8220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MachO::LC_VERSION_MIN_WATCHOS:
8221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadCmdName = "LC_VERSION_MIN_WATCHOS";
8222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
8223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
8224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    llvm_unreachable("Unknown version min load command");
8225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
8226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
8227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  outs() << "      cmd " << LoadCmdName << '\n';
822837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  cmdsize " << vd.cmdsize;
822937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (vd.cmdsize != sizeof(struct MachO::version_min_command))
823037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
823137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
823237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
8233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  outs() << "  version "
8234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar         << MachOObjectFile::getVersionMinMajor(vd, false) << "."
8235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar         << MachOObjectFile::getVersionMinMinor(vd, false);
8236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint32_t Update = MachOObjectFile::getVersionMinUpdate(vd, false);
8237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Update != 0)
8238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << "." << Update;
823937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "\n";
824037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (vd.sdk == 0)
8241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "      sdk n/a";
824237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
8243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << "      sdk "
8244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           << MachOObjectFile::getVersionMinMajor(vd, true) << "."
8245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           << MachOObjectFile::getVersionMinMinor(vd, true);
824637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
8247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Update = MachOObjectFile::getVersionMinUpdate(vd, true);
8248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Update != 0)
8249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << "." << Update;
825037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "\n";
825137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
825237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
825337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintSourceVersionCommand(MachO::source_version_command sd) {
825437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      cmd LC_SOURCE_VERSION\n";
825537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  cmdsize " << sd.cmdsize;
825637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (sd.cmdsize != sizeof(struct MachO::source_version_command))
825737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
825837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
825937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
826037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t a = (sd.version >> 40) & 0xffffff;
826137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t b = (sd.version >> 30) & 0x3ff;
826237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t c = (sd.version >> 20) & 0x3ff;
826337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t d = (sd.version >> 10) & 0x3ff;
826437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t e = sd.version & 0x3ff;
826537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  version " << a << "." << b;
826637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (e != 0)
826737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "." << c << "." << d << "." << e;
826837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (d != 0)
826937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "." << c << "." << d;
827037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (c != 0)
827137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "." << c;
827237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "\n";
827337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
827437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
827537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintEntryPointCommand(MachO::entry_point_command ep) {
827637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "       cmd LC_MAIN\n";
827737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   cmdsize " << ep.cmdsize;
827837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ep.cmdsize != sizeof(struct MachO::entry_point_command))
827937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
828037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
828137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
828237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  entryoff " << ep.entryoff << "\n";
828337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " stacksize " << ep.stacksize << "\n";
828437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
828537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintEncryptionInfoCommand(MachO::encryption_info_command ec,
8287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       uint32_t object_size) {
8288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_ENCRYPTION_INFO\n";
8289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << ec.cmdsize;
8290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cmdsize != sizeof(struct MachO::encryption_info_command))
8291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "     cryptoff " << ec.cryptoff;
8295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cryptoff > object_size)
8296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (past end of file)\n";
8297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    cryptsize " << ec.cryptsize;
8300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cryptsize > object_size)
8301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (past end of file)\n";
8302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cryptid " << ec.cryptid << "\n";
8305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintEncryptionInfoCommand64(MachO::encryption_info_command_64 ec,
8308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                         uint32_t object_size) {
8309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_ENCRYPTION_INFO_64\n";
8310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << ec.cmdsize;
8311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cmdsize != sizeof(struct MachO::encryption_info_command_64))
8312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "     cryptoff " << ec.cryptoff;
8316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cryptoff > object_size)
8317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (past end of file)\n";
8318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    cryptsize " << ec.cryptsize;
8321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ec.cryptsize > object_size)
8322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " (past end of file)\n";
8323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cryptid " << ec.cryptid << "\n";
8326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          pad " << ec.pad << "\n";
8327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintLinkerOptionCommand(MachO::linker_option_command lo,
8330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                     const char *Ptr) {
8331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "     cmd LC_LINKER_OPTION\n";
8332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " cmdsize " << lo.cmdsize;
8333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (lo.cmdsize < sizeof(struct MachO::linker_option_command))
8334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   count " << lo.count << "\n";
8338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *string = Ptr + sizeof(struct MachO::linker_option_command);
8339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t left = lo.cmdsize - sizeof(struct MachO::linker_option_command);
8340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t i = 0;
8341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  while (left > 0) {
8342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    while (*string == '\0' && left > 0) {
8343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      string++;
8344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      left--;
8345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
8346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (left > 0) {
8347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      i++;
8348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "  string #" << i << " " << format("%.*s\n", left, string);
8349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t NullPos = StringRef(string, left).find('\0');
8350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t len = std::min(NullPos, left) + 1;
8351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      string += len;
8352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      left -= len;
8353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
8354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (lo.count != i)
8356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "   count " << lo.count << " does not match number of strings "
8357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           << i << "\n";
8358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintSubFrameworkCommand(MachO::sub_framework_command sub,
8361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                     const char *Ptr) {
8362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_SUB_FRAMEWORK\n";
8363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << sub.cmdsize;
8364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.cmdsize < sizeof(struct MachO::sub_framework_command))
8365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.umbrella < sub.cmdsize) {
8369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *P = Ptr + sub.umbrella;
8370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "     umbrella " << P << " (offset " << sub.umbrella << ")\n";
8371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
8372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "     umbrella ?(bad offset " << sub.umbrella << ")\n";
8373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintSubUmbrellaCommand(MachO::sub_umbrella_command sub,
8377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                    const char *Ptr) {
8378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_SUB_UMBRELLA\n";
8379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << sub.cmdsize;
8380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.cmdsize < sizeof(struct MachO::sub_umbrella_command))
8381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.sub_umbrella < sub.cmdsize) {
8385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *P = Ptr + sub.sub_umbrella;
8386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " sub_umbrella " << P << " (offset " << sub.sub_umbrella << ")\n";
8387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
8388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " sub_umbrella ?(bad offset " << sub.sub_umbrella << ")\n";
8389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintSubLibraryCommand(MachO::sub_library_command sub,
8393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                   const char *Ptr) {
8394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_SUB_LIBRARY\n";
8395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << sub.cmdsize;
8396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.cmdsize < sizeof(struct MachO::sub_library_command))
8397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.sub_library < sub.cmdsize) {
8401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *P = Ptr + sub.sub_library;
8402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "  sub_library " << P << " (offset " << sub.sub_library << ")\n";
8403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
8404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "  sub_library ?(bad offset " << sub.sub_library << ")\n";
8405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintSubClientCommand(MachO::sub_client_command sub,
8409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  const char *Ptr) {
8410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_SUB_CLIENT\n";
8411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << sub.cmdsize;
8412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.cmdsize < sizeof(struct MachO::sub_client_command))
8413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (sub.client < sub.cmdsize) {
8417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const char *P = Ptr + sub.client;
8418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "       client " << P << " (offset " << sub.client << ")\n";
8419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
8420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "       client ?(bad offset " << sub.client << ")\n";
8421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintRoutinesCommand(MachO::routines_command r) {
8425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_ROUTINES\n";
8426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << r.cmdsize;
8427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (r.cmdsize != sizeof(struct MachO::routines_command))
8428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " init_address " << format("0x%08" PRIx32, r.init_address) << "\n";
8432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "  init_module " << r.init_module << "\n";
8433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved1 " << r.reserved1 << "\n";
8434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved2 " << r.reserved2 << "\n";
8435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved3 " << r.reserved3 << "\n";
8436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved4 " << r.reserved4 << "\n";
8437ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved5 " << r.reserved5 << "\n";
8438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved6 " << r.reserved6 << "\n";
8439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintRoutinesCommand64(MachO::routines_command_64 r) {
8442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "          cmd LC_ROUTINES_64\n";
8443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "      cmdsize " << r.cmdsize;
8444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (r.cmdsize != sizeof(struct MachO::routines_command_64))
8445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8448ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " init_address " << format("0x%016" PRIx64, r.init_address) << "\n";
8449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "  init_module " << r.init_module << "\n";
8450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved1 " << r.reserved1 << "\n";
8451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved2 " << r.reserved2 << "\n";
8452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved3 " << r.reserved3 << "\n";
8453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved4 " << r.reserved4 << "\n";
8454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved5 " << r.reserved5 << "\n";
8455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    reserved6 " << r.reserved6 << "\n";
8456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void Print_x86_thread_state64_t(MachO::x86_thread_state64_t &cpu64) {
8459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   rax  " << format("0x%016" PRIx64, cpu64.rax);
8460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rbx " << format("0x%016" PRIx64, cpu64.rbx);
8461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rcx  " << format("0x%016" PRIx64, cpu64.rcx) << "\n";
8462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   rdx  " << format("0x%016" PRIx64, cpu64.rdx);
8463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rdi " << format("0x%016" PRIx64, cpu64.rdi);
8464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rsi  " << format("0x%016" PRIx64, cpu64.rsi) << "\n";
8465ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   rbp  " << format("0x%016" PRIx64, cpu64.rbp);
8466ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rsp " << format("0x%016" PRIx64, cpu64.rsp);
8467ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " r8   " << format("0x%016" PRIx64, cpu64.r8) << "\n";
8468ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    r9  " << format("0x%016" PRIx64, cpu64.r9);
8469ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " r10 " << format("0x%016" PRIx64, cpu64.r10);
8470ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " r11  " << format("0x%016" PRIx64, cpu64.r11) << "\n";
8471ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   r12  " << format("0x%016" PRIx64, cpu64.r12);
8472ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " r13 " << format("0x%016" PRIx64, cpu64.r13);
8473ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " r14  " << format("0x%016" PRIx64, cpu64.r14) << "\n";
8474ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "   r15  " << format("0x%016" PRIx64, cpu64.r15);
8475ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " rip " << format("0x%016" PRIx64, cpu64.rip) << "\n";
8476ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "rflags  " << format("0x%016" PRIx64, cpu64.rflags);
8477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " cs  " << format("0x%016" PRIx64, cpu64.cs);
8478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fs   " << format("0x%016" PRIx64, cpu64.fs) << "\n";
8479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    gs  " << format("0x%016" PRIx64, cpu64.gs) << "\n";
8480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void Print_mmst_reg(MachO::mmst_reg_t &r) {
8483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t f;
8484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t      mmst_reg  ";
8485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (f = 0; f < 10; f++)
8486ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("%02" PRIx32, (r.mmst_reg[f] & 0xff)) << " ";
8487ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8488ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t      mmst_rsrv ";
8489ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (f = 0; f < 6; f++)
8490ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("%02" PRIx32, (r.mmst_rsrv[f] & 0xff)) << " ";
8491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8493ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void Print_xmm_reg(MachO::xmm_reg_t &r) {
8495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t f;
8496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t      xmm_reg ";
8497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (f = 0; f < 16; f++)
8498ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << format("%02" PRIx32, (r.xmm_reg[f] & 0xff)) << " ";
8499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void Print_x86_float_state_t(MachO::x86_float_state64_t &fpu) {
8503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_reserved[0] " << fpu.fpu_reserved[0];
8504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_reserved[1] " << fpu.fpu_reserved[1] << "\n";
8505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    control: invalid " << fpu.fpu_fcw.invalid;
8506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " denorm " << fpu.fpu_fcw.denorm;
8507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " zdiv " << fpu.fpu_fcw.zdiv;
8508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " ovrfl " << fpu.fpu_fcw.ovrfl;
8509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " undfl " << fpu.fpu_fcw.undfl;
8510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " precis " << fpu.fpu_fcw.precis << "\n";
8511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t\t     pc ";
8512ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_24B)
8513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_PREC_24B ";
8514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_53B)
8515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_PREC_53B ";
8516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (fpu.fpu_fcw.pc == MachO::x86_FP_PREC_64B)
8517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_PREC_64B ";
8518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << fpu.fpu_fcw.pc << " ";
8520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "rc ";
8521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_NEAR)
8522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_RND_NEAR ";
8523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_DOWN)
8524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_RND_DOWN ";
8525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (fpu.fpu_fcw.rc == MachO::x86_FP_RND_UP)
8526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_RND_UP ";
8527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (fpu.fpu_fcw.rc == MachO::x86_FP_CHOP)
8528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "FP_CHOP ";
8529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    status: invalid " << fpu.fpu_fsw.invalid;
8531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " denorm " << fpu.fpu_fsw.denorm;
8532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " zdiv " << fpu.fpu_fsw.zdiv;
8533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " ovrfl " << fpu.fpu_fsw.ovrfl;
8534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " undfl " << fpu.fpu_fsw.undfl;
8535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " precis " << fpu.fpu_fsw.precis;
8536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " stkflt " << fpu.fpu_fsw.stkflt << "\n";
8537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t            errsumm " << fpu.fpu_fsw.errsumm;
8538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " c0 " << fpu.fpu_fsw.c0;
8539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " c1 " << fpu.fpu_fsw.c1;
8540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " c2 " << fpu.fpu_fsw.c2;
8541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " tos " << fpu.fpu_fsw.tos;
8542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " c3 " << fpu.fpu_fsw.c3;
8543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " busy " << fpu.fpu_fsw.busy << "\n";
8544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_ftw " << format("0x%02" PRIx32, fpu.fpu_ftw);
8545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_rsrv1 " << format("0x%02" PRIx32, fpu.fpu_rsrv1);
8546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_fop " << format("0x%04" PRIx32, fpu.fpu_fop);
8547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_ip " << format("0x%08" PRIx32, fpu.fpu_ip) << "\n";
8548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_cs " << format("0x%04" PRIx32, fpu.fpu_cs);
8549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_rsrv2 " << format("0x%04" PRIx32, fpu.fpu_rsrv2);
8550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_dp " << format("0x%08" PRIx32, fpu.fpu_dp);
8551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_ds " << format("0x%04" PRIx32, fpu.fpu_ds) << "\n";
8552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_rsrv3 " << format("0x%04" PRIx32, fpu.fpu_rsrv3);
8553ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_mxcsr " << format("0x%08" PRIx32, fpu.fpu_mxcsr);
8554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " fpu_mxcsrmask " << format("0x%08" PRIx32, fpu.fpu_mxcsrmask);
8555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm0:\n";
8557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm0);
8558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm1:\n";
8559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm1);
8560ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm2:\n";
8561ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm2);
8562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm3:\n";
8563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm3);
8564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm4:\n";
8565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm4);
8566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm5:\n";
8567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm5);
8568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm6:\n";
8569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm6);
8570ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_stmm7:\n";
8571ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_mmst_reg(fpu.fpu_stmm7);
8572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm0:\n";
8573ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm0);
8574ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm1:\n";
8575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm1);
8576ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm2:\n";
8577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm2);
8578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm3:\n";
8579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm3);
8580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm4:\n";
8581ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm4);
8582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm5:\n";
8583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm5);
8584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm6:\n";
8585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm6);
8586ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm7:\n";
8587ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm7);
8588ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm8:\n";
8589ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm8);
8590ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm9:\n";
8591ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm9);
8592ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm10:\n";
8593ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm10);
8594ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm11:\n";
8595ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm11);
8596ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm12:\n";
8597ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm12);
8598ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm13:\n";
8599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm13);
8600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm14:\n";
8601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm14);
8602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_xmm15:\n";
8603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Print_xmm_reg(fpu.fpu_xmm15);
8604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_rsrv4:\n";
8605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (uint32_t f = 0; f < 6; f++) {
8606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\t            ";
8607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (uint32_t g = 0; g < 16; g++)
8608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << format("%02" PRIx32, fpu.fpu_rsrv4[f * g]) << " ";
8609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    fpu_reserved1 " << format("0x%08" PRIx32, fpu.fpu_reserved1);
8612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\n";
8613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void Print_x86_exception_state_t(MachO::x86_exception_state64_t &exc64) {
8616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "\t    trapno " << format("0x%08" PRIx32, exc64.trapno);
8617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " err " << format("0x%08" PRIx32, exc64.err);
8618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << " faultvaddr " << format("0x%016" PRIx64, exc64.faultvaddr) << "\n";
8619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void PrintThreadCommand(MachO::thread_command t, const char *Ptr,
8622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               bool isLittleEndian, uint32_t cputype) {
8623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (t.cmd == MachO::LC_THREAD)
8624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "        cmd LC_THREAD\n";
8625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else if (t.cmd == MachO::LC_UNIXTHREAD)
8626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "        cmd LC_UNIXTHREAD\n";
8627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "        cmd " << t.cmd << " (unknown)\n";
8629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  outs() << "    cmdsize " << t.cmdsize;
8630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (t.cmdsize < sizeof(struct MachO::thread_command) + 2 * sizeof(uint32_t))
8631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << " Incorrect size\n";
8632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  else
8633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    outs() << "\n";
8634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
8635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *begin = Ptr + sizeof(struct MachO::thread_command);
8636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const char *end = Ptr + t.cmdsize;
8637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  uint32_t flavor, count, left;
8638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (cputype == MachO::CPU_TYPE_X86_64) {
8639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    while (begin < end) {
8640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        memcpy((char *)&flavor, begin, sizeof(uint32_t));
8642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin += sizeof(uint32_t);
8643ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else {
8644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        flavor = 0;
8645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin = end;
8646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
8647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (isLittleEndian != sys::IsLittleEndianHost)
8648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(flavor);
8649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        memcpy((char *)&count, begin, sizeof(uint32_t));
8651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin += sizeof(uint32_t);
8652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else {
8653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        count = 0;
8654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin = end;
8655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
8656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (isLittleEndian != sys::IsLittleEndianHost)
8657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(count);
8658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (flavor == MachO::x86_THREAD_STATE64) {
8659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "     flavor x86_THREAD_STATE64\n";
8660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (count == MachO::x86_THREAD_STATE64_COUNT)
8661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count x86_THREAD_STATE64_COUNT\n";
8662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        else
8663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count " << count
8664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << " (not x86_THREAD_STATE64_COUNT)\n";
8665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        MachO::x86_thread_state64_t cpu64;
8666ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        left = end - begin;
8667ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (left >= sizeof(MachO::x86_thread_state64_t)) {
8668ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&cpu64, begin, sizeof(MachO::x86_thread_state64_t));
8669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += sizeof(MachO::x86_thread_state64_t);
8670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memset(&cpu64, '\0', sizeof(MachO::x86_thread_state64_t));
8672ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&cpu64, begin, left);
8673ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += left;
8674ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8675ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (isLittleEndian != sys::IsLittleEndianHost)
8676ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          swapStruct(cpu64);
8677ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Print_x86_thread_state64_t(cpu64);
8678ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else if (flavor == MachO::x86_THREAD_STATE) {
8679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "     flavor x86_THREAD_STATE\n";
8680ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (count == MachO::x86_THREAD_STATE_COUNT)
8681ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count x86_THREAD_STATE_COUNT\n";
8682ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        else
8683ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count " << count
8684ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << " (not x86_THREAD_STATE_COUNT)\n";
8685ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        struct MachO::x86_thread_state_t ts;
8686ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        left = end - begin;
8687ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (left >= sizeof(MachO::x86_thread_state_t)) {
8688ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&ts, begin, sizeof(MachO::x86_thread_state_t));
8689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += sizeof(MachO::x86_thread_state_t);
8690ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8691ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memset(&ts, '\0', sizeof(MachO::x86_thread_state_t));
8692ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&ts, begin, left);
8693ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += left;
8694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (isLittleEndian != sys::IsLittleEndianHost)
8696ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          swapStruct(ts);
8697ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (ts.tsh.flavor == MachO::x86_THREAD_STATE64) {
8698ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    tsh.flavor x86_THREAD_STATE64 ";
8699ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (ts.tsh.count == MachO::x86_THREAD_STATE64_COUNT)
8700ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "tsh.count x86_THREAD_STATE64_COUNT\n";
8701ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
8702ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "tsh.count " << ts.tsh.count
8703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << " (not x86_THREAD_STATE64_COUNT\n";
8704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Print_x86_thread_state64_t(ts.uts.ts64);
8705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8706ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    tsh.flavor " << ts.tsh.flavor << "  tsh.count "
8707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << ts.tsh.count << "\n";
8708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8709ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else if (flavor == MachO::x86_FLOAT_STATE) {
8710ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "     flavor x86_FLOAT_STATE\n";
8711ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (count == MachO::x86_FLOAT_STATE_COUNT)
8712ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count x86_FLOAT_STATE_COUNT\n";
8713ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        else
8714ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count " << count << " (not x86_FLOAT_STATE_COUNT)\n";
8715ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        struct MachO::x86_float_state_t fs;
8716ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        left = end - begin;
8717ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (left >= sizeof(MachO::x86_float_state_t)) {
8718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&fs, begin, sizeof(MachO::x86_float_state_t));
8719ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += sizeof(MachO::x86_float_state_t);
8720ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8721ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memset(&fs, '\0', sizeof(MachO::x86_float_state_t));
8722ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&fs, begin, left);
8723ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += left;
8724ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8725ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (isLittleEndian != sys::IsLittleEndianHost)
8726ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          swapStruct(fs);
8727ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (fs.fsh.flavor == MachO::x86_FLOAT_STATE64) {
8728ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    fsh.flavor x86_FLOAT_STATE64 ";
8729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (fs.fsh.count == MachO::x86_FLOAT_STATE64_COUNT)
8730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "fsh.count x86_FLOAT_STATE64_COUNT\n";
8731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
8732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "fsh.count " << fs.fsh.count
8733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << " (not x86_FLOAT_STATE64_COUNT\n";
8734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Print_x86_float_state_t(fs.ufs.fs64);
8735ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8736ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    fsh.flavor " << fs.fsh.flavor << "  fsh.count "
8737ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << fs.fsh.count << "\n";
8738ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8739ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else if (flavor == MachO::x86_EXCEPTION_STATE) {
8740ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "     flavor x86_EXCEPTION_STATE\n";
8741ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (count == MachO::x86_EXCEPTION_STATE_COUNT)
8742ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count x86_EXCEPTION_STATE_COUNT\n";
8743ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        else
8744ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "      count " << count
8745ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << " (not x86_EXCEPTION_STATE_COUNT)\n";
8746ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        struct MachO::x86_exception_state_t es;
8747ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        left = end - begin;
8748ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (left >= sizeof(MachO::x86_exception_state_t)) {
8749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&es, begin, sizeof(MachO::x86_exception_state_t));
8750ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += sizeof(MachO::x86_exception_state_t);
8751ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8752ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memset(&es, '\0', sizeof(MachO::x86_exception_state_t));
8753ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          memcpy(&es, begin, left);
8754ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          begin += left;
8755ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8756ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (isLittleEndian != sys::IsLittleEndianHost)
8757ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          swapStruct(es);
8758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (es.esh.flavor == MachO::x86_EXCEPTION_STATE64) {
8759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    esh.flavor x86_EXCEPTION_STATE64\n";
8760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (es.esh.count == MachO::x86_EXCEPTION_STATE64_COUNT)
8761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "\t    esh.count x86_EXCEPTION_STATE64_COUNT\n";
8762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          else
8763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            outs() << "\t    esh.count " << es.esh.count
8764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << " (not x86_EXCEPTION_STATE64_COUNT\n";
8765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Print_x86_exception_state_t(es.ues.es64);
8766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        } else {
8767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          outs() << "\t    esh.flavor " << es.esh.flavor << "  esh.count "
8768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                 << es.esh.count << "\n";
8769ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
8770ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else {
8771ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "     flavor " << flavor << " (unknown)\n";
8772ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "      count " << count << "\n";
8773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        outs() << "      state (unknown)\n";
8774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin += count * sizeof(uint32_t);
8775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
8776ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
8777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
8778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    while (begin < end) {
8779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        memcpy((char *)&flavor, begin, sizeof(uint32_t));
8781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin += sizeof(uint32_t);
8782ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else {
8783ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        flavor = 0;
8784ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin = end;
8785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
8786ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (isLittleEndian != sys::IsLittleEndianHost)
8787ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(flavor);
8788ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (end - begin > (ptrdiff_t)sizeof(uint32_t)) {
8789ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        memcpy((char *)&count, begin, sizeof(uint32_t));
8790ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin += sizeof(uint32_t);
8791ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } else {
8792ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        count = 0;
8793ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        begin = end;
8794ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
8795ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (isLittleEndian != sys::IsLittleEndianHost)
8796ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        sys::swapByteOrder(count);
8797ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "     flavor " << flavor << "\n";
8798ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "      count " << count << "\n";
8799ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "      state (Unknown cputype/cpusubtype)\n";
8800ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      begin += count * sizeof(uint32_t);
8801ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
8802ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8803ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
8804ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
880537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintDylibCommand(MachO::dylib_command dl, const char *Ptr) {
880637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dl.cmd == MachO::LC_ID_DYLIB)
880737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_ID_DYLIB\n";
880837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dl.cmd == MachO::LC_LOAD_DYLIB)
880937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_LOAD_DYLIB\n";
881037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dl.cmd == MachO::LC_LOAD_WEAK_DYLIB)
881137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_LOAD_WEAK_DYLIB\n";
881237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dl.cmd == MachO::LC_REEXPORT_DYLIB)
881337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_REEXPORT_DYLIB\n";
881437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dl.cmd == MachO::LC_LAZY_LOAD_DYLIB)
881537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_LAZY_LOAD_DYLIB\n";
881637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (dl.cmd == MachO::LC_LOAD_UPWARD_DYLIB)
881737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd LC_LOAD_UPWARD_DYLIB\n";
881837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
881937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "          cmd " << dl.cmd << " (unknown)\n";
882037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      cmdsize " << dl.cmdsize;
882137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dl.cmdsize < sizeof(struct MachO::dylib_command))
882237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
882337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
882437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
882537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dl.dylib.name < dl.cmdsize) {
882637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const char *P = (const char *)(Ptr) + dl.dylib.name;
882737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "         name " << P << " (offset " << dl.dylib.name << ")\n";
882837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
882937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "         name ?(bad offset " << dl.dylib.name << ")\n";
883037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
883137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "   time stamp " << dl.dylib.timestamp << " ";
883237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  time_t t = dl.dylib.timestamp;
883337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << ctime(&t);
883437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "      current version ";
883537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dl.dylib.current_version == 0xffffffff)
883637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "n/a\n";
883737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
883837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << ((dl.dylib.current_version >> 16) & 0xffff) << "."
883937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ((dl.dylib.current_version >> 8) & 0xff) << "."
884037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << (dl.dylib.current_version & 0xff) << "\n";
884137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "compatibility version ";
884237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (dl.dylib.compatibility_version == 0xffffffff)
884337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "n/a\n";
884437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
884537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "."
884637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << ((dl.dylib.compatibility_version >> 8) & 0xff) << "."
884737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << (dl.dylib.compatibility_version & 0xff) << "\n";
884837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
884937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
885037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void PrintLinkEditDataCommand(MachO::linkedit_data_command ld,
885137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     uint32_t object_size) {
885237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ld.cmd == MachO::LC_CODE_SIGNATURE)
8853de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    outs() << "      cmd LC_CODE_SIGNATURE\n";
885437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ld.cmd == MachO::LC_SEGMENT_SPLIT_INFO)
885537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_SEGMENT_SPLIT_INFO\n";
885637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ld.cmd == MachO::LC_FUNCTION_STARTS)
885737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_FUNCTION_STARTS\n";
885837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ld.cmd == MachO::LC_DATA_IN_CODE)
885937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_DATA_IN_CODE\n";
886037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ld.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS)
886137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_DYLIB_CODE_SIGN_DRS\n";
886237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ld.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT)
886337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd LC_LINKER_OPTIMIZATION_HINT\n";
886437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
886537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "      cmd " << ld.cmd << " (?)\n";
886637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  cmdsize " << ld.cmdsize;
886737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ld.cmdsize != sizeof(struct MachO::linkedit_data_command))
886837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " Incorrect size\n";
886937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
887037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
887137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "  dataoff " << ld.dataoff;
887237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ld.dataoff > object_size)
887337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
887437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
887537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
887637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << " datasize " << ld.datasize;
887737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t big_size = ld.dataoff;
887837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  big_size += ld.datasize;
887937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (big_size > object_size)
888037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << " (past end of file)\n";
888137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else
888237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
888337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
888437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
88856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
88866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                              uint32_t cputype, bool verbose) {
888737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Buf = Obj->getData();
88886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Index = 0;
88896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  for (const auto &Command : Obj->load_commands()) {
88906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    outs() << "Load command " << Index++ << "\n";
889137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Command.C.cmd == MachO::LC_SEGMENT) {
889237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command SLC = Obj->getSegmentLoadCommand(Command);
889337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const char *sg_segname = SLC.segname;
889437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintSegmentCommand(SLC.cmd, SLC.cmdsize, SLC.segname, SLC.vmaddr,
889537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          SLC.vmsize, SLC.fileoff, SLC.filesize, SLC.maxprot,
889637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          SLC.initprot, SLC.nsects, SLC.flags, Buf.size(),
889737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          verbose);
889837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned j = 0; j < SLC.nsects; j++) {
8899ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        MachO::section S = Obj->getSection(Command, j);
890037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        PrintSection(S.sectname, S.segname, S.addr, S.size, S.offset, S.align,
890137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     S.reloff, S.nreloc, S.flags, S.reserved1, S.reserved2,
890237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     SLC.cmd, sg_segname, filetype, Buf.size(), verbose);
890337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
890437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
890537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::segment_command_64 SLC_64 = Obj->getSegment64LoadCommand(Command);
890637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const char *sg_segname = SLC_64.segname;
890737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintSegmentCommand(SLC_64.cmd, SLC_64.cmdsize, SLC_64.segname,
890837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          SLC_64.vmaddr, SLC_64.vmsize, SLC_64.fileoff,
890937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          SLC_64.filesize, SLC_64.maxprot, SLC_64.initprot,
891037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          SLC_64.nsects, SLC_64.flags, Buf.size(), verbose);
891137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (unsigned j = 0; j < SLC_64.nsects; j++) {
891237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        MachO::section_64 S_64 = Obj->getSection64(Command, j);
891337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        PrintSection(S_64.sectname, S_64.segname, S_64.addr, S_64.size,
891437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     S_64.offset, S_64.align, S_64.reloff, S_64.nreloc,
891537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     S_64.flags, S_64.reserved1, S_64.reserved2, SLC_64.cmd,
891637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     sg_segname, filetype, Buf.size(), verbose);
891737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
891837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_SYMTAB) {
891937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
892037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintSymtabLoadCommand(Symtab, Obj->is64Bit(), Buf.size());
892137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_DYSYMTAB) {
892237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::dysymtab_command Dysymtab = Obj->getDysymtabLoadCommand();
892337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::symtab_command Symtab = Obj->getSymtabLoadCommand();
892437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintDysymtabLoadCommand(Dysymtab, Symtab.nsyms, Buf.size(),
892537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               Obj->is64Bit());
892637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_DYLD_INFO ||
892737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_DYLD_INFO_ONLY) {
892837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::dyld_info_command DyldInfo = Obj->getDyldInfoLoadCommand(Command);
892937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintDyldInfoLoadCommand(DyldInfo, Buf.size());
893037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_LOAD_DYLINKER ||
893137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_ID_DYLINKER ||
893237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_DYLD_ENVIRONMENT) {
893337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::dylinker_command Dyld = Obj->getDylinkerCommand(Command);
893437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintDyldLoadCommand(Dyld, Command.Ptr);
893537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_UUID) {
893637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::uuid_command Uuid = Obj->getUuidCommand(Command);
893737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintUuidLoadCommand(Uuid);
8938ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_RPATH) {
8939ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::rpath_command Rpath = Obj->getRpathCommand(Command);
8940ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintRpathLoadCommand(Rpath, Command.Ptr);
8941ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
8942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               Command.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS ||
8943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               Command.C.cmd == MachO::LC_VERSION_MIN_TVOS ||
8944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               Command.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) {
894537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::version_min_command Vd = Obj->getVersionMinLoadCommand(Command);
894637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintVersionMinLoadCommand(Vd);
894737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
894837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
894937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintSourceVersionCommand(Sd);
895037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_MAIN) {
895137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::entry_point_command Ep = Obj->getEntryPointCommand(Command);
895237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintEntryPointCommand(Ep);
8953ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO) {
8954ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::encryption_info_command Ei =
8955ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Obj->getEncryptionInfoCommand(Command);
8956ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintEncryptionInfoCommand(Ei, Buf.size());
8957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_ENCRYPTION_INFO_64) {
8958ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::encryption_info_command_64 Ei =
8959ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Obj->getEncryptionInfoCommand64(Command);
8960ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintEncryptionInfoCommand64(Ei, Buf.size());
8961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_LINKER_OPTION) {
8962ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::linker_option_command Lo =
8963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Obj->getLinkerOptionLoadCommand(Command);
8964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintLinkerOptionCommand(Lo, Command.Ptr);
8965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_SUB_FRAMEWORK) {
8966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::sub_framework_command Sf = Obj->getSubFrameworkCommand(Command);
8967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintSubFrameworkCommand(Sf, Command.Ptr);
8968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_SUB_UMBRELLA) {
8969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::sub_umbrella_command Sf = Obj->getSubUmbrellaCommand(Command);
8970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintSubUmbrellaCommand(Sf, Command.Ptr);
8971ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_SUB_LIBRARY) {
8972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::sub_library_command Sl = Obj->getSubLibraryCommand(Command);
8973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintSubLibraryCommand(Sl, Command.Ptr);
8974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_SUB_CLIENT) {
8975ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::sub_client_command Sc = Obj->getSubClientCommand(Command);
8976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintSubClientCommand(Sc, Command.Ptr);
8977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_ROUTINES) {
8978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::routines_command Rc = Obj->getRoutinesCommand(Command);
8979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintRoutinesCommand(Rc);
8980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_ROUTINES_64) {
8981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::routines_command_64 Rc = Obj->getRoutinesCommand64(Command);
8982ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintRoutinesCommand64(Rc);
8983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Command.C.cmd == MachO::LC_THREAD ||
8984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines               Command.C.cmd == MachO::LC_UNIXTHREAD) {
8985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      MachO::thread_command Tc = Obj->getThreadCommand(Command);
8986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrintThreadCommand(Tc, Command.Ptr, Obj->isLittleEndian(), cputype);
898737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_LOAD_DYLIB ||
898837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_ID_DYLIB ||
898937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_LOAD_WEAK_DYLIB ||
899037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_REEXPORT_DYLIB ||
899137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_LAZY_LOAD_DYLIB ||
899237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) {
899337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::dylib_command Dl = Obj->getDylibIDLoadCommand(Command);
899437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintDylibCommand(Dl, Command.Ptr);
899537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else if (Command.C.cmd == MachO::LC_CODE_SIGNATURE ||
899637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO ||
899737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_FUNCTION_STARTS ||
899837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_DATA_IN_CODE ||
899937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS ||
900037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines               Command.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) {
900137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      MachO::linkedit_data_command Ld =
900237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Obj->getLinkeditDataLoadCommand(Command);
900337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      PrintLinkEditDataCommand(Ld, Buf.size());
900437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
900537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "      cmd ?(" << format("0x%08" PRIx32, Command.C.cmd)
900637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             << ")\n";
900737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "  cmdsize " << Command.C.cmdsize << "\n";
900837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // TODO: get and print the raw bytes of the load command.
900937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
901037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // TODO: print all the other kinds of load commands.
901137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
901237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
901337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
9014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void PrintMachHeader(const MachOObjectFile *Obj, bool verbose) {
901537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Obj->is64Bit()) {
901637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::mach_header_64 H_64;
901737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    H_64 = Obj->getHeader64();
901837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PrintMachHeader(H_64.magic, H_64.cputype, H_64.cpusubtype, H_64.filetype,
901937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    H_64.ncmds, H_64.sizeofcmds, H_64.flags, verbose);
902037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
902137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::mach_header H;
902237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    H = Obj->getHeader();
902337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PrintMachHeader(H.magic, H.cputype, H.cpusubtype, H.filetype, H.ncmds,
902437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    H.sizeofcmds, H.flags, verbose);
902537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
902637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
902737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
902837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOFileHeader(const object::ObjectFile *Obj) {
902937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
9030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PrintMachHeader(file, !NonVerbose);
9031de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
9032de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
9033de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid llvm::printMachOLoadCommands(const object::ObjectFile *Obj) {
9034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MachOObjectFile *file = dyn_cast<const MachOObjectFile>(Obj);
903537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t filetype = 0;
903637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t cputype = 0;
9037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (file->is64Bit()) {
9038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MachO::mach_header_64 H_64;
9039de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    H_64 = file->getHeader64();
9040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    filetype = H_64.filetype;
9041de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    cputype = H_64.cputype;
9042de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  } else {
9043de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MachO::mach_header H;
9044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    H = file->getHeader();
9045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    filetype = H.filetype;
9046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    cputype = H.cputype;
9047de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
90486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  PrintLoadCommands(file, filetype, cputype, !NonVerbose);
904937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
905037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
905137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
905237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// export trie dumping
905337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
905437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
905537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {
905637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const llvm::object::ExportEntry &Entry : Obj->exports()) {
905737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Flags = Entry.flags();
905837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
905937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool WeakDef = (Flags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
906037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool ThreadLocal = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
906137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                        MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
906237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool Abs = ((Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
906337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
906437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool Resolver = (Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
906537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ReExport)
906637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "[re-export] ";
906737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
906837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << format("0x%08llX  ",
906937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       Entry.address()); // FIXME:add in base address
907037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << Entry.name();
907137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (WeakDef || ThreadLocal || Resolver || Abs) {
907237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      bool NeedsComma = false;
907337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << " [";
907437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (WeakDef) {
907537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "weak_def";
907637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        NeedsComma = true;
907737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
907837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (ThreadLocal) {
907937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (NeedsComma)
908037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          outs() << ", ";
908137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "per-thread";
908237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        NeedsComma = true;
908337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
908437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Abs) {
908537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (NeedsComma)
908637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          outs() << ", ";
908737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << "absolute";
908837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        NeedsComma = true;
908937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
909037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Resolver) {
909137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (NeedsComma)
909237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          outs() << ", ";
909337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << format("resolver=0x%08llX", Entry.other());
909437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        NeedsComma = true;
909537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
909637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "]";
909737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
909837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ReExport) {
909937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      StringRef DylibName = "unknown";
910037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int Ordinal = Entry.other() - 1;
910137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Obj->getLibraryShortNameByIndex(Ordinal, DylibName);
910237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Entry.otherName().empty())
910337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " (from " << DylibName << ")";
910437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
910537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        outs() << " (" << Entry.otherName() << " from " << DylibName << ")";
910637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
910737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << "\n";
910837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
910937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
911037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
911137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
911237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// rebase table dumping
911337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
911437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
911537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace {
911637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass SegInfo {
911737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
911837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SegInfo(const object::MachOObjectFile *Obj);
911937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
912037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef segmentName(uint32_t SegIndex);
912137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef sectionName(uint32_t SegIndex, uint64_t SegOffset);
912237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
9123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isValidSegIndexAndOffset(uint32_t SegIndex, uint64_t SegOffset);
912437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
912537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate:
912637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct SectionInfo {
912737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address;
912837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Size;
912937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectionName;
913037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SegmentName;
913137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OffsetInSegment;
913237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SegmentStartAddress;
913337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SegmentIndex;
913437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  };
913537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const SectionInfo &findSection(uint32_t SegIndex, uint64_t SegOffset);
913637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<SectionInfo, 32> Sections;
913737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
913837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
913937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
914037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesSegInfo::SegInfo(const object::MachOObjectFile *Obj) {
914137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Build table of sections so segIndex/offset pairs can be translated.
914237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0;
914337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef CurSegName;
914437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t CurSegAddress;
914537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
914637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SectionInfo Info;
9147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    error(Section.getName(Info.SectionName));
914837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.Address = Section.getAddress();
914937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.Size = Section.getSize();
915037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.SegmentName =
915137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl());
915237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Info.SegmentName.equals(CurSegName)) {
915337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++CurSegIndex;
915437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurSegName = Info.SegmentName;
915537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CurSegAddress = Info.Address;
915637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
915737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.SegmentIndex = CurSegIndex - 1;
915837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.OffsetInSegment = Info.Address - CurSegAddress;
915937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Info.SegmentStartAddress = CurSegAddress;
916037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Sections.push_back(Info);
916137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
916237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
916337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
916437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesStringRef SegInfo::segmentName(uint32_t SegIndex) {
916537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const SectionInfo &SI : Sections) {
916637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SI.SegmentIndex == SegIndex)
916737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return SI.SegmentName;
916837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
916937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm_unreachable("invalid segIndex");
917037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
917137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
9172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool SegInfo::isValidSegIndexAndOffset(uint32_t SegIndex,
9173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                       uint64_t OffsetInSeg) {
9174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (const SectionInfo &SI : Sections) {
9175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SI.SegmentIndex != SegIndex)
9176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
9177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SI.OffsetInSegment > OffsetInSeg)
9178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
9179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
9180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
9181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
9182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
9183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
9184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
9185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
918637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesconst SegInfo::SectionInfo &SegInfo::findSection(uint32_t SegIndex,
918737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                 uint64_t OffsetInSeg) {
918837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const SectionInfo &SI : Sections) {
918937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SI.SegmentIndex != SegIndex)
919037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
919137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SI.OffsetInSegment > OffsetInSeg)
919237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
919337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (OffsetInSeg >= (SI.OffsetInSegment + SI.Size))
919437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
919537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return SI;
919637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
919737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  llvm_unreachable("segIndex and offset not in any section");
919837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
919937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
920037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesStringRef SegInfo::sectionName(uint32_t SegIndex, uint64_t OffsetInSeg) {
920137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return findSection(SegIndex, OffsetInSeg).SectionName;
920237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
920337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
920437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t SegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) {
920537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const SectionInfo &SI = findSection(SegIndex, OffsetInSeg);
920637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SI.SegmentStartAddress + OffsetInSeg;
920737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
920837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
920937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachORebaseTable(const object::MachOObjectFile *Obj) {
921037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Build table of sections so names can used in final output.
921137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SegInfo sectionTable(Obj);
921237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
921337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "segment  section            address     type\n";
921437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) {
921537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SegIndex = Entry.segmentIndex();
921637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OffsetInSeg = Entry.segmentOffset();
921737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SegmentName = sectionTable.segmentName(SegIndex);
921837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
921937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
922037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
922137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Table lines look like: __DATA  __nl_symbol_ptr  0x0000F00C  pointer
922237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << format("%-8s %-18s 0x%08" PRIX64 "  %s\n",
922337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     SegmentName.str().c_str(), SectionName.str().c_str(),
922437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     Address, Entry.typeName().str().c_str());
922537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
922637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
922737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
922837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic StringRef ordinalName(const object::MachOObjectFile *Obj, int Ordinal) {
922937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef DylibName;
923037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (Ordinal) {
923137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case MachO::BIND_SPECIAL_DYLIB_SELF:
923237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return "this-image";
923337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE:
923437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return "main-executable";
923537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP:
923637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return "flat-namespace";
923737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  default:
923837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Ordinal > 0) {
923937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::error_code EC =
924037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Obj->getLibraryShortNameByIndex(Ordinal - 1, DylibName);
924137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (EC)
924237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return "<<bad library ordinal>>";
924337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return DylibName;
924437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
924537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
924637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return "<<unknown special ordinal>>";
924737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
924837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
924937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
925037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// bind table dumping
925137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
925237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
925337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOBindTable(const object::MachOObjectFile *Obj) {
925437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Build table of sections so names can used in final output.
925537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SegInfo sectionTable(Obj);
925637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
925737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "segment  section            address    type       "
925837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "addend dylib            symbol\n";
925937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) {
926037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SegIndex = Entry.segmentIndex();
926137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OffsetInSeg = Entry.segmentOffset();
926237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SegmentName = sectionTable.segmentName(SegIndex);
926337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
926437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
926537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
926637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Table lines look like:
926737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //  __DATA  __got  0x00012010    pointer   0 libSystem ___stack_chk_guard
926837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef Attr;
926937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_WEAK_IMPORT)
927037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Attr = " (weak_import)";
927137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << left_justify(SegmentName, 8) << " "
927237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(SectionName, 18) << " "
927337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format_hex(Address, 10, true) << " "
927437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(Entry.typeName(), 8) << " "
927537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format_decimal(Entry.addend(), 8) << " "
927637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
927737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << Entry.symbolName() << Attr << "\n";
927837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
927937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
928037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
928137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
928237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// lazy bind table dumping
928337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
928437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
928537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOLazyBindTable(const object::MachOObjectFile *Obj) {
928637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Build table of sections so names can used in final output.
928737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SegInfo sectionTable(Obj);
928837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
928937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "segment  section            address     "
929037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "dylib            symbol\n";
929137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const llvm::object::MachOBindEntry &Entry : Obj->lazyBindTable()) {
929237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SegIndex = Entry.segmentIndex();
929337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OffsetInSeg = Entry.segmentOffset();
929437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SegmentName = sectionTable.segmentName(SegIndex);
929537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
929637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
929737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
929837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Table lines look like:
929937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //  __DATA  __got  0x00012010 libSystem ___stack_chk_guard
930037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << left_justify(SegmentName, 8) << " "
930137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(SectionName, 18) << " "
930237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format_hex(Address, 10, true) << " "
930337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(ordinalName(Obj, Entry.ordinal()), 16) << " "
930437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << Entry.symbolName() << "\n";
930537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
930637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
930737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
930837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
930937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// weak bind table dumping
931037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
931137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
931237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid llvm::printMachOWeakBindTable(const object::MachOObjectFile *Obj) {
931337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Build table of sections so names can used in final output.
931437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SegInfo sectionTable(Obj);
931537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
931637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "segment  section            address     "
931737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "type       addend   symbol\n";
931837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const llvm::object::MachOBindEntry &Entry : Obj->weakBindTable()) {
931937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Strong symbols don't have a location to update.
932037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
932137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      outs() << "                                        strong              "
932237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             << Entry.symbolName() << "\n";
932337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
932437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
932537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t SegIndex = Entry.segmentIndex();
932637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OffsetInSeg = Entry.segmentOffset();
932737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SegmentName = sectionTable.segmentName(SegIndex);
932837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SectionName = sectionTable.sectionName(SegIndex, OffsetInSeg);
932937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
933037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
933137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Table lines look like:
933237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // __DATA  __data  0x00001000  pointer    0   _foo
933337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    outs() << left_justify(SegmentName, 8) << " "
933437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(SectionName, 18) << " "
933537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format_hex(Address, 10, true) << " "
933637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << left_justify(Entry.typeName(), 8) << " "
933737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << format_decimal(Entry.addend(), 8) << "   " << Entry.symbolName()
933837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "\n";
933937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
934037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
934137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
934237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// get_dyld_bind_info_symbolname() is used for disassembly and passed an
934337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// address, ReferenceValue, in the Mach-O file and looks in the dyld bind
934437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// information for that address. If the address is found its binding symbol
934537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// name is returned.  If not nullptr is returned.
934637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
934737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                 struct DisassembleInfo *info) {
934837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (info->bindtable == nullptr) {
934937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    info->bindtable = new (BindTable);
935037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SegInfo sectionTable(info->O);
935137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (const llvm::object::MachOBindEntry &Entry : info->O->bindTable()) {
935237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint32_t SegIndex = Entry.segmentIndex();
935337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t OffsetInSeg = Entry.segmentOffset();
9354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!sectionTable.isValidSegIndexAndOffset(SegIndex, OffsetInSeg))
9355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
935637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t Address = sectionTable.address(SegIndex, OffsetInSeg);
935737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const char *SymbolName = nullptr;
935837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      StringRef name = Entry.symbolName();
935937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!name.empty())
936037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        SymbolName = name.data();
936137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      info->bindtable->push_back(std::make_pair(Address, SymbolName));
936237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
936337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
936437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (bind_table_iterator BI = info->bindtable->begin(),
936537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           BE = info->bindtable->end();
936637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines       BI != BE; ++BI) {
936737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = BI->first;
936837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ReferenceValue == Address) {
936937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const char *SymbolName = BI->second;
937037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return SymbolName;
937137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
937237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
937337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return nullptr;
93740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
9375