Index: llvm/trunk/test/tools/llvm-readobj/file-headers.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/file-headers.test +++ llvm/trunk/test/tools/llvm-readobj/file-headers.test @@ -10,6 +10,16 @@ RUN: | FileCheck %s -check-prefix ELF32 RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-x86-64 \ RUN: | FileCheck %s -check-prefix ELF64 +RUN: llvm-readobj -h %p/Inputs/trivial.obj.macho-i386 \ +RUN: | FileCheck %s -check-prefix MACHO32 +RUN: llvm-readobj -h %p/Inputs/trivial.obj.macho-x86-64 \ +RUN: | FileCheck %s -check-prefix MACHO64 +RUN: llvm-readobj -h %p/Inputs/trivial.obj.macho-ppc \ +RUN: | FileCheck %s -check-prefix MACHO-PPC +RUN: llvm-readobj -h %p/Inputs/trivial.obj.macho-ppc64 \ +RUN: | FileCheck %s -check-prefix MACHO-PPC64 +RUN: llvm-readobj -h %p/Inputs/trivial.obj.macho-arm \ +RUN: | FileCheck %s -check-prefix MACHO-ARM RUN: llvm-readobj -h %p/Inputs/magic.coff-unknown \ RUN: | FileCheck %s -check-prefix COFF-UNKNOWN RUN: llvm-readobj -h %p/Inputs/magic.coff-importlib \ @@ -122,6 +132,88 @@ ELF64-NEXT: StringTableSectionIndex: 7 ELF64-NEXT: } +MACHO32: File: {{(.*[/\\])?}}trivial.obj.macho-i386 +MACHO32-NEXT: Format: Mach-O 32-bit i386 +MACHO32-NEXT: Arch: i386 +MACHO32-NEXT: AddressSize: 32bit +MACHO32-NEXT: MachHeader { +MACHO32-NEXT: Magic: Magic (0xFEEDFACE) +MACHO32-NEXT: CpuType: X86 (0x7) +MACHO32-NEXT: CpuSubType: CPU_SUBTYPE_I386_ALL (0x3) +MACHO32-NEXT: FileType: Relocatable (0x1) +MACHO32-NEXT: NumOfLoadCommands: 3 +MACHO32-NEXT: SizeOfLoadCommands: 296 +MACHO32-NEXT: Flags [ (0x2000) +MACHO32-NEXT: MH_SUBSECTIONS_VIA_SYMBOLS (0x2000) +MACHO32-NEXT: ] +MACHO32-NEXT: } + +MACHO64: File: {{(.*[/\\])?}}trivial.obj.macho-x86-64 +MACHO64-NEXT: Format: Mach-O 64-bit x86-64 +MACHO64-NEXT: Arch: x86_64 +MACHO64-NEXT: AddressSize: 64bit +MACHO64-NEXT: MachHeader { +MACHO64-NEXT: Magic: Magic64 (0xFEEDFACF) +MACHO64-NEXT: CpuType: X86-64 (0x1000007) +MACHO64-NEXT: CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3) +MACHO64-NEXT: FileType: Relocatable (0x1) +MACHO64-NEXT: NumOfLoadCommands: 3 +MACHO64-NEXT: SizeOfLoadCommands: 336 +MACHO64-NEXT: Flags [ (0x2000) +MACHO64-NEXT: MH_SUBSECTIONS_VIA_SYMBOLS (0x2000) +MACHO64-NEXT: ] +MACHO64-NEXT: Reserved: 0x0 +MACHO64-NEXT: } + +MACHO-PPC: File: {{(.*[/\\])?}}trivial.obj.macho-ppc +MACHO-PPC-NEXT: Format: Mach-O 32-bit ppc +MACHO-PPC-NEXT: Arch: powerpc +MACHO-PPC-NEXT: AddressSize: 32bit +MACHO-PPC-NEXT: MachHeader { +MACHO-PPC-NEXT: Magic: Magic (0xFEEDFACE) +MACHO-PPC-NEXT: CpuType: PowerPC (0x12) +MACHO-PPC-NEXT: CpuSubType: CPU_SUBTYPE_POWERPC_ALL (0x0) +MACHO-PPC-NEXT: FileType: Relocatable (0x1) +MACHO-PPC-NEXT: NumOfLoadCommands: 3 +MACHO-PPC-NEXT: SizeOfLoadCommands: 500 +MACHO-PPC-NEXT: Flags [ (0x2000) +MACHO-PPC-NEXT: MH_SUBSECTIONS_VIA_SYMBOLS (0x2000) +MACHO-PPC-NEXT: ] +MACHO-PPC-NEXT: } + +MACHO-PPC64: File: {{(.*[/\\])?}}trivial.obj.macho-ppc64 +MACHO-PPC64-NEXT: Format: Mach-O 64-bit ppc64 +MACHO-PPC64-NEXT: Arch: powerpc64 +MACHO-PPC64-NEXT: AddressSize: 64bit +MACHO-PPC64-NEXT: MachHeader { +MACHO-PPC64-NEXT: Magic: Magic64 (0xFEEDFACF) +MACHO-PPC64-NEXT: CpuType: PowerPC64 (0x1000012) +MACHO-PPC64-NEXT: CpuSubtype: 0x0 +MACHO-PPC64-NEXT: FileType: Relocatable (0x1) +MACHO-PPC64-NEXT: NumOfLoadCommands: 3 +MACHO-PPC64-NEXT: SizeOfLoadCommands: 576 +MACHO-PPC64-NEXT: Flags [ (0x2000) +MACHO-PPC64-NEXT: MH_SUBSECTIONS_VIA_SYMBOLS (0x2000) +MACHO-PPC64-NEXT: ] +MACHO-PPC64-NEXT: Reserved: 0x0 +MACHO-PPC64-NEXT: } + +MACHO-ARM: File: {{(.*[/\\])?}}trivial.obj.macho-arm +MACHO-ARM-NEXT: Format: Mach-O arm +MACHO-ARM-NEXT: Arch: arm +MACHO-ARM-NEXT: AddressSize: 32bit +MACHO-ARM-NEXT: MachHeader { +MACHO-ARM-NEXT: Magic: Magic (0xFEEDFACE) +MACHO-ARM-NEXT: CpuType: Arm (0xC) +MACHO-ARM-NEXT: CpuSubType: CPU_SUBTYPE_ARM_V7 (0x9) +MACHO-ARM-NEXT: FileType: Relocatable (0x1) +MACHO-ARM-NEXT: NumOfLoadCommands: 3 +MACHO-ARM-NEXT: SizeOfLoadCommands: 636 +MACHO-ARM-NEXT: Flags [ (0x2000) +MACHO-ARM-NEXT: MH_SUBSECTIONS_VIA_SYMBOLS (0x2000) +MACHO-ARM-NEXT: ] +MACHO-ARM-NEXT: } + PE32: File: {{(.*[/\\])?}}trivial.exe.coff-i386 PE32-NEXT: Format: COFF-i386 PE32-NEXT: Arch: i386 Index: llvm/trunk/tools/llvm-readobj/MachODumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/MachODumper.cpp +++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp @@ -39,6 +39,9 @@ void printUnwindInfo() override; private: + template + void printFileHeaders(const MachHeader &Header); + void printSymbol(const SymbolRef &Symbol); void printRelocation(const RelocationRef &Reloc); @@ -68,6 +71,137 @@ } // namespace llvm +static const EnumEntry MachOMagics[] = { + { "Magic", MachO::MH_MAGIC }, + { "Cigam", MachO::MH_CIGAM }, + { "Magic64", MachO::MH_MAGIC_64 }, + { "Cigam64", MachO::MH_CIGAM_64 }, + { "FatMagic", MachO::FAT_MAGIC }, + { "FatCigam", MachO::FAT_CIGAM }, +}; + +static const EnumEntry MachOHeaderFileTypes[] = { + { "Relocatable", MachO::MH_OBJECT }, + { "Executable", MachO::MH_EXECUTE }, + { "FixedVMLibrary", MachO::MH_FVMLIB }, + { "Core", MachO::MH_CORE }, + { "PreloadedExecutable", MachO::MH_PRELOAD }, + { "DynamicLibrary", MachO::MH_DYLIB }, + { "DynamicLinker", MachO::MH_DYLINKER }, + { "Bundle", MachO::MH_BUNDLE }, + { "DynamicLibraryStub", MachO::MH_DYLIB_STUB }, + { "DWARFSymbol", MachO::MH_DSYM }, + { "KextBundle", MachO::MH_KEXT_BUNDLE }, +}; + +static const EnumEntry MachOHeaderCpuTypes[] = { + { "Any" , static_cast(MachO::CPU_TYPE_ANY) }, + { "X86" , MachO::CPU_TYPE_X86 }, + { "X86-64" , MachO::CPU_TYPE_X86_64 }, + { "Mc98000" , MachO::CPU_TYPE_MC98000 }, + { "Arm" , MachO::CPU_TYPE_ARM }, + { "Arm64" , MachO::CPU_TYPE_ARM64 }, + { "Sparc" , MachO::CPU_TYPE_SPARC }, + { "PowerPC" , MachO::CPU_TYPE_POWERPC }, + { "PowerPC64" , MachO::CPU_TYPE_POWERPC64 }, +}; + +static const EnumEntry MachOHeaderCpuSubtypesX86[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_I386_ALL), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_386), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_486SX), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_586), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTPRO), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M3), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTII_M5), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_CELERON_MOBILE), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_M), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_3_XEON), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_M), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_PENTIUM_4_M), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ITANIUM_2), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_XEON_MP), +}; + +static const EnumEntry MachOHeaderCpuSubtypesX64[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_ALL), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_ARCH1), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_X86_64_H), +}; + +static const EnumEntry MachOHeaderCpuSubtypesARM[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_ALL), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V4T), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V5TEJ), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_XSCALE), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7S), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7K), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V6M), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7M), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM_V7EM), +}; + +static const EnumEntry MachOHeaderCpuSubtypesARM64[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL), +}; + +static const EnumEntry MachOHeaderCpuSubtypesSPARC[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_SPARC_ALL), +}; + +static const EnumEntry MachOHeaderCpuSubtypesPPC[] = { + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_ALL), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_601), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_602), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603e), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_603ev), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_604e), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_620), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_750), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7400), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_7450), + LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_POWERPC_970), +}; + +static const EnumEntry MachOHeaderFlags[] = { + LLVM_READOBJ_ENUM_ENT(MachO, MH_NOUNDEFS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_INCRLINK), + LLVM_READOBJ_ENUM_ENT(MachO, MH_DYLDLINK), + LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDATLOAD), + LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBOUND), + LLVM_READOBJ_ENUM_ENT(MachO, MH_SPLIT_SEGS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_LAZY_INIT), + LLVM_READOBJ_ENUM_ENT(MachO, MH_TWOLEVEL), + LLVM_READOBJ_ENUM_ENT(MachO, MH_FORCE_FLAT), + LLVM_READOBJ_ENUM_ENT(MachO, MH_NOMULTIDEFS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_NOFIXPREBINDING), + LLVM_READOBJ_ENUM_ENT(MachO, MH_PREBINDABLE), + LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLMODSBOUND), + LLVM_READOBJ_ENUM_ENT(MachO, MH_SUBSECTIONS_VIA_SYMBOLS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_CANONICAL), + LLVM_READOBJ_ENUM_ENT(MachO, MH_WEAK_DEFINES), + LLVM_READOBJ_ENUM_ENT(MachO, MH_BINDS_TO_WEAK), + LLVM_READOBJ_ENUM_ENT(MachO, MH_ALLOW_STACK_EXECUTION), + LLVM_READOBJ_ENUM_ENT(MachO, MH_ROOT_SAFE), + LLVM_READOBJ_ENUM_ENT(MachO, MH_SETUID_SAFE), + LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_REEXPORTED_DYLIBS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_PIE), + LLVM_READOBJ_ENUM_ENT(MachO, MH_DEAD_STRIPPABLE_DYLIB), + LLVM_READOBJ_ENUM_ENT(MachO, MH_HAS_TLV_DESCRIPTORS), + LLVM_READOBJ_ENUM_ENT(MachO, MH_NO_HEAP_EXECUTION), + LLVM_READOBJ_ENUM_ENT(MachO, MH_APP_EXTENSION_SAFE), +}; static const EnumEntry MachOSectionTypes[] = { { "Regular" , 0x00 }, @@ -205,7 +339,47 @@ } void MachODumper::printFileHeaders() { - W.startLine() << "FileHeaders not implemented.\n"; + DictScope H(W, "MachHeader"); + if (!Obj->is64Bit()) { + printFileHeaders(Obj->getHeader()); + } else { + printFileHeaders(Obj->getHeader64()); + W.printHex("Reserved", Obj->getHeader64().reserved); + } +} + +template +void MachODumper::printFileHeaders(const MachHeader &Header) { + W.printEnum("Magic", Header.magic, makeArrayRef(MachOMagics)); + W.printEnum("CpuType", Header.cputype, makeArrayRef(MachOHeaderCpuTypes)); + uint32_t subtype = Header.cpusubtype & ~MachO::CPU_SUBTYPE_MASK; + switch (Header.cputype) { + case MachO::CPU_TYPE_X86: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX86)); + break; + case MachO::CPU_TYPE_X86_64: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX64)); + break; + case MachO::CPU_TYPE_ARM: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM)); + break; + case MachO::CPU_TYPE_POWERPC: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesPPC)); + break; + case MachO::CPU_TYPE_SPARC: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesSPARC)); + break; + case MachO::CPU_TYPE_ARM64: + W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM64)); + break; + case MachO::CPU_TYPE_POWERPC64: + default: + W.printHex("CpuSubtype", subtype); + } + W.printEnum("FileType", Header.filetype, makeArrayRef(MachOHeaderFileTypes)); + W.printNumber("NumOfLoadCommands", Header.ncmds); + W.printNumber("SizeOfLoadCommands", Header.sizeofcmds); + W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags)); } void MachODumper::printSections() {