]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/macho++.h
3c02c5fafc13ce95384fa5c7dbbf1a39c0cb4ea9
[apple/libsecurity_codesigning.git] / lib / macho++.h
1 /*
2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 //
25 // macho++ - Mach-O object file helpers
26 //
27 #ifndef _H_MACHOPLUSPLUS
28 #define _H_MACHOPLUSPLUS
29
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>
37
38 namespace Security {
39
40
41 //
42 // An architecture specification.
43 // Simply a pair or (cpu type, cpu subtype), really.
44 //
45 class Architecture : public std::pair<cpu_type_t, cpu_subtype_t> {
46 public:
47 Architecture() { }
48 explicit Architecture(cpu_type_t type, cpu_subtype_t sub = 0)
49 : std::pair<cpu_type_t, cpu_subtype_t>(type, sub) { }
50 Architecture(const fat_arch &archInFile);
51
52 cpu_type_t cpuType() const { return this->first; }
53 cpu_subtype_t cpuSubtype() const { return this->second; }
54 const char *name() const;
55
56 public:
57 friend bool operator == (const Architecture &a1, const Architecture &a2)
58 { return a1.cpuType() == a2.cpuType(); }
59
60 friend bool operator < (const Architecture &a1, const Architecture &a2)
61 { return a1.cpuType() < a2.cpuType(); }
62
63 public:
64 static Architecture local();
65 };
66
67
68 //
69 // A Mach-O formatted file segment.
70 //
71 class MachO : public UnixPlusPlus::FileDesc {
72 public:
73 MachO(FileDesc fd, size_t offset = 0, size_t length = 0);
74 ~MachO();
75
76 size_t offset() const { return mOffset; }
77 size_t length() const { return mLength; }
78
79 template <class T>
80 T flip(T value) const
81 { return mFlip ? Security::flip(value) : value; }
82
83 bool isFlipped() const { return mFlip; }
84 bool is64() const { return m64; }
85
86 Architecture architecture() const;
87 uint32_t type() const;
88 uint32_t flags() const;
89
90 const load_command *loadCommands() const { return mCommands; }
91 const load_command *nextCommand(const load_command *command) const;
92
93 const segment_command *findSegment(const char *segname) const;
94 const section *findSection(const char *segname, const char *sectname) const;
95
96 const linkedit_data_command *findCodeSignature() const;
97
98 size_t signingOffset() const; // starting offset of CS section, or 0 if none
99 size_t signingLength() const; // length of CS section, or 0 if none
100 size_t signingExtent() const; // signingOffset, or file length if none
101
102 void seek(size_t offset); // relative to start of image
103 CFDataRef dataAt(size_t offset, size_t size);
104
105 private:
106 size_t mOffset; // starting file offset
107 size_t mLength; // Mach-O file length
108 bool m64; // is 64-bit
109 bool mFlip; // wrong byte order (flip all integers)
110 mach_header mHeader; // Mach-O header
111 load_command *mCommands; // load commands
112 load_command *mEndCommands; // end of load commands
113 };
114
115
116 //
117 // A Universal object represents a Mach-O binary image (whole) file.
118 // It can represent a true Universal (aka "Fat") file with multiple
119 // architectures; but it will also represent a single Mach-O ("thin")
120 // binary and make you believe it's a Universal with just one architecture.
121 //
122 class Universal : public UnixPlusPlus::FileDesc {
123 public:
124 Universal(FileDesc fd);
125 ~Universal();
126
127 // return a genuine MachO object for the given architecture
128 MachO *architecture() const; // native
129 MachO *architecture(const Architecture &arch) const; // given
130
131 // return (just) the starting offset of an architecture
132 size_t archOffset() const; // native
133 size_t archOffset(const Architecture &arch) const; // given
134
135 // return a set of architectures contained
136 typedef std::set<Architecture> Architectures;
137 void architectures(Architectures &archs);
138
139 bool isUniversal() const { return mArchList; }
140 Architecture bestNativeArch() const;
141
142 public:
143 static uint32_t typeOf(FileDesc fd);
144
145 private:
146 const fat_arch *findArch(const Architecture &arch) const;
147 MachO *findImage(const Architecture &arch) const;
148
149 private:
150 fat_arch *mArchList; // architectures (NULL if thin file)
151 unsigned mArchCount; // number of architectures (if fat)
152 Architecture mThinArch; // single architecture (if thin)
153 };
154
155
156 } // end namespace Security
157
158 #endif // !_H_MACHOPLUSPLUS