X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..ea3f04195ba4a5034c9c8e9b726d4f7ce96f1832:/pexpert/gen/bootargs.c diff --git a/pexpert/gen/bootargs.c b/pexpert/gen/bootargs.c index c5efead48..fddac8d3e 100644 --- a/pexpert/gen/bootargs.c +++ b/pexpert/gen/bootargs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -32,8 +32,10 @@ typedef boolean_t (*argsep_func_t) (char c); static boolean_t isargsep( char c); static boolean_t israngesep( char c); +#ifndef CONFIG_EMBEDDED static int argstrcpy(char *from, char *to); -static int argstrcpy2(char *from,char *to, unsigned maxlen); +#endif +static int argstrcpy2(char *from, char *to, unsigned maxlen); static int argnumcpy(long long val, void *to, unsigned maxlen); static int getval(char *s, long long *val, argsep_func_t issep, boolean_t skip_equal_sign); boolean_t get_range_bounds(char * c, int64_t * lower, int64_t * upper); @@ -42,129 +44,175 @@ extern int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize struct i24 { - int32_t i24 : 24; + int32_t i24 : 24; int32_t _pad : 8; }; -#define NUM 0 -#define STR 1 - -#if !defined(__LP64__) && !defined(__arm__) -boolean_t -PE_parse_boot_arg( - const char *arg_string, - void *arg_ptr) -{ - int max_len = -1; - +#define NUM 0 +#define STR 1 - return PE_parse_boot_argn(arg_string, arg_ptr, max_len); -} -#endif - -boolean_t -PE_parse_boot_argn( - const char *arg_string, - void *arg_ptr, - int max_len) +static boolean_t +PE_parse_boot_argn_internal( + const char *arg_string, + void * arg_ptr, + int max_len, + boolean_t force_string) { char *args; char *cp, c; uintptr_t i; - long long val; + long long val = 0; boolean_t arg_boolean; boolean_t arg_found; args = PE_boot_args(); - if (*args == '\0') return FALSE; + if (*args == '\0') { + return FALSE; + } +#ifdef CONFIG_EMBEDDED + if (max_len == -1) { + return FALSE; + } +#endif arg_found = FALSE; - while(*args && isargsep(*args)) args++; + while (*args && isargsep(*args)) { + args++; + } - while (*args) - { - if (*args == '-') + while (*args) { + if (*args == '-') { arg_boolean = TRUE; - else + } else { arg_boolean = FALSE; + } cp = args; - while (!isargsep (*cp) && *cp != '=') + while (!isargsep(*cp) && *cp != '=') { cp++; - if (*cp != '=' && !arg_boolean) + } + if (*cp != '=' && !arg_boolean) { goto gotit; + } c = *cp; - i = cp-args; + i = cp - args; if (strncmp(args, arg_string, i) || - (i!=strlen(arg_string))) + (i != strlen(arg_string))) { goto gotit; + } + if (arg_boolean) { - argnumcpy(1, arg_ptr, max_len); - arg_found = TRUE; + if (!force_string) { + if (max_len > 0) { + argnumcpy(1, arg_ptr, max_len);/* max_len of 0 performs no copy at all*/ + arg_found = TRUE; + } else if (max_len == 0) { + arg_found = TRUE; + } + } break; } else { - while (*cp && isargsep (*cp)) + while (*cp && isargsep(*cp)) { cp++; + } if (*cp == '=' && c != '=') { - args = cp+1; + args = cp + 1; goto gotit; } - if ('_' == *arg_string) /* Force a string copy if the argument name begins with an underscore */ - { - int hacklen = 17 > max_len ? 17 : max_len; - argstrcpy2 (++cp, (char *)arg_ptr, hacklen - 1); /* Hack - terminate after 16 characters */ - arg_found = TRUE; + if ('_' == *arg_string) { /* Force a string copy if the argument name begins with an underscore */ + if (max_len > 0) { + int hacklen = 17 > max_len ? 17 : max_len; + argstrcpy2(++cp, (char *)arg_ptr, hacklen - 1); /* Hack - terminate after 16 characters */ + arg_found = TRUE; + } else if (max_len == 0) { + arg_found = TRUE; + } break; } - switch (getval(cp, &val, isargsep, FALSE)) - { - case NUM: + switch ((force_string && *cp == '=') ? STR : getval(cp, &val, isargsep, FALSE)) { + case NUM: + if (max_len > 0) { argnumcpy(val, arg_ptr, max_len); arg_found = TRUE; - break; - case STR: - if(max_len > 0) //max_len of 0 performs no copy at all - argstrcpy2(++cp, (char *)arg_ptr, max_len - 1); - else if(max_len == -1) // unreachable on embedded - argstrcpy(++cp, (char *)arg_ptr); + } else if (max_len == 0) { + arg_found = TRUE; + } + break; + case STR: + if (max_len > 0) { + argstrcpy2(++cp, (char *)arg_ptr, max_len - 1); /*max_len of 0 performs no copy at all*/ + arg_found = TRUE; + } else if (max_len == 0) { + arg_found = TRUE; + } +#if !CONFIG_EMBEDDED + else if (max_len == -1) { /* unreachable on embedded */ + argstrcpy(++cp, (char *)arg_ptr); arg_found = TRUE; - break; + } +#endif + break; } goto gotit; } gotit: /* Skip over current arg */ - while(!isargsep(*args)) args++; + while (!isargsep(*args)) { + args++; + } /* Skip leading white space (catch end of args) */ - while(*args && isargsep(*args)) args++; + while (*args && isargsep(*args)) { + args++; + } } - return(arg_found); + return arg_found; +} + +boolean_t +PE_parse_boot_argn( + const char *arg_string, + void *arg_ptr, + int max_len) +{ + return PE_parse_boot_argn_internal(arg_string, arg_ptr, max_len, FALSE); +} + +boolean_t +PE_parse_boot_arg_str( + const char *arg_string, + char *arg_ptr, + int strlen) +{ + return PE_parse_boot_argn_internal(arg_string, arg_ptr, strlen, TRUE); } static boolean_t isargsep(char c) { - if (c == ' ' || c == '\0' || c == '\t') - return (TRUE); - else - return (FALSE); + if (c == ' ' || c == '\0' || c == '\t') { + return TRUE; + } else { + return FALSE; + } } static boolean_t israngesep(char c) { - if (isargsep(c) || c == '_' || c == ',') - return (TRUE); - else - return (FALSE); + if (isargsep(c) || c == '_' || c == ',') { + return TRUE; + } else { + return FALSE; + } } +#if !CONFIG_EMBEDDED static int argstrcpy( char *from, @@ -177,8 +225,9 @@ argstrcpy( *to++ = *from++; } *to = 0; - return(i); + return i; } +#endif static int argstrcpy2( @@ -193,35 +242,36 @@ argstrcpy2( *to++ = *from++; } *to = 0; - return(i); + return i; } -static int argnumcpy(long long val, void *to, unsigned maxlen) +static int +argnumcpy(long long val, void *to, unsigned maxlen) { switch (maxlen) { - case 0: - /* No write-back, caller just wants to know if arg was found */ - break; - case 1: - *(int8_t *)to = val; - break; - case 2: - *(int16_t *)to = val; - break; - case 3: - /* Unlikely in practice */ - ((struct i24 *)to)->i24 = val; - break; - case 4: - *(int32_t *)to = val; - break; - case 8: - *(int64_t *)to = val; - break; - default: - *(int32_t *)to = val; - maxlen = 4; - break; + case 0: + /* No write-back, caller just wants to know if arg was found */ + break; + case 1: + *(int8_t *)to = val; + break; + case 2: + *(int16_t *)to = val; + break; + case 3: + /* Unlikely in practice */ + ((struct i24 *)to)->i24 = val; + break; + case 4: + *(int32_t *)to = val; + break; + case 8: + *(int64_t *)to = val; + break; + default: + *(int32_t *)to = val; + maxlen = 4; + break; } return (int)maxlen; @@ -245,13 +295,14 @@ getval( } if (has_value || skip_equal_sign) { - if (*s == '-') - sign = -1, s++; - intval = *s++-'0'; + if (*s == '-') { + sign = -1; + s++; + } + intval = *s++ - '0'; radix = 10; if (intval == 0) { - switch(*s) { - + switch (*s) { case 'x': radix = 16; s++; @@ -264,94 +315,108 @@ getval( case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - intval = *s-'0'; + intval = *s - '0'; s++; radix = 8; break; default: - if (!issep(*s)) - return (STR); + if (!issep(*s)) { + return STR; + } + } + } else if (intval >= radix) { + return STR; + } + for (;;) { + c = *s++; + if (issep(c)) { + break; } - } else if (intval >= radix) { - return (STR); - } - for(;;) { - c = *s++; - if (issep(c)) - break; - if ((radix <= 10) && - ((c >= '0') && (c <= ('9' - (10 - radix))))) { - c -= '0'; - } else if ((radix == 16) && - ((c >= '0') && (c <= '9'))) { + if ((radix <= 10) && + ((c >= '0') && (c <= ('9' - (10 - radix))))) { + c -= '0'; + } else if ((radix == 16) && + ((c >= '0') && (c <= '9'))) { c -= '0'; - } else if ((radix == 16) && - ((c >= 'a') && (c <= 'f'))) { + } else if ((radix == 16) && + ((c >= 'a') && (c <= 'f'))) { c -= 'a' - 10; - } else if ((radix == 16) && - ((c >= 'A') && (c <= 'F'))) { + } else if ((radix == 16) && + ((c >= 'A') && (c <= 'F'))) { c -= 'A' - 10; - } else if (c == 'k' || c == 'K') { + } else if (c == 'k' || c == 'K') { sign *= 1024; break; } else if (c == 'm' || c == 'M') { sign *= 1024 * 1024; - break; + break; } else if (c == 'g' || c == 'G') { sign *= 1024 * 1024 * 1024; - break; + break; } else { - return (STR); - } - if (c >= radix) - return (STR); + return STR; + } + if (c >= radix) { + return STR; + } intval *= radix; intval += c; } - if (!issep(c) && !issep(*s)) - return STR; + if (!issep(c) && !issep(*s)) { + return STR; + } *val = intval * sign; - return (NUM); + return NUM; } *val = 1; - return (NUM); + return NUM; } boolean_t PE_imgsrc_mount_supported() { +#if CONFIG_LOCKERBOOT + /* + * Booting from a locker requires that we be able to mount the containing + * volume inside the locker. This looks redundant, but this is here in case + * the other conditional needs to be modified for some reason. + */ return TRUE; +#else + return TRUE; +#endif } boolean_t PE_get_default( - const char *property_name, - void *property_ptr, + const char *property_name, + void *property_ptr, unsigned int max_property) { - DTEntry dte; - void **property_data; + DTEntry dte; + void **property_data; unsigned int property_size; /* * Look for the property using the PE DT support. */ if (kSuccess == DTLookupEntry(NULL, "/defaults", &dte)) { - /* * We have a /defaults node, look for the named property. */ - if (kSuccess != DTGetProperty(dte, property_name, (void **)&property_data, &property_size)) + if (kSuccess != DTGetProperty(dte, property_name, (void **)&property_data, &property_size)) { return FALSE; + } /* * This would be a fine place to do smart argument size management for 32/64 * translation, but for now we'll insist that callers know how big their * default values are. */ - if (property_size > max_property) + if (property_size > max_property) { return FALSE; + } /* * Copy back the precisely-sized result.