MachODumper.cpp revision 288943
1249259Sdim//===-- MachODump.cpp - Object file dumping utility for llvm --------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file implements the MachO-specific dumper for llvm-readobj. 11249259Sdim// 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdim#include "llvm-readobj.h" 15249259Sdim#include "Error.h" 16249259Sdim#include "ObjDumper.h" 17288943Sdim#include "StackMapPrinter.h" 18249259Sdim#include "StreamWriter.h" 19249259Sdim#include "llvm/ADT/SmallString.h" 20276479Sdim#include "llvm/ADT/StringExtras.h" 21249259Sdim#include "llvm/Object/MachO.h" 22249259Sdim#include "llvm/Support/Casting.h" 23249259Sdim 24249259Sdimusing namespace llvm; 25249259Sdimusing namespace object; 26249259Sdim 27249259Sdimnamespace { 28249259Sdim 29249259Sdimclass MachODumper : public ObjDumper { 30249259Sdimpublic: 31251662Sdim MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer) 32249259Sdim : ObjDumper(Writer) 33249259Sdim , Obj(Obj) { } 34249259Sdim 35280031Sdim void printFileHeaders() override; 36280031Sdim void printSections() override; 37280031Sdim void printRelocations() override; 38280031Sdim void printSymbols() override; 39280031Sdim void printDynamicSymbols() override; 40280031Sdim void printUnwindInfo() override; 41288943Sdim void printStackMap() const override; 42249259Sdim 43249259Sdimprivate: 44280031Sdim template<class MachHeader> 45280031Sdim void printFileHeaders(const MachHeader &Header); 46280031Sdim 47276479Sdim void printSymbol(const SymbolRef &Symbol); 48249259Sdim 49276479Sdim void printRelocation(const RelocationRef &Reloc); 50249259Sdim 51276479Sdim void printRelocation(const MachOObjectFile *Obj, const RelocationRef &Reloc); 52251662Sdim 53251662Sdim void printSections(const MachOObjectFile *Obj); 54251662Sdim 55251662Sdim const MachOObjectFile *Obj; 56249259Sdim}; 57249259Sdim 58249259Sdim} // namespace 59249259Sdim 60249259Sdim 61249259Sdimnamespace llvm { 62249259Sdim 63276479Sdimstd::error_code createMachODumper(const object::ObjectFile *Obj, 64276479Sdim StreamWriter &Writer, 65276479Sdim std::unique_ptr<ObjDumper> &Result) { 66249259Sdim const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj); 67249259Sdim if (!MachOObj) 68249259Sdim return readobj_error::unsupported_obj_file_format; 69249259Sdim 70249259Sdim Result.reset(new MachODumper(MachOObj, Writer)); 71249259Sdim return readobj_error::success; 72249259Sdim} 73249259Sdim 74249259Sdim} // namespace llvm 75249259Sdim 76280031Sdimstatic const EnumEntry<uint32_t> MachOMagics[] = { 77280031Sdim { "Magic", MachO::MH_MAGIC }, 78280031Sdim { "Cigam", MachO::MH_CIGAM }, 79280031Sdim { "Magic64", MachO::MH_MAGIC_64 }, 80280031Sdim { "Cigam64", MachO::MH_CIGAM_64 }, 81280031Sdim { "FatMagic", MachO::FAT_MAGIC }, 82280031Sdim { "FatCigam", MachO::FAT_CIGAM }, 83280031Sdim}; 84249259Sdim 85280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderFileTypes[] = { 86280031Sdim { "Relocatable", MachO::MH_OBJECT }, 87280031Sdim { "Executable", MachO::MH_EXECUTE }, 88280031Sdim { "FixedVMLibrary", MachO::MH_FVMLIB }, 89280031Sdim { "Core", MachO::MH_CORE }, 90280031Sdim { "PreloadedExecutable", MachO::MH_PRELOAD }, 91280031Sdim { "DynamicLibrary", MachO::MH_DYLIB }, 92280031Sdim { "DynamicLinker", MachO::MH_DYLINKER }, 93280031Sdim { "Bundle", MachO::MH_BUNDLE }, 94280031Sdim { "DynamicLibraryStub", MachO::MH_DYLIB_STUB }, 95280031Sdim { "DWARFSymbol", MachO::MH_DSYM }, 96280031Sdim { "KextBundle", MachO::MH_KEXT_BUNDLE }, 97280031Sdim}; 98280031Sdim 99280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuTypes[] = { 100280031Sdim { "Any" , static_cast<uint32_t>(MachO::CPU_TYPE_ANY) }, 101280031Sdim { "X86" , MachO::CPU_TYPE_X86 }, 102280031Sdim { "X86-64" , MachO::CPU_TYPE_X86_64 }, 103280031Sdim { "Mc98000" , MachO::CPU_TYPE_MC98000 }, 104280031Sdim { "Arm" , MachO::CPU_TYPE_ARM }, 105280031Sdim { "Arm64" , MachO::CPU_TYPE_ARM64 }, 106280031Sdim { "Sparc" , MachO::CPU_TYPE_SPARC }, 107280031Sdim { "PowerPC" , MachO::CPU_TYPE_POWERPC }, 108280031Sdim { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 }, 109280031Sdim}; 110280031Sdim 111280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX86[] = { 112280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_I386_ALL), 113280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_386), 114280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486), 115280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486SX), 116280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_586), 117280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTPRO), 118280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M3), 119280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M5), 120280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON), 121280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON_MOBILE), 122280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3), 123280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_M), 124280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_XEON), 125280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_M), 126280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4), 127280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4_M), 128280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM), 129280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM_2), 130280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON), 131280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON_MP), 132280031Sdim}; 133280031Sdim 134280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesX64[] = { 135280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_ALL), 136280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_ARCH1), 137280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_H), 138280031Sdim}; 139280031Sdim 140280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM[] = { 141280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_ALL), 142280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V4T), 143280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6), 144280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5), 145280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5TEJ), 146280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_XSCALE), 147280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7), 148280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7S), 149280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7K), 150280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6M), 151280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7M), 152280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7EM), 153280031Sdim}; 154280031Sdim 155280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesARM64[] = { 156280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL), 157280031Sdim}; 158280031Sdim 159280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesSPARC[] = { 160280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_SPARC_ALL), 161280031Sdim}; 162280031Sdim 163280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderCpuSubtypesPPC[] = { 164280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_ALL), 165280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_601), 166280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_602), 167280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603), 168280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603e), 169280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603ev), 170280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604), 171280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604e), 172280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_620), 173280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_750), 174280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7400), 175280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7450), 176280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_970), 177280031Sdim}; 178280031Sdim 179280031Sdimstatic const EnumEntry<uint32_t> MachOHeaderFlags[] = { 180280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_NOUNDEFS), 181280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_INCRLINK), 182280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_DYLDLINK), 183280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDATLOAD), 184280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBOUND), 185280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_SPLIT_SEGS), 186280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_LAZY_INIT), 187280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_TWOLEVEL), 188280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_FORCE_FLAT), 189280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_NOMULTIDEFS), 190280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_NOFIXPREBINDING), 191280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBINDABLE), 192280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLMODSBOUND), 193280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_SUBSECTIONS_VIA_SYMBOLS), 194280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_CANONICAL), 195280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_WEAK_DEFINES), 196280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDS_TO_WEAK), 197280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLOW_STACK_EXECUTION), 198280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_ROOT_SAFE), 199280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_SETUID_SAFE), 200280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_REEXPORTED_DYLIBS), 201280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_PIE), 202280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_DEAD_STRIPPABLE_DYLIB), 203280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_HAS_TLV_DESCRIPTORS), 204280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_HEAP_EXECUTION), 205280031Sdim LLVM_READOBJ_ENUM_ENT(MachO, MH_APP_EXTENSION_SAFE), 206280031Sdim}; 207280031Sdim 208249259Sdimstatic const EnumEntry<unsigned> MachOSectionAttributes[] = { 209249259Sdim { "LocReloc" , 1 << 0 /*S_ATTR_LOC_RELOC */ }, 210249259Sdim { "ExtReloc" , 1 << 1 /*S_ATTR_EXT_RELOC */ }, 211249259Sdim { "SomeInstructions" , 1 << 2 /*S_ATTR_SOME_INSTRUCTIONS */ }, 212249259Sdim { "Debug" , 1 << 17 /*S_ATTR_DEBUG */ }, 213249259Sdim { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ }, 214249259Sdim { "LiveSupport" , 1 << 19 /*S_ATTR_LIVE_SUPPORT */ }, 215249259Sdim { "NoDeadStrip" , 1 << 20 /*S_ATTR_NO_DEAD_STRIP */ }, 216249259Sdim { "StripStaticSyms" , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS */ }, 217249259Sdim { "NoTOC" , 1 << 22 /*S_ATTR_NO_TOC */ }, 218249259Sdim { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS */ }, 219249259Sdim}; 220249259Sdim 221249259Sdimstatic const EnumEntry<unsigned> MachOSymbolRefTypes[] = { 222249259Sdim { "UndefinedNonLazy", 0 }, 223249259Sdim { "ReferenceFlagUndefinedLazy", 1 }, 224249259Sdim { "ReferenceFlagDefined", 2 }, 225249259Sdim { "ReferenceFlagPrivateDefined", 3 }, 226249259Sdim { "ReferenceFlagPrivateUndefinedNonLazy", 4 }, 227249259Sdim { "ReferenceFlagPrivateUndefinedLazy", 5 } 228249259Sdim}; 229249259Sdim 230249259Sdimstatic const EnumEntry<unsigned> MachOSymbolFlags[] = { 231249259Sdim { "ReferencedDynamically", 0x10 }, 232249259Sdim { "NoDeadStrip", 0x20 }, 233249259Sdim { "WeakRef", 0x40 }, 234249259Sdim { "WeakDef", 0x80 } 235249259Sdim}; 236249259Sdim 237249259Sdimstatic const EnumEntry<unsigned> MachOSymbolTypes[] = { 238249259Sdim { "Undef", 0x0 }, 239249259Sdim { "Abs", 0x2 }, 240249259Sdim { "Indirect", 0xA }, 241249259Sdim { "PreboundUndef", 0xC }, 242276479Sdim { "Section", 0xE } 243249259Sdim}; 244249259Sdim 245249259Sdimnamespace { 246249259Sdim struct MachOSection { 247249259Sdim ArrayRef<char> Name; 248249259Sdim ArrayRef<char> SegmentName; 249249259Sdim uint64_t Address; 250249259Sdim uint64_t Size; 251249259Sdim uint32_t Offset; 252249259Sdim uint32_t Alignment; 253249259Sdim uint32_t RelocationTableOffset; 254249259Sdim uint32_t NumRelocationTableEntries; 255249259Sdim uint32_t Flags; 256249259Sdim uint32_t Reserved1; 257249259Sdim uint32_t Reserved2; 258249259Sdim }; 259249259Sdim 260249259Sdim struct MachOSymbol { 261249259Sdim uint32_t StringIndex; 262249259Sdim uint8_t Type; 263249259Sdim uint8_t SectionIndex; 264249259Sdim uint16_t Flags; 265249259Sdim uint64_t Value; 266249259Sdim }; 267249259Sdim} 268249259Sdim 269251662Sdimstatic void getSection(const MachOObjectFile *Obj, 270251662Sdim DataRefImpl Sec, 271249259Sdim MachOSection &Section) { 272251662Sdim if (!Obj->is64Bit()) { 273261991Sdim MachO::section Sect = Obj->getSection(Sec); 274261991Sdim Section.Address = Sect.addr; 275261991Sdim Section.Size = Sect.size; 276261991Sdim Section.Offset = Sect.offset; 277261991Sdim Section.Alignment = Sect.align; 278261991Sdim Section.RelocationTableOffset = Sect.reloff; 279261991Sdim Section.NumRelocationTableEntries = Sect.nreloc; 280261991Sdim Section.Flags = Sect.flags; 281261991Sdim Section.Reserved1 = Sect.reserved1; 282261991Sdim Section.Reserved2 = Sect.reserved2; 283251662Sdim return; 284249259Sdim } 285261991Sdim MachO::section_64 Sect = Obj->getSection64(Sec); 286261991Sdim Section.Address = Sect.addr; 287261991Sdim Section.Size = Sect.size; 288261991Sdim Section.Offset = Sect.offset; 289261991Sdim Section.Alignment = Sect.align; 290261991Sdim Section.RelocationTableOffset = Sect.reloff; 291261991Sdim Section.NumRelocationTableEntries = Sect.nreloc; 292261991Sdim Section.Flags = Sect.flags; 293261991Sdim Section.Reserved1 = Sect.reserved1; 294261991Sdim Section.Reserved2 = Sect.reserved2; 295249259Sdim} 296249259Sdim 297249259Sdim 298251662Sdimstatic void getSymbol(const MachOObjectFile *Obj, 299249259Sdim DataRefImpl DRI, 300249259Sdim MachOSymbol &Symbol) { 301251662Sdim if (!Obj->is64Bit()) { 302261991Sdim MachO::nlist Entry = Obj->getSymbolTableEntry(DRI); 303261991Sdim Symbol.StringIndex = Entry.n_strx; 304261991Sdim Symbol.Type = Entry.n_type; 305261991Sdim Symbol.SectionIndex = Entry.n_sect; 306261991Sdim Symbol.Flags = Entry.n_desc; 307261991Sdim Symbol.Value = Entry.n_value; 308251662Sdim return; 309249259Sdim } 310261991Sdim MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI); 311261991Sdim Symbol.StringIndex = Entry.n_strx; 312261991Sdim Symbol.Type = Entry.n_type; 313261991Sdim Symbol.SectionIndex = Entry.n_sect; 314261991Sdim Symbol.Flags = Entry.n_desc; 315261991Sdim Symbol.Value = Entry.n_value; 316249259Sdim} 317249259Sdim 318249259Sdimvoid MachODumper::printFileHeaders() { 319280031Sdim DictScope H(W, "MachHeader"); 320280031Sdim if (!Obj->is64Bit()) { 321280031Sdim printFileHeaders(Obj->getHeader()); 322280031Sdim } else { 323280031Sdim printFileHeaders(Obj->getHeader64()); 324280031Sdim W.printHex("Reserved", Obj->getHeader64().reserved); 325280031Sdim } 326249259Sdim} 327249259Sdim 328280031Sdimtemplate<class MachHeader> 329280031Sdimvoid MachODumper::printFileHeaders(const MachHeader &Header) { 330280031Sdim W.printEnum("Magic", Header.magic, makeArrayRef(MachOMagics)); 331280031Sdim W.printEnum("CpuType", Header.cputype, makeArrayRef(MachOHeaderCpuTypes)); 332280031Sdim uint32_t subtype = Header.cpusubtype & ~MachO::CPU_SUBTYPE_MASK; 333280031Sdim switch (Header.cputype) { 334280031Sdim case MachO::CPU_TYPE_X86: 335280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX86)); 336280031Sdim break; 337280031Sdim case MachO::CPU_TYPE_X86_64: 338280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX64)); 339280031Sdim break; 340280031Sdim case MachO::CPU_TYPE_ARM: 341280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM)); 342280031Sdim break; 343280031Sdim case MachO::CPU_TYPE_POWERPC: 344280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesPPC)); 345280031Sdim break; 346280031Sdim case MachO::CPU_TYPE_SPARC: 347280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesSPARC)); 348280031Sdim break; 349280031Sdim case MachO::CPU_TYPE_ARM64: 350280031Sdim W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM64)); 351280031Sdim break; 352280031Sdim case MachO::CPU_TYPE_POWERPC64: 353280031Sdim default: 354280031Sdim W.printHex("CpuSubtype", subtype); 355280031Sdim } 356280031Sdim W.printEnum("FileType", Header.filetype, makeArrayRef(MachOHeaderFileTypes)); 357280031Sdim W.printNumber("NumOfLoadCommands", Header.ncmds); 358280031Sdim W.printNumber("SizeOfLoadCommands", Header.sizeofcmds); 359280031Sdim W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags)); 360280031Sdim} 361280031Sdim 362249259Sdimvoid MachODumper::printSections() { 363251662Sdim return printSections(Obj); 364251662Sdim} 365251662Sdim 366251662Sdimvoid MachODumper::printSections(const MachOObjectFile *Obj) { 367249259Sdim ListScope Group(W, "Sections"); 368249259Sdim 369249259Sdim int SectionIndex = -1; 370276479Sdim for (const SectionRef &Section : Obj->sections()) { 371249259Sdim ++SectionIndex; 372249259Sdim 373276479Sdim MachOSection MOSection; 374276479Sdim getSection(Obj, Section.getRawDataRefImpl(), MOSection); 375276479Sdim DataRefImpl DR = Section.getRawDataRefImpl(); 376249259Sdim 377249259Sdim StringRef Name; 378276479Sdim if (error(Section.getName(Name))) 379276479Sdim Name = ""; 380249259Sdim 381251662Sdim ArrayRef<char> RawName = Obj->getSectionRawName(DR); 382251662Sdim StringRef SegmentName = Obj->getSectionFinalSegmentName(DR); 383251662Sdim ArrayRef<char> RawSegmentName = Obj->getSectionRawFinalSegmentName(DR); 384251662Sdim 385249259Sdim DictScope SectionD(W, "Section"); 386249259Sdim W.printNumber("Index", SectionIndex); 387251662Sdim W.printBinary("Name", Name, RawName); 388251662Sdim W.printBinary("Segment", SegmentName, RawSegmentName); 389276479Sdim W.printHex("Address", MOSection.Address); 390276479Sdim W.printHex("Size", MOSection.Size); 391276479Sdim W.printNumber("Offset", MOSection.Offset); 392276479Sdim W.printNumber("Alignment", MOSection.Alignment); 393276479Sdim W.printHex("RelocationOffset", MOSection.RelocationTableOffset); 394276479Sdim W.printNumber("RelocationCount", MOSection.NumRelocationTableEntries); 395276479Sdim W.printEnum("Type", MOSection.Flags & 0xFF, 396276479Sdim makeArrayRef(MachOSectionAttributes)); 397276479Sdim W.printFlags("Attributes", MOSection.Flags >> 8, 398276479Sdim makeArrayRef(MachOSectionAttributes)); 399276479Sdim W.printHex("Reserved1", MOSection.Reserved1); 400276479Sdim W.printHex("Reserved2", MOSection.Reserved2); 401249259Sdim 402249259Sdim if (opts::SectionRelocations) { 403249259Sdim ListScope D(W, "Relocations"); 404276479Sdim for (const RelocationRef &Reloc : Section.relocations()) 405276479Sdim printRelocation(Reloc); 406249259Sdim } 407249259Sdim 408249259Sdim if (opts::SectionSymbols) { 409249259Sdim ListScope D(W, "Symbols"); 410276479Sdim for (const SymbolRef &Symbol : Obj->symbols()) { 411280031Sdim if (!Section.containsSymbol(Symbol)) 412249259Sdim continue; 413249259Sdim 414276479Sdim printSymbol(Symbol); 415249259Sdim } 416249259Sdim } 417249259Sdim 418249259Sdim if (opts::SectionData) { 419280031Sdim bool IsBSS = Section.isBSS(); 420280031Sdim if (!IsBSS) { 421280031Sdim StringRef Data; 422280031Sdim if (error(Section.getContents(Data))) 423280031Sdim break; 424249259Sdim 425280031Sdim W.printBinaryBlock("SectionData", Data); 426280031Sdim } 427249259Sdim } 428249259Sdim } 429249259Sdim} 430249259Sdim 431249259Sdimvoid MachODumper::printRelocations() { 432249259Sdim ListScope D(W, "Relocations"); 433249259Sdim 434276479Sdim std::error_code EC; 435276479Sdim for (const SectionRef &Section : Obj->sections()) { 436249259Sdim StringRef Name; 437276479Sdim if (error(Section.getName(Name))) 438249259Sdim continue; 439249259Sdim 440249259Sdim bool PrintedGroup = false; 441276479Sdim for (const RelocationRef &Reloc : Section.relocations()) { 442249259Sdim if (!PrintedGroup) { 443249259Sdim W.startLine() << "Section " << Name << " {\n"; 444249259Sdim W.indent(); 445249259Sdim PrintedGroup = true; 446249259Sdim } 447249259Sdim 448276479Sdim printRelocation(Reloc); 449249259Sdim } 450249259Sdim 451249259Sdim if (PrintedGroup) { 452249259Sdim W.unindent(); 453249259Sdim W.startLine() << "}\n"; 454249259Sdim } 455249259Sdim } 456249259Sdim} 457249259Sdim 458276479Sdimvoid MachODumper::printRelocation(const RelocationRef &Reloc) { 459276479Sdim return printRelocation(Obj, Reloc); 460251662Sdim} 461251662Sdim 462251662Sdimvoid MachODumper::printRelocation(const MachOObjectFile *Obj, 463276479Sdim const RelocationRef &Reloc) { 464288943Sdim uint64_t Offset = Reloc.getOffset(); 465249259Sdim SmallString<32> RelocName; 466288943Sdim Reloc.getTypeName(RelocName); 467249259Sdim 468276479Sdim DataRefImpl DR = Reloc.getRawDataRefImpl(); 469261991Sdim MachO::any_relocation_info RE = Obj->getRelocation(DR); 470251662Sdim bool IsScattered = Obj->isRelocationScattered(RE); 471288943Sdim bool IsExtern = !IsScattered && Obj->getPlainRelocationExternal(RE); 472288943Sdim 473288943Sdim StringRef TargetName; 474288943Sdim if (IsExtern) { 475276479Sdim symbol_iterator Symbol = Reloc.getSymbol(); 476276479Sdim if (Symbol != Obj->symbol_end()) { 477288943Sdim ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); 478288943Sdim if (error(TargetNameOrErr.getError())) 479276479Sdim return; 480288943Sdim TargetName = *TargetNameOrErr; 481288943Sdim } 482288943Sdim } else if (!IsScattered) { 483288943Sdim section_iterator SecI = Obj->getRelocationSection(DR); 484288943Sdim if (SecI != Obj->section_end()) { 485288943Sdim if (error(SecI->getName(TargetName))) 486288943Sdim return; 487288943Sdim } 488276479Sdim } 489288943Sdim if (TargetName.empty()) 490288943Sdim TargetName = "-"; 491251662Sdim 492251662Sdim if (opts::ExpandRelocs) { 493251662Sdim DictScope Group(W, "Relocation"); 494251662Sdim W.printHex("Offset", Offset); 495251662Sdim W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE)); 496251662Sdim W.printNumber("Length", Obj->getAnyRelocationLength(RE)); 497251662Sdim W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE)); 498288943Sdim if (IsScattered) { 499288943Sdim W.printHex("Value", Obj->getScatteredRelocationValue(RE)); 500288943Sdim } else { 501288943Sdim const char *Kind = IsExtern ? "Symbol" : "Section"; 502288943Sdim W.printNumber(Kind, TargetName, Obj->getPlainRelocationSymbolNum(RE)); 503288943Sdim } 504251662Sdim } else { 505288943Sdim SmallString<32> SymbolNameOrOffset("0x"); 506288943Sdim if (IsScattered) { 507288943Sdim // Scattered relocations don't really have an associated symbol for some 508288943Sdim // reason, even if one exists in the symtab at the correct address. 509288943Sdim SymbolNameOrOffset += utohexstr(Obj->getScatteredRelocationValue(RE)); 510288943Sdim } else { 511288943Sdim SymbolNameOrOffset = TargetName; 512288943Sdim } 513288943Sdim 514251662Sdim raw_ostream& OS = W.startLine(); 515251662Sdim OS << W.hex(Offset) 516251662Sdim << " " << Obj->getAnyRelocationPCRel(RE) 517251662Sdim << " " << Obj->getAnyRelocationLength(RE); 518251662Sdim if (IsScattered) 519251662Sdim OS << " n/a"; 520251662Sdim else 521251662Sdim OS << " " << Obj->getPlainRelocationExternal(RE); 522251662Sdim OS << " " << RelocName 523251662Sdim << " " << IsScattered 524276479Sdim << " " << SymbolNameOrOffset 525251662Sdim << "\n"; 526251662Sdim } 527249259Sdim} 528249259Sdim 529249259Sdimvoid MachODumper::printSymbols() { 530249259Sdim ListScope Group(W, "Symbols"); 531249259Sdim 532276479Sdim for (const SymbolRef &Symbol : Obj->symbols()) { 533276479Sdim printSymbol(Symbol); 534249259Sdim } 535249259Sdim} 536249259Sdim 537249259Sdimvoid MachODumper::printDynamicSymbols() { 538249259Sdim ListScope Group(W, "DynamicSymbols"); 539249259Sdim} 540249259Sdim 541276479Sdimvoid MachODumper::printSymbol(const SymbolRef &Symbol) { 542249259Sdim StringRef SymbolName; 543288943Sdim if (ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName()) 544288943Sdim SymbolName = *SymbolNameOrErr; 545249259Sdim 546276479Sdim MachOSymbol MOSymbol; 547276479Sdim getSymbol(Obj, Symbol.getRawDataRefImpl(), MOSymbol); 548249259Sdim 549251662Sdim StringRef SectionName = ""; 550276479Sdim section_iterator SecI(Obj->section_begin()); 551276479Sdim if (!error(Symbol.getSection(SecI)) && SecI != Obj->section_end()) 552276479Sdim error(SecI->getName(SectionName)); 553249259Sdim 554249259Sdim DictScope D(W, "Symbol"); 555276479Sdim W.printNumber("Name", SymbolName, MOSymbol.StringIndex); 556276479Sdim if (MOSymbol.Type & MachO::N_STAB) { 557276479Sdim W.printHex("Type", "SymDebugTable", MOSymbol.Type); 558249259Sdim } else { 559276479Sdim if (MOSymbol.Type & MachO::N_PEXT) 560276479Sdim W.startLine() << "PrivateExtern\n"; 561276479Sdim if (MOSymbol.Type & MachO::N_EXT) 562276479Sdim W.startLine() << "Extern\n"; 563276479Sdim W.printEnum("Type", uint8_t(MOSymbol.Type & MachO::N_TYPE), 564276479Sdim makeArrayRef(MachOSymbolTypes)); 565249259Sdim } 566276479Sdim W.printHex("Section", SectionName, MOSymbol.SectionIndex); 567276479Sdim W.printEnum("RefType", static_cast<uint16_t>(MOSymbol.Flags & 0xF), 568276479Sdim makeArrayRef(MachOSymbolRefTypes)); 569276479Sdim W.printFlags("Flags", static_cast<uint16_t>(MOSymbol.Flags & ~0xF), 570276479Sdim makeArrayRef(MachOSymbolFlags)); 571276479Sdim W.printHex("Value", MOSymbol.Value); 572249259Sdim} 573249259Sdim 574249259Sdimvoid MachODumper::printUnwindInfo() { 575249259Sdim W.startLine() << "UnwindInfo not implemented.\n"; 576249259Sdim} 577288943Sdim 578288943Sdimvoid MachODumper::printStackMap() const { 579288943Sdim object::SectionRef StackMapSection; 580288943Sdim for (auto Sec : Obj->sections()) { 581288943Sdim StringRef Name; 582288943Sdim Sec.getName(Name); 583288943Sdim if (Name == "__llvm_stackmaps") { 584288943Sdim StackMapSection = Sec; 585288943Sdim break; 586288943Sdim } 587288943Sdim } 588288943Sdim 589288943Sdim if (StackMapSection == object::SectionRef()) 590288943Sdim return; 591288943Sdim 592288943Sdim StringRef StackMapContents; 593288943Sdim StackMapSection.getContents(StackMapContents); 594288943Sdim ArrayRef<uint8_t> StackMapContentsArray( 595288943Sdim reinterpret_cast<const uint8_t*>(StackMapContents.data()), 596288943Sdim StackMapContents.size()); 597288943Sdim 598288943Sdim if (Obj->isLittleEndian()) 599288943Sdim prettyPrintStackMap( 600288943Sdim llvm::outs(), 601288943Sdim StackMapV1Parser<support::little>(StackMapContentsArray)); 602288943Sdim else 603288943Sdim prettyPrintStackMap(llvm::outs(), 604288943Sdim StackMapV1Parser<support::big>(StackMapContentsArray)); 605288943Sdim} 606