1/*
2 *  kcgen_main.h
3 *  kext_tools
4 *
5 *  Created by nik on 5/20/08.
6 *  Copyright 2008 __MyCompanyName__. All rights reserved.
7 *
8 */
9#ifndef _KCGEN_MAIN_H
10#define _KCGEN_MAIN_H
11
12#include <CoreFoundation/CoreFoundation.h>
13#include <IOKit/kext/OSKext.h>
14
15#include <getopt.h>
16#include <sysexits.h>
17
18#include <IOKit/kext/OSKext.h>
19
20#include "kext_tools_util.h"
21#include "kernelcache.h"
22
23#pragma mark Basic Types & Constants
24/*******************************************************************************
25* Constants
26*******************************************************************************/
27
28enum {
29    kKcgenExitOK          = EX_OK,
30    kKcgenExitNotFound,
31    kKcgenExitArchNotFound,
32    kKcgenExitKextBad,
33    kKcgenExitStale,
34
35    // don't think we use it
36    kKcgenExitUnspecified = 11,
37
38    // don't actually exit with this, it's just a sentinel value
39    kKcgenExitHelp        = 33,
40    kKcgenExitNoStart
41};
42
43#pragma mark Command-line Option Definitions
44/*******************************************************************************
45* Command-line options. This data is used by getopt_long_only().
46*
47* Options common to all kext tools are in kext_tools_util.h.
48*******************************************************************************/
49
50// kOptNameBundleIdentifier in kext_tools_util.h
51// kOptNameSystemExtensions in kext_tools_util.h
52
53#define kOptNameOptionalBundleIdentifier  "optional-bundle-id"
54
55/* Prelinked-kernel-generation flags.
56 */
57#define kOptNamePrelinkedKernel         "prelinked-kernel"
58#define kOptNameSystemPrelinkedKernel   "system-prelinked-kernel"
59#define kOptNameKernel                  "kernel"
60#define kOptNameAllLoaded               "all-loaded"
61#define kOptNameSymbols                 "symbols"
62#define kOptNameVolumeRoot              "volume-root"
63
64/* Embedded prelinked-kernel-generation flags.
65 */
66#define kOptNameAllPersonalities        "all-personalities"
67#define kOptNameNoLinkFailures          "no-link-failures"
68#define kOptNameStripSymbols            "strip-symbols"
69
70#define kOptNameMaxSliceSize            "max-slice-size"
71
72/* Misc flags.
73 */
74#define kOptNameNoAuthentication        "no-authentication"
75#define kOptNameTests                   "print-diagnostics"
76#define kOptNameCompressed              "compressed"
77#define kOptNameUncompressed            "uncompressed"
78
79#define kOptArch                  'a'
80// 'b' in kext_tools_util.h
81#define kOptPrelinkedKernel       'c'
82// 'h' in kext_tools_util.h
83#define kOptKernel                'K'
84// 'q' in kext_tools_util.h
85#define kOptTests                 't'
86// 'v' in kext_tools_util.h
87#define kOptNoAuthentication      'z'
88
89/* Options with no single-letter variant.  */
90// Do not use -1, that's getopt() end-of-args return value
91// and can cause confusion
92#define kLongOptLongindexHack             (-2)
93#define kLongOptOptionalBundleIdentifier  (-3)
94#define kLongOptCompressed                (-5)
95#define kLongOptUncompressed              (-6)
96#define kLongOptSymbols                   (-7)
97#define kLongOptVolumeRoot               (-10)
98#define kLongOptAllPersonalities         (-11)
99#define kLongOptNoLinkFailures           (-12)
100#define kLongOptStripSymbols             (-13)
101#define kLongOptMaxSliceSize             (-14)
102
103#define kOptChars                ":a:b:c:ehK:lLnNqsStvz"
104
105int longopt = 0;
106
107struct option sOptInfo[] = {
108    { kOptNameLongindexHack,            no_argument,        &longopt, kLongOptLongindexHack },
109
110    { kOptNameHelp,                     no_argument,        NULL,     kOptHelp },
111    { kOptNameQuiet,                    no_argument,        NULL,     kOptQuiet },
112    { kOptNameVerbose,                  optional_argument,  NULL,     kOptVerbose },
113    { kOptNameCompressed,               no_argument,        &longopt, kLongOptCompressed },
114    { kOptNameUncompressed,             no_argument,        &longopt, kLongOptUncompressed },
115
116    { kOptNameArch,                     required_argument,  NULL,     kOptArch },
117    { kOptNameVolumeRoot,               required_argument,  &longopt, kLongOptVolumeRoot },
118
119    { kOptNameBundleIdentifier,         required_argument,  NULL,     kOptBundleIdentifier },
120    { kOptNameOptionalBundleIdentifier, required_argument,  &longopt, kLongOptOptionalBundleIdentifier },
121
122    { kOptNamePrelinkedKernel,          optional_argument,  NULL,     kOptPrelinkedKernel },
123    { kOptNameKernel,                   required_argument,  NULL,     kOptKernel },
124    { kOptNameSymbols,                  required_argument,  &longopt, kLongOptSymbols },
125
126    { kOptNameTests,                    no_argument,        NULL,     kOptTests },
127
128    { kOptNameMaxSliceSize,             required_argument,  &longopt, kLongOptMaxSliceSize },
129
130    /* Always on for kcgen; can be removed at some point. */
131    { kOptNameAllPersonalities,         no_argument,        &longopt, kLongOptAllPersonalities },
132    { kOptNameNoLinkFailures,           no_argument,        &longopt, kLongOptNoLinkFailures },
133    { kOptNameStripSymbols,             no_argument,        &longopt, kLongOptStripSymbols },
134    { kOptNameNoAuthentication,         no_argument,        NULL,     kOptNoAuthentication },
135
136    { NULL, 0, NULL, 0 }  // sentinel to terminate list
137};
138
139typedef struct {
140    Boolean   printTestResults;     // -t
141
142    char    * prelinkedKernelPath;            // -c option
143    Boolean   generatePrelinkedSymbols;     // -symbols option
144    Boolean   stripSymbols;                 // -strip-symbols option
145    CFIndex   maxSliceSize;
146
147    CFURLRef  compressedPrelinkedKernelURL; // -uncompress option
148
149    char    * kernelPath;    // overriden by -K option
150    CFDataRef kernelFile;    // contents of kernelURL
151    CFURLRef  symbolDirURL;  // -s option;
152    CFURLRef  volumeRootURL;
153
154    CFMutableSetRef    kextIDs;          // -b; must release
155    CFMutableSetRef    optionalKextIDs;  // -optional-bundle-id; must release
156    CFMutableArrayRef  argURLs;          // directories & kexts in order
157    CFMutableArrayRef  repositoryURLs;   // just non-kext directories
158    CFMutableArrayRef  namedKextURLs;
159    CFMutableArrayRef  targetArchs;
160
161    CFArrayRef         allKexts;         // directories + named
162    CFArrayRef         repositoryKexts;  // all from directories (may include named)
163    CFArrayRef         namedKexts;
164
165    Boolean     compress;
166    Boolean     uncompress;
167} KcgenArgs;
168
169#pragma mark Function Prototypes
170/*******************************************************************************
171* Function Prototypes
172*******************************************************************************/
173ExitStatus readArgs(
174    int            * argc,
175    char * const  ** argv,
176    KcgenArgs  * toolArgs);
177const NXArchInfo * addArchForName(
178    KcgenArgs * toolArgs,
179    const char    * archname);
180ExitStatus readPrelinkedKernelArgs(
181    KcgenArgs * toolArgs,
182    int             argc,
183    char * const  * argv,
184    Boolean         isLongopt);
185ExitStatus setPrelinkedKernelArgs(
186    KcgenArgs * toolArgs,
187    char          * filename);
188
189ExitStatus checkArgs(KcgenArgs * toolArgs);
190
191ExitStatus writeFatFile(
192    const char                * filePath,
193    CFArrayRef                  fileSlices,
194    CFArrayRef                  fileArchs,
195    mode_t                      fileMode,
196    const struct timeval        fileTimes[2]);
197ExitStatus checkKextForProblems(
198    KcgenArgs         * toolArgs,
199    OSKextRef           theKext,
200    const NXArchInfo  * arch);
201ExitStatus filterKextsForCache(
202    KcgenArgs     * toolArgs,
203    CFMutableArrayRef   kextArray,
204    const NXArchInfo  * arch,
205    Boolean           * fatalOut);
206ExitStatus createPrelinkedKernelArchs(
207    KcgenArgs     * toolArgs,
208    CFMutableArrayRef * prelinkArchsOut);
209ExitStatus createExistingPrelinkedSlices(
210    KcgenArgs     * toolArgs,
211    CFMutableArrayRef * prelinkedSlicesOut,
212    CFMutableArrayRef * prelinkedArchsOut);
213ExitStatus createPrelinkedKernel(
214    KcgenArgs     * toolArgs);
215CFArrayRef mergeArchs(
216    CFArrayRef  archSet1,
217    CFArrayRef  archSet2);
218ExitStatus createPrelinkedKernelForArch(
219    KcgenArgs       * toolArgs,
220    CFDataRef           * prelinkedKernelOut,
221    CFDictionaryRef     * prelinkedSymbolsOut,
222    const NXArchInfo    * archInfo);
223ExitStatus compressPrelinkedKernel(
224    const char        * prelinkedKernelPath,
225    Boolean             compress);
226void logUsedKexts(
227    KcgenArgs       * toolArgs,
228    CFArrayRef        prelinkKexts);
229
230void usage(UsageLevel usageLevel);
231
232#endif /* _KCGEN_MAIN_H */
233