2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 // macho++ - Mach-O object file helpers
27 #ifndef _H_MACHOPLUSPLUS
28 #define _H_MACHOPLUSPLUS
30 #include <mach-o/loader.h>
31 #include <mach-o/fat.h>
32 #include <mach-o/arch.h>
33 #include <security_utilities/globalizer.h>
34 #include <security_utilities/endian.h>
35 #include <security_utilities/unix++.h>
36 #include <security_utilities/cfutilities.h>
42 // An architecture specification.
43 // Simply a pair or (cpu type, cpu subtype), really.
45 class Architecture
: public std::pair
<cpu_type_t
, cpu_subtype_t
> {
46 typedef std::pair
<cpu_type_t
, cpu_subtype_t
> _Pair
;
49 explicit Architecture(cpu_type_t type
, cpu_subtype_t sub
= CPU_SUBTYPE_MULTIPLE
)
50 : std::pair
<cpu_type_t
, cpu_subtype_t
>(type
, sub
) { }
51 Architecture(const fat_arch
&archInFile
);
52 Architecture(const char *name
);
54 cpu_type_t
cpuType() const { return this->first
; }
55 cpu_subtype_t
cpuSubtype() const { return this->second
; }
56 const char *name() const; // NULL if unknown
57 std::string
displayName() const; // always display-able
59 static const cpu_type_t none
= 0;
60 operator bool () const { return cpuType() != none
; }
61 bool operator ! () const { return cpuType() == none
; }
64 friend bool operator == (const Architecture
&a1
, const Architecture
&a2
)
65 { return _Pair(a1
) == _Pair(a2
); }
67 friend bool operator < (const Architecture
&a1
, const Architecture
&a2
)
68 { return _Pair(a1
) < _Pair(a2
); }
70 bool matches(const Architecture
&templ
) const;
73 static Architecture
local();
78 // Common features of Mach-O object images.
79 // MachOBase does not define where we get this from.
88 { return mFlip
? Security::flip(value
) : value
; }
90 bool isFlipped() const { return mFlip
; }
91 bool is64() const { return m64
; }
93 const mach_header
&header() const { return *mHeader
; }
94 Architecture
architecture() const;
95 uint32_t type() const;
96 uint32_t flags() const;
98 const load_command
*loadCommands() const { return mCommands
; }
99 const load_command
*nextCommand(const load_command
*command
) const;
100 size_t commandLength() const { return flip(mHeader
->sizeofcmds
); }
102 const load_command
*findCommand(uint32_t cmd
) const;
103 const segment_command
*findSegment(const char *segname
) const;
104 const section
*findSection(const char *segname
, const char *sectname
) const;
106 const char *string(const load_command
*cmd
, const lc_str
&str
) const;
108 const linkedit_data_command
*findCodeSignature() const;
109 const linkedit_data_command
*findLibraryDependencies() const;
111 size_t signingOffset() const; // starting offset of CS section, or 0 if none
112 size_t signingLength() const; // length of CS section, or 0 if none
115 void initHeader(const mach_header
*address
);
116 void initCommands(const load_command
*commands
);
118 size_t headerSize() const; // size of header
119 size_t commandSize() const; // size of commands area
122 const mach_header
*mHeader
; // Mach-O header
123 const load_command
*mCommands
; // load commands
124 const load_command
*mEndCommands
; // end of load commands
126 bool m64
; // is 64-bit
127 bool mFlip
; // wrong byte order (flip all integers)
132 // A Mach-O object image that resides on disk.
133 // We only read small parts of the contents into (discontinuous) memory.
135 class MachO
: public MachOBase
, public UnixPlusPlus::FileDesc
{
137 MachO(FileDesc fd
, size_t offset
= 0, size_t length
= 0);
140 size_t offset() const { return mOffset
; }
141 size_t length() const { return mLength
; }
142 size_t signingExtent() const; // signingOffset, or file length if none
144 void seek(size_t offset
); // relative to start of image
145 CFDataRef
dataAt(size_t offset
, size_t size
);
148 size_t mOffset
; // starting file offset
149 size_t mLength
; // Mach-O file length
151 mach_header mHeaderBuffer
; // read-in Mach-O header
152 load_command
*mCommandBuffer
; // read-in (malloc'ed) Mach-O load commands
157 // A Mach-O object image that was mapped into memory.
158 // We expect the entire image to be contiguously mapped starting at the
159 // address given. No particular alignment is required (beyond native
160 // alignment constraints on member variables).
162 class MachOImage
: public MachOBase
{
164 MachOImage(const void *address
);
166 const void *address() { return &this->header(); }
169 class MainMachOImage
: public MachOImage
{
173 static const void *mainImageAddress();
178 // A Universal object represents a Mach-O binary image (whole) file.
179 // It can represent a true Universal (aka "Fat") file with multiple
180 // architectures; but it will also represent a single Mach-O ("thin")
181 // binary and make you believe it's a Universal with just one architecture.
183 class Universal
: public UnixPlusPlus::FileDesc
{
185 Universal(FileDesc fd
, off_t offset
= 0);
188 // return a genuine MachO object for the given architecture
189 MachO
*architecture() const; // native
190 MachO
*architecture(const Architecture
&arch
) const; // given
191 MachO
*architecture(off_t offset
) const; // given by file offset
193 // return (just) the starting offset of an architecture
194 size_t archOffset() const; // native
195 size_t archOffset(const Architecture
&arch
) const; // given
197 // return a set of architectures contained
198 typedef std::set
<Architecture
> Architectures
;
199 void architectures(Architectures
&archs
);
201 bool isUniversal() const { return mArchList
!= NULL
; }
202 Architecture
bestNativeArch() const;
205 static uint32_t typeOf(FileDesc fd
);
208 const fat_arch
*findArch(const Architecture
&arch
) const;
209 MachO
*findImage(const Architecture
&arch
) const;
212 fat_arch
*mArchList
; // architectures (NULL if thin file)
213 unsigned mArchCount
; // number of architectures (if fat)
214 Architecture mThinArch
; // single architecture (if thin)
215 off_t mBase
; // overriding offset in file (all types)
219 } // end namespace Security
221 #endif // !_H_MACHOPLUSPLUS