From 71be19dff2711856104fbe70a4d6711e745f74e2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 24 Mar 2015 20:26:55 +0000 Subject: [PATCH] [llvm-readobj] add support for macho universal binary. Patch by Keyue Hu (Chilledheart)! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233107 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/MachOUniversal.h | 10 +- .../Inputs/macho-universal.x86_64.i386 | Bin 0 -> 16624 bytes .../macho-universal-x86_64.i386.test | 141 ++++++++++++++++++ tools/llvm-readobj/llvm-readobj.cpp | 17 +++ 4 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 test/tools/llvm-readobj/Inputs/macho-universal.x86_64.i386 create mode 100644 test/tools/llvm-readobj/macho-universal-x86_64.i386.test diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index 93f66543882..05119b29331 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Object/Archive.h" #include "llvm/Object/Binary.h" #include "llvm/Object/MachO.h" @@ -69,9 +70,8 @@ public: ObjectForArch Obj; public: object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} - const ObjectForArch* operator->() const { - return &Obj; - } + const ObjectForArch *operator->() const { return &Obj; } + const ObjectForArch &operator*() const { return Obj; } bool operator==(const object_iterator &Other) const { return Obj == Other.Obj; @@ -97,6 +97,10 @@ public: return ObjectForArch(nullptr, 0); } + iterator_range objects() const { + return make_range(begin_objects(), end_objects()); + } + uint32_t getNumberOfObjects() const { return NumberOfObjects; } // Cast methods. diff --git a/test/tools/llvm-readobj/Inputs/macho-universal.x86_64.i386 b/test/tools/llvm-readobj/Inputs/macho-universal.x86_64.i386 new file mode 100644 index 0000000000000000000000000000000000000000..36d5fc29d6819ec58acd0572ae720eadd75635a2 GIT binary patch literal 16624 zcmeHNK}%Fo6uwU_hcum{q9|&Tl2XxGWC#&tIiwUNrV&Bh)Oj)kI?BvQ8UzDTFR;bqP&F3T6BORB`bWVe}gEfV5n&7B) zXXILEuDjXKgZ<*#e1O;jMM_4rPTM1C*Fcva?`9<~gZZ7V3+TZQi%UhRPVImDqKe+zq|Phm5^kM4XK#_dqQ(3k2z&%a)1T!F<9 zl#fjf!>MFLf4rw5I@%wFP1z4+9#xH3A6LI>{Ql%c&FrHG@jFK_hm@2GY%^Np*_?wM z!+p7r-`_7hrwPh6=ImId*|TweDjn^ut*t*wQDv#43nB`b5+1iB_igmj~StCI!SY8@c^xqfDzOB?hc2LF{`B>vY6CU)I&9*- zS%)4+JihSEpbw+}6E$|ekMLC{zsBy>*Sp{Rh>f2QAluOPyUga+Ym<54dSN)&VTe10@b${|l TQ}YLh^XmP~!C&j&Xr2EzYYPxd literal 0 HcmV?d00001 diff --git a/test/tools/llvm-readobj/macho-universal-x86_64.i386.test b/test/tools/llvm-readobj/macho-universal-x86_64.i386.test new file mode 100644 index 00000000000..502e0fb3980 --- /dev/null +++ b/test/tools/llvm-readobj/macho-universal-x86_64.i386.test @@ -0,0 +1,141 @@ +RUN: llvm-readobj -h %p/Inputs/macho-universal.x86_64.i386 \ +RUN: | FileCheck %s -check-prefix MULTIHEADER + +RUN: llvm-readobj -sections %p/Inputs/macho-universal.x86_64.i386 \ +RUN: | FileCheck %s -check-prefix MULTISECTIONS + +MULTIHEADER: Format: Mach-O 64-bit x86-64 +MULTIHEADER: Arch: x86_64 +MULTIHEADER: AddressSize: 64bit +MULTIHEADER: MachHeader { +MULTIHEADER: Magic: Magic64 (0xFEEDFACF) +MULTIHEADER: CpuType: X86-64 (0x1000007) +MULTIHEADER: CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3) +MULTIHEADER: FileType: Executable (0x2) +MULTIHEADER: NumOfLoadCommands: 16 +MULTIHEADER: SizeOfLoadCommands: 880 +MULTIHEADER: Flags [ (0x200085) +MULTIHEADER: MH_DYLDLINK (0x4) +MULTIHEADER: MH_NOUNDEFS (0x1) +MULTIHEADER: MH_PIE (0x200000) +MULTIHEADER: MH_TWOLEVEL (0x80) +MULTIHEADER: ] +MULTIHEADER: Reserved: 0x0 +MULTIHEADER: } + +MULTIHEADER: Format: Mach-O 32-bit i386 +MULTIHEADER: Arch: i386 +MULTIHEADER: AddressSize: 32bit +MULTIHEADER: MachHeader { +MULTIHEADER: Magic: Magic (0xFEEDFACE) +MULTIHEADER: CpuType: X86 (0x7) +MULTIHEADER: CpuSubType: CPU_SUBTYPE_I386_ALL (0x3) +MULTIHEADER: FileType: Executable (0x2) +MULTIHEADER: NumOfLoadCommands: 16 +MULTIHEADER: SizeOfLoadCommands: 716 +MULTIHEADER: Flags [ (0x1200085) +MULTIHEADER: MH_DYLDLINK (0x4) +MULTIHEADER: MH_NOUNDEFS (0x1) +MULTIHEADER: MH_NO_HEAP_EXECUTION (0x1000000) +MULTIHEADER: MH_PIE (0x200000) +MULTIHEADER: MH_TWOLEVEL (0x80) +MULTIHEADER: ] +MULTIHEADER: } + + + +MULTISECTIONS: Format: Mach-O 64-bit x86-64 +MULTISECTIONS: Arch: x86_64 +MULTISECTIONS: AddressSize: 64bit +MULTISECTIONS: Sections [ +MULTISECTIONS: Section { +MULTISECTIONS: Index: 0 +MULTISECTIONS: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Address: 0x100000F60 +MULTISECTIONS: Size: 0x12 +MULTISECTIONS: Offset: 3936 +MULTISECTIONS: Alignment: 4 +MULTISECTIONS: RelocationOffset: 0x0 +MULTISECTIONS: RelocationCount: 0 +MULTISECTIONS: Type: 0x0 +MULTISECTIONS: Attributes [ (0x800004) +MULTISECTIONS: PureInstructions (0x800000) +MULTISECTIONS: SomeInstructions (0x4) +MULTISECTIONS: ] +MULTISECTIONS: Reserved1: 0x0 +MULTISECTIONS: Reserved2: 0x0 +MULTISECTIONS: } +MULTISECTIONS: Section { +MULTISECTIONS: Index: 1 +MULTISECTIONS: Name: __unwind_info (5F 5F 75 6E 77 69 6E 64 5F 69 6E 66 6F 00 00 00) +MULTISECTIONS: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Address: 0x100000F72 +MULTISECTIONS: Size: 0x48 +MULTISECTIONS: Offset: 3954 +MULTISECTIONS: Alignment: 0 +MULTISECTIONS: RelocationOffset: 0x0 +MULTISECTIONS: RelocationCount: 0 +MULTISECTIONS: Type: 0x0 +MULTISECTIONS: Attributes [ (0x0) +MULTISECTIONS: ] +MULTISECTIONS: Reserved1: 0x0 +MULTISECTIONS: Reserved2: 0x0 +MULTISECTIONS: } +MULTISECTIONS: Section { +MULTISECTIONS: Index: 2 +MULTISECTIONS: Name: __eh_frame (5F 5F 65 68 5F 66 72 61 6D 65 00 00 00 00 00 00) +MULTISECTIONS: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Address: 0x100000FC0 +MULTISECTIONS: Size: 0x40 +MULTISECTIONS: Offset: 4032 +MULTISECTIONS: Alignment: 3 +MULTISECTIONS: RelocationOffset: 0x0 +MULTISECTIONS: RelocationCount: 0 +MULTISECTIONS: Type: 0x0 +MULTISECTIONS: Attributes [ (0x0) +MULTISECTIONS: ] +MULTISECTIONS: Reserved1: 0x0 +MULTISECTIONS: Reserved2: 0x0 +MULTISECTIONS: } +MULTISECTIONS: ] + +MULTISECTIONS: Format: Mach-O 32-bit i386 +MULTISECTIONS: Arch: i386 +MULTISECTIONS: AddressSize: 32bit +MULTISECTIONS: Sections [ +MULTISECTIONS: Section { +MULTISECTIONS: Index: 0 +MULTISECTIONS: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Address: 0x1FA0 +MULTISECTIONS: Size: 0x15 +MULTISECTIONS: Offset: 4000 +MULTISECTIONS: Alignment: 4 +MULTISECTIONS: RelocationOffset: 0x0 +MULTISECTIONS: RelocationCount: 0 +MULTISECTIONS: Type: 0x0 +MULTISECTIONS: Attributes [ (0x800004) +MULTISECTIONS: PureInstructions (0x800000) +MULTISECTIONS: SomeInstructions (0x4) +MULTISECTIONS: ] +MULTISECTIONS: Reserved1: 0x0 +MULTISECTIONS: Reserved2: 0x0 +MULTISECTIONS: } +MULTISECTIONS: Section { +MULTISECTIONS: Index: 1 +MULTISECTIONS: Name: __unwind_info (5F 5F 75 6E 77 69 6E 64 5F 69 6E 66 6F 00 00 00) +MULTISECTIONS: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00) +MULTISECTIONS: Address: 0x1FB5 +MULTISECTIONS: Size: 0x48 +MULTISECTIONS: Offset: 4021 +MULTISECTIONS: Alignment: 0 +MULTISECTIONS: RelocationOffset: 0x0 +MULTISECTIONS: RelocationCount: 0 +MULTISECTIONS: Type: 0x0 +MULTISECTIONS: Attributes [ (0x0) +MULTISECTIONS: ] +MULTISECTIONS: Reserved1: 0x0 +MULTISECTIONS: Reserved2: 0x0 +MULTISECTIONS: } +MULTISECTIONS: ] diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index f8f3086d840..32db723fa6f 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -25,6 +25,7 @@ #include "StreamWriter.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -320,6 +321,19 @@ static void dumpArchive(const Archive *Arc) { } } +/// @brief Dumps each object file in \a MachO Universal Binary; +static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) { + for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) { + ErrorOr> ObjOrErr = Obj.getAsObjectFile(); + if (std::error_code EC = ObjOrErr.getError()) { + reportError(UBinary->getFileName(), EC.message()); + continue; + } + + if (MachOObjectFile *MachOObj = ObjOrErr.get().get()) + dumpObject(MachOObj); + } +} /// @brief Opens \a File and dumps it. static void dumpInput(StringRef File) { @@ -339,6 +353,9 @@ static void dumpInput(StringRef File) { if (Archive *Arc = dyn_cast(&Binary)) dumpArchive(Arc); + else if (MachOUniversalBinary *UBinary = + dyn_cast(&Binary)) + dumpMachOUniversalBinary(UBinary); else if (ObjectFile *Obj = dyn_cast(&Binary)) dumpObject(Obj); else -- 2.34.1