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