1*19c3b8c2SApple OSS Distributions /*
2*19c3b8c2SApple OSS Distributions * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
3*19c3b8c2SApple OSS Distributions *
4*19c3b8c2SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*19c3b8c2SApple OSS Distributions *
6*19c3b8c2SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*19c3b8c2SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*19c3b8c2SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*19c3b8c2SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*19c3b8c2SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*19c3b8c2SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*19c3b8c2SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*19c3b8c2SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*19c3b8c2SApple OSS Distributions *
15*19c3b8c2SApple OSS Distributions * Please obtain a copy of the License at
16*19c3b8c2SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*19c3b8c2SApple OSS Distributions *
18*19c3b8c2SApple OSS Distributions * The Original Code and all software distributed under the License are
19*19c3b8c2SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*19c3b8c2SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*19c3b8c2SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*19c3b8c2SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*19c3b8c2SApple OSS Distributions * Please see the License for the specific language governing rights and
24*19c3b8c2SApple OSS Distributions * limitations under the License.
25*19c3b8c2SApple OSS Distributions *
26*19c3b8c2SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*19c3b8c2SApple OSS Distributions */
28*19c3b8c2SApple OSS Distributions #include <pexpert/pexpert.h>
29*19c3b8c2SApple OSS Distributions #include <pexpert/device_tree.h>
30*19c3b8c2SApple OSS Distributions
31*19c3b8c2SApple OSS Distributions #if defined(CONFIG_XNUPOST)
32*19c3b8c2SApple OSS Distributions #include <tests/xnupost.h>
33*19c3b8c2SApple OSS Distributions #endif
34*19c3b8c2SApple OSS Distributions
35*19c3b8c2SApple OSS Distributions typedef boolean_t (*argsep_func_t) (char c);
36*19c3b8c2SApple OSS Distributions
37*19c3b8c2SApple OSS Distributions static boolean_t isargsep( char c);
38*19c3b8c2SApple OSS Distributions static boolean_t israngesep( char c);
39*19c3b8c2SApple OSS Distributions #if defined(__x86_64__)
40*19c3b8c2SApple OSS Distributions static int argstrcpy(char *from, char *to);
41*19c3b8c2SApple OSS Distributions #endif
42*19c3b8c2SApple OSS Distributions static int argstrcpy2(char *from, char *to, unsigned maxlen);
43*19c3b8c2SApple OSS Distributions static int argnumcpy(long long val, void *to, unsigned maxlen);
44*19c3b8c2SApple OSS Distributions static int getval(char *s, long long *val, argsep_func_t issep, boolean_t skip_equal_sign);
45*19c3b8c2SApple OSS Distributions boolean_t get_range_bounds(char * c, int64_t * lower, int64_t * upper);
46*19c3b8c2SApple OSS Distributions
47*19c3b8c2SApple OSS Distributions extern int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize);
48*19c3b8c2SApple OSS Distributions #if defined(CONFIG_XNUPOST)
49*19c3b8c2SApple OSS Distributions kern_return_t parse_boot_arg_test(void);
50*19c3b8c2SApple OSS Distributions #endif
51*19c3b8c2SApple OSS Distributions
52*19c3b8c2SApple OSS Distributions struct i24 {
53*19c3b8c2SApple OSS Distributions int32_t i24 : 24;
54*19c3b8c2SApple OSS Distributions int32_t _pad : 8;
55*19c3b8c2SApple OSS Distributions };
56*19c3b8c2SApple OSS Distributions
57*19c3b8c2SApple OSS Distributions #define NUM 0
58*19c3b8c2SApple OSS Distributions #define STR 1
59*19c3b8c2SApple OSS Distributions
60*19c3b8c2SApple OSS Distributions static boolean_t
PE_parse_boot_argn_internal(char * args,const char * arg_string,void * arg_ptr,int max_len,boolean_t force_string)61*19c3b8c2SApple OSS Distributions PE_parse_boot_argn_internal(
62*19c3b8c2SApple OSS Distributions char *args,
63*19c3b8c2SApple OSS Distributions const char *arg_string,
64*19c3b8c2SApple OSS Distributions void * arg_ptr,
65*19c3b8c2SApple OSS Distributions int max_len,
66*19c3b8c2SApple OSS Distributions boolean_t force_string)
67*19c3b8c2SApple OSS Distributions {
68*19c3b8c2SApple OSS Distributions char *cp, c;
69*19c3b8c2SApple OSS Distributions uintptr_t i;
70*19c3b8c2SApple OSS Distributions long long val = 0;
71*19c3b8c2SApple OSS Distributions boolean_t arg_boolean;
72*19c3b8c2SApple OSS Distributions boolean_t arg_found;
73*19c3b8c2SApple OSS Distributions
74*19c3b8c2SApple OSS Distributions if (*args == '\0') {
75*19c3b8c2SApple OSS Distributions return FALSE;
76*19c3b8c2SApple OSS Distributions }
77*19c3b8c2SApple OSS Distributions
78*19c3b8c2SApple OSS Distributions #if !defined(__x86_64__)
79*19c3b8c2SApple OSS Distributions if (max_len == -1) {
80*19c3b8c2SApple OSS Distributions return FALSE;
81*19c3b8c2SApple OSS Distributions }
82*19c3b8c2SApple OSS Distributions #endif
83*19c3b8c2SApple OSS Distributions
84*19c3b8c2SApple OSS Distributions arg_found = FALSE;
85*19c3b8c2SApple OSS Distributions
86*19c3b8c2SApple OSS Distributions while (*args && isargsep(*args)) {
87*19c3b8c2SApple OSS Distributions args++;
88*19c3b8c2SApple OSS Distributions }
89*19c3b8c2SApple OSS Distributions
90*19c3b8c2SApple OSS Distributions while (*args) {
91*19c3b8c2SApple OSS Distributions if (*args == '-') {
92*19c3b8c2SApple OSS Distributions arg_boolean = TRUE;
93*19c3b8c2SApple OSS Distributions } else {
94*19c3b8c2SApple OSS Distributions arg_boolean = FALSE;
95*19c3b8c2SApple OSS Distributions }
96*19c3b8c2SApple OSS Distributions
97*19c3b8c2SApple OSS Distributions cp = args;
98*19c3b8c2SApple OSS Distributions while (!isargsep(*cp) && *cp != '=') {
99*19c3b8c2SApple OSS Distributions cp++;
100*19c3b8c2SApple OSS Distributions }
101*19c3b8c2SApple OSS Distributions
102*19c3b8c2SApple OSS Distributions c = *cp;
103*19c3b8c2SApple OSS Distributions
104*19c3b8c2SApple OSS Distributions i = cp - args;
105*19c3b8c2SApple OSS Distributions if (strncmp(args, arg_string, i) ||
106*19c3b8c2SApple OSS Distributions (i != strlen(arg_string))) {
107*19c3b8c2SApple OSS Distributions goto gotit;
108*19c3b8c2SApple OSS Distributions }
109*19c3b8c2SApple OSS Distributions
110*19c3b8c2SApple OSS Distributions if (arg_boolean) {
111*19c3b8c2SApple OSS Distributions if (max_len > 0) {
112*19c3b8c2SApple OSS Distributions if (force_string) {
113*19c3b8c2SApple OSS Distributions argstrcpy2("1", arg_ptr, max_len);
114*19c3b8c2SApple OSS Distributions } else {
115*19c3b8c2SApple OSS Distributions argnumcpy(1, arg_ptr, max_len);/* max_len of 0 performs no copy at all*/
116*19c3b8c2SApple OSS Distributions }
117*19c3b8c2SApple OSS Distributions arg_found = TRUE;
118*19c3b8c2SApple OSS Distributions } else if (max_len == 0) {
119*19c3b8c2SApple OSS Distributions arg_found = TRUE;
120*19c3b8c2SApple OSS Distributions }
121*19c3b8c2SApple OSS Distributions break;
122*19c3b8c2SApple OSS Distributions } else {
123*19c3b8c2SApple OSS Distributions while (*cp && isargsep(*cp)) {
124*19c3b8c2SApple OSS Distributions cp++;
125*19c3b8c2SApple OSS Distributions }
126*19c3b8c2SApple OSS Distributions if (*cp == '=' && c != '=') {
127*19c3b8c2SApple OSS Distributions args = cp + 1;
128*19c3b8c2SApple OSS Distributions goto gotit;
129*19c3b8c2SApple OSS Distributions }
130*19c3b8c2SApple OSS Distributions if ('_' == *arg_string) { /* Force a string copy if the argument name begins with an underscore */
131*19c3b8c2SApple OSS Distributions if (max_len > 0) {
132*19c3b8c2SApple OSS Distributions int hacklen = 17 > max_len ? 17 : max_len;
133*19c3b8c2SApple OSS Distributions argstrcpy2(++cp, (char *)arg_ptr, hacklen - 1); /* Hack - terminate after 16 characters */
134*19c3b8c2SApple OSS Distributions arg_found = TRUE;
135*19c3b8c2SApple OSS Distributions } else if (max_len == 0) {
136*19c3b8c2SApple OSS Distributions arg_found = TRUE;
137*19c3b8c2SApple OSS Distributions }
138*19c3b8c2SApple OSS Distributions break;
139*19c3b8c2SApple OSS Distributions }
140*19c3b8c2SApple OSS Distributions switch (force_string ? STR : getval(cp, &val, isargsep, FALSE)) {
141*19c3b8c2SApple OSS Distributions case NUM:
142*19c3b8c2SApple OSS Distributions if (max_len > 0) {
143*19c3b8c2SApple OSS Distributions argnumcpy(val, arg_ptr, max_len);
144*19c3b8c2SApple OSS Distributions arg_found = TRUE;
145*19c3b8c2SApple OSS Distributions } else if (max_len == 0) {
146*19c3b8c2SApple OSS Distributions arg_found = TRUE;
147*19c3b8c2SApple OSS Distributions }
148*19c3b8c2SApple OSS Distributions break;
149*19c3b8c2SApple OSS Distributions case STR:
150*19c3b8c2SApple OSS Distributions if (*cp == '=') {
151*19c3b8c2SApple OSS Distributions if (max_len > 0) {
152*19c3b8c2SApple OSS Distributions argstrcpy2(++cp, (char *)arg_ptr, max_len - 1); /*max_len of 0 performs no copy at all*/
153*19c3b8c2SApple OSS Distributions arg_found = TRUE;
154*19c3b8c2SApple OSS Distributions } else if (max_len == 0) {
155*19c3b8c2SApple OSS Distributions arg_found = TRUE;
156*19c3b8c2SApple OSS Distributions }
157*19c3b8c2SApple OSS Distributions #if defined(__x86_64__)
158*19c3b8c2SApple OSS Distributions else if (max_len == -1) { /* unreachable on embedded */
159*19c3b8c2SApple OSS Distributions argstrcpy(++cp, (char *)arg_ptr);
160*19c3b8c2SApple OSS Distributions arg_found = TRUE;
161*19c3b8c2SApple OSS Distributions }
162*19c3b8c2SApple OSS Distributions #endif
163*19c3b8c2SApple OSS Distributions } else {
164*19c3b8c2SApple OSS Distributions if (max_len > 0) {
165*19c3b8c2SApple OSS Distributions argstrcpy2("1", arg_ptr, max_len);
166*19c3b8c2SApple OSS Distributions arg_found = TRUE;
167*19c3b8c2SApple OSS Distributions } else if (max_len == 0) {
168*19c3b8c2SApple OSS Distributions arg_found = TRUE;
169*19c3b8c2SApple OSS Distributions }
170*19c3b8c2SApple OSS Distributions }
171*19c3b8c2SApple OSS Distributions break;
172*19c3b8c2SApple OSS Distributions }
173*19c3b8c2SApple OSS Distributions goto gotit;
174*19c3b8c2SApple OSS Distributions }
175*19c3b8c2SApple OSS Distributions gotit:
176*19c3b8c2SApple OSS Distributions /* Skip over current arg */
177*19c3b8c2SApple OSS Distributions while (!isargsep(*args)) {
178*19c3b8c2SApple OSS Distributions args++;
179*19c3b8c2SApple OSS Distributions }
180*19c3b8c2SApple OSS Distributions
181*19c3b8c2SApple OSS Distributions /* Skip leading white space (catch end of args) */
182*19c3b8c2SApple OSS Distributions while (*args && isargsep(*args)) {
183*19c3b8c2SApple OSS Distributions args++;
184*19c3b8c2SApple OSS Distributions }
185*19c3b8c2SApple OSS Distributions }
186*19c3b8c2SApple OSS Distributions
187*19c3b8c2SApple OSS Distributions return arg_found;
188*19c3b8c2SApple OSS Distributions }
189*19c3b8c2SApple OSS Distributions
190*19c3b8c2SApple OSS Distributions boolean_t
PE_parse_boot_argn(const char * arg_string,void * arg_ptr,int max_len)191*19c3b8c2SApple OSS Distributions PE_parse_boot_argn(
192*19c3b8c2SApple OSS Distributions const char *arg_string,
193*19c3b8c2SApple OSS Distributions void *arg_ptr,
194*19c3b8c2SApple OSS Distributions int max_len)
195*19c3b8c2SApple OSS Distributions {
196*19c3b8c2SApple OSS Distributions return PE_parse_boot_argn_internal(PE_boot_args(), arg_string, arg_ptr, max_len, FALSE);
197*19c3b8c2SApple OSS Distributions }
198*19c3b8c2SApple OSS Distributions
199*19c3b8c2SApple OSS Distributions boolean_t
PE_parse_boot_arg_str(const char * arg_string,char * arg_ptr,int strlen)200*19c3b8c2SApple OSS Distributions PE_parse_boot_arg_str(
201*19c3b8c2SApple OSS Distributions const char *arg_string,
202*19c3b8c2SApple OSS Distributions char *arg_ptr,
203*19c3b8c2SApple OSS Distributions int strlen)
204*19c3b8c2SApple OSS Distributions {
205*19c3b8c2SApple OSS Distributions return PE_parse_boot_argn_internal(PE_boot_args(), arg_string, arg_ptr, strlen, TRUE);
206*19c3b8c2SApple OSS Distributions }
207*19c3b8c2SApple OSS Distributions
208*19c3b8c2SApple OSS Distributions #if defined(CONFIG_XNUPOST)
209*19c3b8c2SApple OSS Distributions kern_return_t
parse_boot_arg_test(void)210*19c3b8c2SApple OSS Distributions parse_boot_arg_test(void)
211*19c3b8c2SApple OSS Distributions {
212*19c3b8c2SApple OSS Distributions // Tests are derived from libc/tests/darwin_bsd.c
213*19c3b8c2SApple OSS Distributions static struct string_test_case {
214*19c3b8c2SApple OSS Distributions char *args;
215*19c3b8c2SApple OSS Distributions const char *argname;
216*19c3b8c2SApple OSS Distributions char *argvalue;
217*19c3b8c2SApple OSS Distributions boolean_t found;
218*19c3b8c2SApple OSS Distributions } string_test_cases[] = {
219*19c3b8c2SApple OSS Distributions {"-x -a b=3 y=42", "-a", "1", TRUE},
220*19c3b8c2SApple OSS Distributions {"-x -a b=3 y=42", "b", "3", TRUE},
221*19c3b8c2SApple OSS Distributions {"-x -a b=2 ba=3 y=42", "b", "2", TRUE},
222*19c3b8c2SApple OSS Distributions {"-x -a ba=3 b=2 y=42", "b", "2", TRUE},
223*19c3b8c2SApple OSS Distributions {"-x -a b=2 ba=3 y=42", "ba", "3", TRUE},
224*19c3b8c2SApple OSS Distributions {"-x -a ba=3 b=2 y=42", "ba", "3", TRUE},
225*19c3b8c2SApple OSS Distributions {"-x -ab -aa y=42", "-a", NULL, FALSE},
226*19c3b8c2SApple OSS Distributions {"-x b=96 y=42", "bx", NULL, FALSE},
227*19c3b8c2SApple OSS Distributions {"-x ab=96 y=42", "a", NULL, FALSE},
228*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "notarealthing", NULL,
229*19c3b8c2SApple OSS Distributions FALSE},
230*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "hello", "world", TRUE},
231*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "debug", "0xBAADF00D",
232*19c3b8c2SApple OSS Distributions TRUE},
233*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "-foobar", "1", TRUE},
234*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "abc", "1", TRUE},
235*19c3b8c2SApple OSS Distributions };
236*19c3b8c2SApple OSS Distributions
237*19c3b8c2SApple OSS Distributions T_LOG("Testing boot-arg string parsing.\n");
238*19c3b8c2SApple OSS Distributions for (int i = 0; i < (int)(sizeof(string_test_cases) /
239*19c3b8c2SApple OSS Distributions sizeof(string_test_cases[0])); i++) {
240*19c3b8c2SApple OSS Distributions struct string_test_case *test_case = &string_test_cases[i];
241*19c3b8c2SApple OSS Distributions
242*19c3b8c2SApple OSS Distributions char result[256] = "NOT_FOUND";
243*19c3b8c2SApple OSS Distributions boolean_t found = PE_parse_boot_argn_internal(test_case->args,
244*19c3b8c2SApple OSS Distributions test_case->argname, result, sizeof(result), TRUE);
245*19c3b8c2SApple OSS Distributions
246*19c3b8c2SApple OSS Distributions if (test_case->found) {
247*19c3b8c2SApple OSS Distributions T_LOG("\"%s\": Looking for \"%s\", expecting \"%s\" found",
248*19c3b8c2SApple OSS Distributions test_case->args, test_case->argname, test_case->argvalue);
249*19c3b8c2SApple OSS Distributions T_EXPECT(found, "Should find argument");
250*19c3b8c2SApple OSS Distributions T_EXPECT_EQ_STR(result, test_case->argvalue,
251*19c3b8c2SApple OSS Distributions "Should find correct result");
252*19c3b8c2SApple OSS Distributions } else {
253*19c3b8c2SApple OSS Distributions T_LOG("\"%s\": Looking for \"%s\", expecting not found",
254*19c3b8c2SApple OSS Distributions test_case->args, test_case->argname, test_case->argvalue);
255*19c3b8c2SApple OSS Distributions T_EXPECT(!found, "Should not find argument");
256*19c3b8c2SApple OSS Distributions }
257*19c3b8c2SApple OSS Distributions }
258*19c3b8c2SApple OSS Distributions
259*19c3b8c2SApple OSS Distributions static struct integer_test_case {
260*19c3b8c2SApple OSS Distributions char *args;
261*19c3b8c2SApple OSS Distributions const char *argname;
262*19c3b8c2SApple OSS Distributions int argvalue;
263*19c3b8c2SApple OSS Distributions boolean_t found;
264*19c3b8c2SApple OSS Distributions } integer_test_cases[] = {
265*19c3b8c2SApple OSS Distributions {"-x -a b=3 y=42", "-a", 1, TRUE},
266*19c3b8c2SApple OSS Distributions {"-x -a b=3 y=42", "b", 3, TRUE},
267*19c3b8c2SApple OSS Distributions {"-x -a b=2 ba=3 y=42", "b", 2, TRUE},
268*19c3b8c2SApple OSS Distributions {"-x -a ba=3 b=2 y=42", "b", 2, TRUE},
269*19c3b8c2SApple OSS Distributions {"-x -a b=2 ba=3 y=42", "ba", 3, TRUE},
270*19c3b8c2SApple OSS Distributions {"-x -a ba=3 b=2 y=42", "ba", 3, TRUE},
271*19c3b8c2SApple OSS Distributions {"-x -ab -aa y=42", "-a", 0, FALSE},
272*19c3b8c2SApple OSS Distributions {"-x b=96 y=42", "bx", 0, FALSE},
273*19c3b8c2SApple OSS Distributions {"-x ab=96 y=42", "a", 0, FALSE},
274*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "notarealthing", 0, FALSE},
275*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "hello",
276*19c3b8c2SApple OSS Distributions 0x00726F77 /* "wor" */, TRUE},
277*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "debug", 0xBAADF00D, TRUE},
278*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "-foobar", 1, TRUE},
279*19c3b8c2SApple OSS Distributions {"hello=world -foobar abc debug=0xBAADF00D", "abc", 1, TRUE},
280*19c3b8c2SApple OSS Distributions };
281*19c3b8c2SApple OSS Distributions
282*19c3b8c2SApple OSS Distributions T_LOG("Testing boot-arg integer parsing.\n");
283*19c3b8c2SApple OSS Distributions for (int i = 0; i < (int)(sizeof(integer_test_cases) /
284*19c3b8c2SApple OSS Distributions sizeof(integer_test_cases[0])); i++) {
285*19c3b8c2SApple OSS Distributions struct integer_test_case *test_case = &integer_test_cases[i];
286*19c3b8c2SApple OSS Distributions
287*19c3b8c2SApple OSS Distributions int result = 0xCAFEFACE;
288*19c3b8c2SApple OSS Distributions boolean_t found = PE_parse_boot_argn_internal(test_case->args,
289*19c3b8c2SApple OSS Distributions test_case->argname, &result, sizeof(result), FALSE);
290*19c3b8c2SApple OSS Distributions
291*19c3b8c2SApple OSS Distributions if (test_case->found) {
292*19c3b8c2SApple OSS Distributions T_LOG("\"%s\": Looking for \"%s\", expecting %d found",
293*19c3b8c2SApple OSS Distributions test_case->args, test_case->argname, test_case->argvalue);
294*19c3b8c2SApple OSS Distributions T_EXPECT(found, "Should find argument");
295*19c3b8c2SApple OSS Distributions T_EXPECT_EQ_INT(result, test_case->argvalue,
296*19c3b8c2SApple OSS Distributions "Should find correct result");
297*19c3b8c2SApple OSS Distributions } else {
298*19c3b8c2SApple OSS Distributions T_LOG("\"%s\": Looking for \"%s\", expecting not found",
299*19c3b8c2SApple OSS Distributions test_case->args, test_case->argname, test_case->argvalue);
300*19c3b8c2SApple OSS Distributions T_EXPECT(!found, "Should not find argument");
301*19c3b8c2SApple OSS Distributions }
302*19c3b8c2SApple OSS Distributions }
303*19c3b8c2SApple OSS Distributions
304*19c3b8c2SApple OSS Distributions return KERN_SUCCESS;
305*19c3b8c2SApple OSS Distributions }
306*19c3b8c2SApple OSS Distributions #endif /* defined(CONFIG_XNUPOST) */
307*19c3b8c2SApple OSS Distributions
308*19c3b8c2SApple OSS Distributions static boolean_t
isargsep(char c)309*19c3b8c2SApple OSS Distributions isargsep(char c)
310*19c3b8c2SApple OSS Distributions {
311*19c3b8c2SApple OSS Distributions if (c == ' ' || c == '\0' || c == '\t') {
312*19c3b8c2SApple OSS Distributions return TRUE;
313*19c3b8c2SApple OSS Distributions } else {
314*19c3b8c2SApple OSS Distributions return FALSE;
315*19c3b8c2SApple OSS Distributions }
316*19c3b8c2SApple OSS Distributions }
317*19c3b8c2SApple OSS Distributions
318*19c3b8c2SApple OSS Distributions static boolean_t
israngesep(char c)319*19c3b8c2SApple OSS Distributions israngesep(char c)
320*19c3b8c2SApple OSS Distributions {
321*19c3b8c2SApple OSS Distributions if (isargsep(c) || c == '_' || c == ',') {
322*19c3b8c2SApple OSS Distributions return TRUE;
323*19c3b8c2SApple OSS Distributions } else {
324*19c3b8c2SApple OSS Distributions return FALSE;
325*19c3b8c2SApple OSS Distributions }
326*19c3b8c2SApple OSS Distributions }
327*19c3b8c2SApple OSS Distributions
328*19c3b8c2SApple OSS Distributions #if defined(__x86_64__)
329*19c3b8c2SApple OSS Distributions static int
argstrcpy(char * from,char * to)330*19c3b8c2SApple OSS Distributions argstrcpy(
331*19c3b8c2SApple OSS Distributions char *from,
332*19c3b8c2SApple OSS Distributions char *to)
333*19c3b8c2SApple OSS Distributions {
334*19c3b8c2SApple OSS Distributions int i = 0;
335*19c3b8c2SApple OSS Distributions
336*19c3b8c2SApple OSS Distributions while (!isargsep(*from)) {
337*19c3b8c2SApple OSS Distributions i++;
338*19c3b8c2SApple OSS Distributions *to++ = *from++;
339*19c3b8c2SApple OSS Distributions }
340*19c3b8c2SApple OSS Distributions *to = 0;
341*19c3b8c2SApple OSS Distributions return i;
342*19c3b8c2SApple OSS Distributions }
343*19c3b8c2SApple OSS Distributions #endif
344*19c3b8c2SApple OSS Distributions
345*19c3b8c2SApple OSS Distributions static int
argstrcpy2(char * from,char * to,unsigned maxlen)346*19c3b8c2SApple OSS Distributions argstrcpy2(
347*19c3b8c2SApple OSS Distributions char *from,
348*19c3b8c2SApple OSS Distributions char *to,
349*19c3b8c2SApple OSS Distributions unsigned maxlen)
350*19c3b8c2SApple OSS Distributions {
351*19c3b8c2SApple OSS Distributions unsigned int i = 0;
352*19c3b8c2SApple OSS Distributions
353*19c3b8c2SApple OSS Distributions while (!isargsep(*from) && i < maxlen) {
354*19c3b8c2SApple OSS Distributions i++;
355*19c3b8c2SApple OSS Distributions *to++ = *from++;
356*19c3b8c2SApple OSS Distributions }
357*19c3b8c2SApple OSS Distributions *to = 0;
358*19c3b8c2SApple OSS Distributions return i;
359*19c3b8c2SApple OSS Distributions }
360*19c3b8c2SApple OSS Distributions
361*19c3b8c2SApple OSS Distributions static int
argnumcpy(long long val,void * to,unsigned maxlen)362*19c3b8c2SApple OSS Distributions argnumcpy(long long val, void *to, unsigned maxlen)
363*19c3b8c2SApple OSS Distributions {
364*19c3b8c2SApple OSS Distributions switch (maxlen) {
365*19c3b8c2SApple OSS Distributions case 0:
366*19c3b8c2SApple OSS Distributions /* No write-back, caller just wants to know if arg was found */
367*19c3b8c2SApple OSS Distributions break;
368*19c3b8c2SApple OSS Distributions case 1:
369*19c3b8c2SApple OSS Distributions *(int8_t *)to = (int8_t)val;
370*19c3b8c2SApple OSS Distributions break;
371*19c3b8c2SApple OSS Distributions case 2:
372*19c3b8c2SApple OSS Distributions *(int16_t *)to = (int16_t)val;
373*19c3b8c2SApple OSS Distributions break;
374*19c3b8c2SApple OSS Distributions case 3:
375*19c3b8c2SApple OSS Distributions /* Unlikely in practice */
376*19c3b8c2SApple OSS Distributions ((struct i24 *)to)->i24 = (int32_t)val;
377*19c3b8c2SApple OSS Distributions break;
378*19c3b8c2SApple OSS Distributions case 4:
379*19c3b8c2SApple OSS Distributions *(int32_t *)to = (int32_t)val;
380*19c3b8c2SApple OSS Distributions break;
381*19c3b8c2SApple OSS Distributions case 8:
382*19c3b8c2SApple OSS Distributions *(int64_t *)to = (int64_t)val;
383*19c3b8c2SApple OSS Distributions break;
384*19c3b8c2SApple OSS Distributions default:
385*19c3b8c2SApple OSS Distributions *(int32_t *)to = (int32_t)val;
386*19c3b8c2SApple OSS Distributions maxlen = 4;
387*19c3b8c2SApple OSS Distributions break;
388*19c3b8c2SApple OSS Distributions }
389*19c3b8c2SApple OSS Distributions
390*19c3b8c2SApple OSS Distributions return (int)maxlen;
391*19c3b8c2SApple OSS Distributions }
392*19c3b8c2SApple OSS Distributions
393*19c3b8c2SApple OSS Distributions static int
getval(char * s,long long * val,argsep_func_t issep,boolean_t skip_equal_sign)394*19c3b8c2SApple OSS Distributions getval(
395*19c3b8c2SApple OSS Distributions char *s,
396*19c3b8c2SApple OSS Distributions long long *val,
397*19c3b8c2SApple OSS Distributions argsep_func_t issep,
398*19c3b8c2SApple OSS Distributions boolean_t skip_equal_sign )
399*19c3b8c2SApple OSS Distributions {
400*19c3b8c2SApple OSS Distributions unsigned long long radix, intval;
401*19c3b8c2SApple OSS Distributions unsigned char c;
402*19c3b8c2SApple OSS Distributions int sign = 1;
403*19c3b8c2SApple OSS Distributions boolean_t has_value = FALSE;
404*19c3b8c2SApple OSS Distributions
405*19c3b8c2SApple OSS Distributions if (*s == '=') {
406*19c3b8c2SApple OSS Distributions s++;
407*19c3b8c2SApple OSS Distributions has_value = TRUE;
408*19c3b8c2SApple OSS Distributions }
409*19c3b8c2SApple OSS Distributions
410*19c3b8c2SApple OSS Distributions if (has_value || skip_equal_sign) {
411*19c3b8c2SApple OSS Distributions if (*s == '-') {
412*19c3b8c2SApple OSS Distributions sign = -1;
413*19c3b8c2SApple OSS Distributions s++;
414*19c3b8c2SApple OSS Distributions }
415*19c3b8c2SApple OSS Distributions intval = *s++ - '0';
416*19c3b8c2SApple OSS Distributions radix = 10;
417*19c3b8c2SApple OSS Distributions if (intval == 0) {
418*19c3b8c2SApple OSS Distributions switch (*s) {
419*19c3b8c2SApple OSS Distributions case 'x':
420*19c3b8c2SApple OSS Distributions radix = 16;
421*19c3b8c2SApple OSS Distributions s++;
422*19c3b8c2SApple OSS Distributions break;
423*19c3b8c2SApple OSS Distributions
424*19c3b8c2SApple OSS Distributions case 'b':
425*19c3b8c2SApple OSS Distributions radix = 2;
426*19c3b8c2SApple OSS Distributions s++;
427*19c3b8c2SApple OSS Distributions break;
428*19c3b8c2SApple OSS Distributions
429*19c3b8c2SApple OSS Distributions case '0': case '1': case '2': case '3':
430*19c3b8c2SApple OSS Distributions case '4': case '5': case '6': case '7':
431*19c3b8c2SApple OSS Distributions intval = *s - '0';
432*19c3b8c2SApple OSS Distributions s++;
433*19c3b8c2SApple OSS Distributions radix = 8;
434*19c3b8c2SApple OSS Distributions break;
435*19c3b8c2SApple OSS Distributions
436*19c3b8c2SApple OSS Distributions default:
437*19c3b8c2SApple OSS Distributions if (!issep(*s)) {
438*19c3b8c2SApple OSS Distributions return STR;
439*19c3b8c2SApple OSS Distributions }
440*19c3b8c2SApple OSS Distributions }
441*19c3b8c2SApple OSS Distributions } else if (intval >= radix) {
442*19c3b8c2SApple OSS Distributions return STR;
443*19c3b8c2SApple OSS Distributions }
444*19c3b8c2SApple OSS Distributions for (;;) {
445*19c3b8c2SApple OSS Distributions c = *s++;
446*19c3b8c2SApple OSS Distributions if (issep(c)) {
447*19c3b8c2SApple OSS Distributions break;
448*19c3b8c2SApple OSS Distributions }
449*19c3b8c2SApple OSS Distributions if ((radix <= 10) &&
450*19c3b8c2SApple OSS Distributions ((c >= '0') && (c <= ('9' - (10 - radix))))) {
451*19c3b8c2SApple OSS Distributions c -= '0';
452*19c3b8c2SApple OSS Distributions } else if ((radix == 16) &&
453*19c3b8c2SApple OSS Distributions ((c >= '0') && (c <= '9'))) {
454*19c3b8c2SApple OSS Distributions c -= '0';
455*19c3b8c2SApple OSS Distributions } else if ((radix == 16) &&
456*19c3b8c2SApple OSS Distributions ((c >= 'a') && (c <= 'f'))) {
457*19c3b8c2SApple OSS Distributions c -= 'a' - 10;
458*19c3b8c2SApple OSS Distributions } else if ((radix == 16) &&
459*19c3b8c2SApple OSS Distributions ((c >= 'A') && (c <= 'F'))) {
460*19c3b8c2SApple OSS Distributions c -= 'A' - 10;
461*19c3b8c2SApple OSS Distributions } else if (c == 'k' || c == 'K') {
462*19c3b8c2SApple OSS Distributions sign *= 1024;
463*19c3b8c2SApple OSS Distributions break;
464*19c3b8c2SApple OSS Distributions } else if (c == 'm' || c == 'M') {
465*19c3b8c2SApple OSS Distributions sign *= 1024 * 1024;
466*19c3b8c2SApple OSS Distributions break;
467*19c3b8c2SApple OSS Distributions } else if (c == 'g' || c == 'G') {
468*19c3b8c2SApple OSS Distributions sign *= 1024 * 1024 * 1024;
469*19c3b8c2SApple OSS Distributions break;
470*19c3b8c2SApple OSS Distributions } else {
471*19c3b8c2SApple OSS Distributions return STR;
472*19c3b8c2SApple OSS Distributions }
473*19c3b8c2SApple OSS Distributions if (c >= radix) {
474*19c3b8c2SApple OSS Distributions return STR;
475*19c3b8c2SApple OSS Distributions }
476*19c3b8c2SApple OSS Distributions intval *= radix;
477*19c3b8c2SApple OSS Distributions intval += c;
478*19c3b8c2SApple OSS Distributions }
479*19c3b8c2SApple OSS Distributions if (!issep(c) && !issep(*s)) {
480*19c3b8c2SApple OSS Distributions return STR;
481*19c3b8c2SApple OSS Distributions }
482*19c3b8c2SApple OSS Distributions *val = intval * sign;
483*19c3b8c2SApple OSS Distributions return NUM;
484*19c3b8c2SApple OSS Distributions }
485*19c3b8c2SApple OSS Distributions *val = 1;
486*19c3b8c2SApple OSS Distributions return NUM;
487*19c3b8c2SApple OSS Distributions }
488*19c3b8c2SApple OSS Distributions
489*19c3b8c2SApple OSS Distributions boolean_t
PE_imgsrc_mount_supported()490*19c3b8c2SApple OSS Distributions PE_imgsrc_mount_supported()
491*19c3b8c2SApple OSS Distributions {
492*19c3b8c2SApple OSS Distributions return TRUE;
493*19c3b8c2SApple OSS Distributions }
494*19c3b8c2SApple OSS Distributions
495*19c3b8c2SApple OSS Distributions boolean_t
PE_get_default(const char * property_name,void * property_ptr,unsigned int max_property)496*19c3b8c2SApple OSS Distributions PE_get_default(
497*19c3b8c2SApple OSS Distributions const char *property_name,
498*19c3b8c2SApple OSS Distributions void *property_ptr,
499*19c3b8c2SApple OSS Distributions unsigned int max_property)
500*19c3b8c2SApple OSS Distributions {
501*19c3b8c2SApple OSS Distributions DTEntry dte;
502*19c3b8c2SApple OSS Distributions void const *property_data;
503*19c3b8c2SApple OSS Distributions unsigned int property_size;
504*19c3b8c2SApple OSS Distributions
505*19c3b8c2SApple OSS Distributions /*
506*19c3b8c2SApple OSS Distributions * Look for the property using the PE DT support.
507*19c3b8c2SApple OSS Distributions */
508*19c3b8c2SApple OSS Distributions if (kSuccess == SecureDTLookupEntry(NULL, "/defaults", &dte)) {
509*19c3b8c2SApple OSS Distributions /*
510*19c3b8c2SApple OSS Distributions * We have a /defaults node, look for the named property.
511*19c3b8c2SApple OSS Distributions */
512*19c3b8c2SApple OSS Distributions if (kSuccess != SecureDTGetProperty(dte, property_name, &property_data, &property_size)) {
513*19c3b8c2SApple OSS Distributions return FALSE;
514*19c3b8c2SApple OSS Distributions }
515*19c3b8c2SApple OSS Distributions
516*19c3b8c2SApple OSS Distributions /*
517*19c3b8c2SApple OSS Distributions * This would be a fine place to do smart argument size management for 32/64
518*19c3b8c2SApple OSS Distributions * translation, but for now we'll insist that callers know how big their
519*19c3b8c2SApple OSS Distributions * default values are.
520*19c3b8c2SApple OSS Distributions */
521*19c3b8c2SApple OSS Distributions if (property_size > max_property) {
522*19c3b8c2SApple OSS Distributions return FALSE;
523*19c3b8c2SApple OSS Distributions }
524*19c3b8c2SApple OSS Distributions
525*19c3b8c2SApple OSS Distributions /*
526*19c3b8c2SApple OSS Distributions * Copy back the precisely-sized result.
527*19c3b8c2SApple OSS Distributions */
528*19c3b8c2SApple OSS Distributions memcpy(property_ptr, property_data, property_size);
529*19c3b8c2SApple OSS Distributions return TRUE;
530*19c3b8c2SApple OSS Distributions }
531*19c3b8c2SApple OSS Distributions
532*19c3b8c2SApple OSS Distributions /*
533*19c3b8c2SApple OSS Distributions * Look for the property using I/O Kit's DT support.
534*19c3b8c2SApple OSS Distributions */
535*19c3b8c2SApple OSS Distributions return IODTGetDefault(property_name, property_ptr, max_property) ? FALSE : TRUE;
536*19c3b8c2SApple OSS Distributions }
537*19c3b8c2SApple OSS Distributions
538*19c3b8c2SApple OSS Distributions /* function: get_range_bounds
539*19c3b8c2SApple OSS Distributions * Parse a range string like "1_3,5_20" and return 1,3 as lower and upper.
540*19c3b8c2SApple OSS Distributions * Note: '_' is separator for bounds integer delimiter and
541*19c3b8c2SApple OSS Distributions * ',' is considered as separator for range pair.
542*19c3b8c2SApple OSS Distributions * returns TRUE when both range values are found
543*19c3b8c2SApple OSS Distributions */
544*19c3b8c2SApple OSS Distributions boolean_t
get_range_bounds(char * c,int64_t * lower,int64_t * upper)545*19c3b8c2SApple OSS Distributions get_range_bounds(char *c, int64_t *lower, int64_t *upper)
546*19c3b8c2SApple OSS Distributions {
547*19c3b8c2SApple OSS Distributions if (c == NULL || lower == NULL || upper == NULL) {
548*19c3b8c2SApple OSS Distributions return FALSE;
549*19c3b8c2SApple OSS Distributions }
550*19c3b8c2SApple OSS Distributions
551*19c3b8c2SApple OSS Distributions if (NUM != getval(c, lower, israngesep, TRUE)) {
552*19c3b8c2SApple OSS Distributions return FALSE;
553*19c3b8c2SApple OSS Distributions }
554*19c3b8c2SApple OSS Distributions
555*19c3b8c2SApple OSS Distributions while (*c != '\0') {
556*19c3b8c2SApple OSS Distributions if (*c == '_') {
557*19c3b8c2SApple OSS Distributions break;
558*19c3b8c2SApple OSS Distributions }
559*19c3b8c2SApple OSS Distributions c++;
560*19c3b8c2SApple OSS Distributions }
561*19c3b8c2SApple OSS Distributions
562*19c3b8c2SApple OSS Distributions if (*c == '_') {
563*19c3b8c2SApple OSS Distributions c++;
564*19c3b8c2SApple OSS Distributions if (NUM != getval(c, upper, israngesep, TRUE)) {
565*19c3b8c2SApple OSS Distributions return FALSE;
566*19c3b8c2SApple OSS Distributions }
567*19c3b8c2SApple OSS Distributions } else {
568*19c3b8c2SApple OSS Distributions return FALSE;
569*19c3b8c2SApple OSS Distributions }
570*19c3b8c2SApple OSS Distributions return TRUE;
571*19c3b8c2SApple OSS Distributions }
572