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,               optional_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    uint32_t    compressionType;
167    Boolean     uncompress;
168} KcgenArgs;
169
170#pragma mark Function Prototypes
171/*******************************************************************************
172* Function Prototypes
173*******************************************************************************/
174ExitStatus readArgs(
175    int            * argc,
176    char * const  ** argv,
177    KcgenArgs  * toolArgs);
178const NXArchInfo * addArchForName(
179    KcgenArgs * toolArgs,
180    const char    * archname);
181ExitStatus readPrelinkedKernelArgs(
182    KcgenArgs * toolArgs,
183    int             argc,
184    char * const  * argv,
185    Boolean         isLongopt);
186ExitStatus setPrelinkedKernelArgs(
187    KcgenArgs * toolArgs,
188    char          * filename);
189
190ExitStatus checkArgs(KcgenArgs * toolArgs);
191
192ExitStatus writeFatFile(
193    const char                * filePath,
194    CFArrayRef                  fileSlices,
195    CFArrayRef                  fileArchs,
196    mode_t                      fileMode,
197    const struct timeval        fileTimes[2]);
198ExitStatus checkKextForProblems(
199    KcgenArgs         * toolArgs,
200    OSKextRef           theKext,
201    const NXArchInfo  * arch);
202ExitStatus filterKextsForCache(
203    KcgenArgs     * toolArgs,
204    CFMutableArrayRef   kextArray,
205    const NXArchInfo  * arch,
206    Boolean           * fatalOut);
207ExitStatus createPrelinkedKernelArchs(
208    KcgenArgs     * toolArgs,
209    CFMutableArrayRef * prelinkArchsOut);
210ExitStatus createExistingPrelinkedSlices(
211    KcgenArgs     * toolArgs,
212    CFMutableArrayRef * prelinkedSlicesOut,
213    CFMutableArrayRef * prelinkedArchsOut);
214ExitStatus createPrelinkedKernel(
215    KcgenArgs     * toolArgs);
216CFArrayRef mergeArchs(
217    CFArrayRef  archSet1,
218    CFArrayRef  archSet2);
219ExitStatus createPrelinkedKernelForArch(
220    KcgenArgs       * toolArgs,
221    CFDataRef           * prelinkedKernelOut,
222    CFDictionaryRef     * prelinkedSymbolsOut,
223    const NXArchInfo    * archInfo);
224ExitStatus compressPrelinkedKernel(
225    const char        * prelinkedKernelPath,
226    Boolean             compress,
227    uint32_t            compressionType);
228void logUsedKexts(
229    KcgenArgs       * toolArgs,
230    CFArrayRef        prelinkKexts);
231
232void usage(UsageLevel usageLevel);
233
234#endif /* _KCGEN_MAIN_H */
235