]> git.saurik.com Git - apple/libc.git/blame_incremental - libdarwin/variant.c
Libc-1353.100.2.tar.gz
[apple/libc.git] / libdarwin / variant.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2016 Apple 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#include <stdlib.h>
25#include <unistd.h>
26#include <sys/stat.h>
27#include <sys/sysctl.h>
28#include <sys/types.h>
29#include <dispatch/dispatch.h>
30#include <xpc/xpc.h>
31#include <xpc/private.h>
32#include <System/sys/csr.h>
33#include <System/machine/cpu_capabilities.h>
34
35#include <os/assumes.h>
36#include <os/bsd.h>
37#include <os/stdlib.h>
38#include <os/variant_private.h>
39
40/*
41 * Lists all properties overridden by an empty file
42 */
43#define ALL_OVERRIDES_STR "content,diagnostics,ui,security"
44
45enum variant_property {
46 VP_CONTENT,
47 VP_DIAGNOSTICS,
48 VP_UI,
49 VP_SECURITY,
50 VP_MAX
51};
52
53enum check_status {
54 S_UNKNOWN = 0,
55 S_NO = 2,
56 S_YES = 3
57};
58
59typedef struct {
60 const char *variant;
61 bool (*function)(const char*);
62} variant_check_mapping;
63
64static bool
65status2bool(enum check_status status) {
66 switch (status) {
67 case S_NO:
68 return false;
69 case S_YES:
70 return true;
71 case S_UNKNOWN:
72 default:
73 os_crash("os_variant had unexpected status");
74 }
75}
76
77#define VAR_FILE_LEGACY "/var/db/disableAppleInternal"
78
79#if TARGET_OS_OSX
80#define VAR_FILE_OVERRIDE "/var/db/os_variant_override"
81#else
82#define VAR_FILE_OVERRIDE "/usr/share/misc/os_variant_override"
83#endif
84
85#if !TARGET_OS_SIMULATOR
86#define INTERNAL_CONTENT_PATH "/System/Library/CoreServices/AppleInternalVariant.plist"
87#else
88#define INTERNAL_CONTENT_PATH "/AppleInternal"
89#endif
90
91#define SYSTEM_VERSION_PLIST_PATH "/System/Library/CoreServices/SystemVersion.plist"
92#define SYSTEM_VERSION_PLIST_KEY "ReleaseType"
93
94#if TARGET_OS_IPHONE
95#define INTERNAL_SETTINGS_PATH "/AppleInternal/Library/PreferenceBundles/Internal Settings.bundle"
96#else
97#define INTERNAL_DIAGS_PROFILE_PATH "/var/db/ConfigurationProfiles/Settings/com.apple.InternalDiagnostics.plist"
98#define FACTORY_CONTENT_PATH "/System/Library/CoreServices/AppleFactoryVariant.plist"
99#define BASE_SYSTEM_CONTENT_PATH "/System/Library/BaseSystem"
100#endif
101
102#if !TARGET_OS_SIMULATOR
103#define CACHE_SYSCTL_NAME "kern.osvariant_status"
104
105static void _restore_cached_check_status(uint64_t status);
106static uint64_t _get_cached_check_status(void);
107
108static char * _read_file(const char *path, size_t *size_out)
109{
110 char *buf = NULL;
111
112 int fd = open(path, O_RDONLY);
113 if (fd == -1) return NULL;
114
115 struct stat sb;
116 int rc = fstat(fd, &sb);
117 if (rc != 0 || sb.st_size == 0) {
118 goto error;
119 }
120
121 size_t size_limit = (size_out && *size_out != 0) ? *size_out : 1024;
122 size_t size = (size_t)sb.st_size;
123 if (size_out) *size_out = (size_t)sb.st_size;
124 if (size > size_limit) {
125 goto error;
126 }
127
128 buf = malloc(size + 1);
129 if (!buf) {
130 goto error;
131 }
132
133 ssize_t bytes_read = read(fd, buf, size);
134 buf[size] = '\0';
135
136
137 if (bytes_read == (ssize_t)size) {
138 close(fd);
139 return buf;
140 }
141
142error:
143 close(fd);
144 free(buf);
145 return NULL;
146}
147
148static xpc_object_t read_plist(const char *path)
149{
150 size_t size = 16 * 1024;
151 uint8_t *buf = (uint8_t*)_read_file(path, &size);
152 if (!buf) return NULL;
153
154 xpc_object_t plist = xpc_create_from_plist(buf, size);
155 if (plist && xpc_get_type(plist) != XPC_TYPE_DICTIONARY) {
156 xpc_release(plist);
157 plist = NULL;
158 }
159
160 free(buf);
161
162 return plist;
163}
164#endif
165
166#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
167static enum check_status internal_content = S_UNKNOWN;
168#endif
169#if !TARGET_OS_SIMULATOR
170static enum check_status can_has_debugger = S_UNKNOWN;
171#if TARGET_OS_IPHONE
172static enum check_status internal_release_type = S_UNKNOWN;
173static enum check_status factory_release_type = S_UNKNOWN;
174static enum check_status darwin_release_type = S_UNKNOWN;
175static enum check_status recovery_release_type = S_UNKNOWN;
176static enum check_status development_kernel = S_UNKNOWN;
177#else // TARGET_OS_IPHONE
178static enum check_status internal_diags_profile = S_UNKNOWN;
179static enum check_status factory_content = S_UNKNOWN;
180static enum check_status base_system_content = S_UNKNOWN;
181#endif // TARGET_OS_IPHONE
182#endif // !TARGET_OS_SIMULATOR
183static enum check_status is_ephemeral = S_UNKNOWN;
184
185static bool disabled_status[VP_MAX] = {};
186
187static void _parse_disabled_status(char *test_string)
188{
189#if TARGET_OS_SIMULATOR
190#pragma unused(test_string)
191#else // TARGET_OS_SIMULATOR
192 char *override_str = NULL;
193
194 bzero(disabled_status, sizeof(disabled_status));
195
196 if (test_string != NULL) {
197 /* used for unit tests */
198 override_str = os_strdup(test_string);
199 } else {
200 if (access(VAR_FILE_LEGACY, F_OK) == 0) {
201 override_str = os_strdup(ALL_OVERRIDES_STR);
202 } else if (access(VAR_FILE_OVERRIDE, F_OK) != 0) {
203 return;
204 }
205
206 override_str = _read_file(VAR_FILE_OVERRIDE, NULL);
207 }
208
209 if (override_str == NULL) {
210 override_str = os_strdup(ALL_OVERRIDES_STR);
211 }
212
213 char *token, *string = override_str;
214 while ((token = strsep(&string, ",\n")) != NULL) {
215 if (strcmp(token, "content") == 0) {
216 disabled_status[VP_CONTENT] = true;
217 } else if (strcmp(token, "diagnostics") == 0) {
218 disabled_status[VP_DIAGNOSTICS] = true;
219 } else if (strcmp(token, "ui") == 0) {
220 disabled_status[VP_UI] = true;
221 } else if (strcmp(token, "security") == 0) {
222 disabled_status[VP_SECURITY] = true;
223 }
224 }
225
226 free(override_str);
227 return;
228#endif //!TARGET_OS_SIMULATOR
229}
230
231#if !TARGET_OS_SIMULATOR
232static bool _load_cached_status(void)
233{
234 uint64_t status = 0;
235 size_t status_size = sizeof(status);
236 int ret = sysctlbyname(CACHE_SYSCTL_NAME, &status, &status_size, NULL, 0);
237 if (ret != 0) {
238 return false;
239 }
240
241 if (status) {
242 _restore_cached_check_status(status);
243 return true;
244 }
245
246 if (status == 0 && getpid() == 1) {
247 /*
248 * Looks like we are in launchd; try to set the status.
249 *
250 * We don't actually care if this works because we'll have warmed our state.
251 */
252 status = _get_cached_check_status();
253 sysctlbyname(CACHE_SYSCTL_NAME, NULL, 0, &status, status_size);
254 return true;
255 }
256
257 return false;
258}
259#endif
260
261static void _initialize_status(void * __unused ctx)
262{
263#if !TARGET_OS_SIMULATOR
264 if (!_load_cached_status()) {
265 _parse_disabled_status(NULL);
266 }
267#else
268 _parse_disabled_status(NULL);
269#endif
270}
271
272static bool _check_disabled(enum variant_property variant_property)
273{
274 static dispatch_once_t disabled_status_pred;
275 dispatch_once_f(&disabled_status_pred, NULL, _initialize_status);
276
277 return disabled_status[variant_property];
278}
279
280#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
281static bool _check_internal_content(void)
282{
283 if (internal_content == S_UNKNOWN) {
284#if !TARGET_OS_SIMULATOR
285 const char * path = INTERNAL_CONTENT_PATH;
286#else
287 char *simulator_root = getenv("IPHONE_SIMULATOR_ROOT");
288 char *to_free = NULL, *path = NULL;
289 if (simulator_root) {
290 asprintf(&path, "%s/%s", simulator_root, INTERNAL_CONTENT_PATH);
291 if (path == NULL) {
292 return false;
293 }
294 to_free = path;
295 }
296#endif
297 internal_content = (access(path, F_OK) == 0) ? S_YES : S_NO;
298#if TARGET_OS_SIMULATOR
299 free(to_free);
300#endif
301 }
302 return status2bool(internal_content);
303}
304#endif // !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
305
306#if TARGET_OS_OSX
307static bool _check_factory_content(void)
308{
309 if (factory_content == S_UNKNOWN) {
310 const char * path = FACTORY_CONTENT_PATH;
311 factory_content = (access(path, F_OK) == 0) ? S_YES : S_NO;
312 }
313 return status2bool(factory_content);
314}
315#endif // TARGET_OS_OSX
316
317#if TARGET_OS_IPHONE
318
319#if !TARGET_OS_SIMULATOR
320static bool _parse_system_version_plist(void)
321{
322 xpc_object_t system_version_plist = read_plist(SYSTEM_VERSION_PLIST_PATH);
323 if (!system_version_plist) {
324 return false;
325 }
326
327 const char *release_type =
328 xpc_dictionary_get_string(system_version_plist,
329 SYSTEM_VERSION_PLIST_KEY);
330
331 if (release_type == NULL) {
332 /*
333 * Confusingly, customer images are just completely missing this key.
334 */
335 internal_release_type = S_NO;
336 factory_release_type = S_NO;
337 darwin_release_type = S_NO;
338 recovery_release_type = S_NO;
339 } else if (strcmp(release_type, "NonUI") == 0) {
340 factory_release_type = S_YES;
341 internal_release_type = S_YES;
342 darwin_release_type = S_NO;
343 recovery_release_type = S_NO;
344 } else {
345 factory_release_type = S_NO;
346 internal_release_type = (strstr(release_type, "Internal") != NULL) ? S_YES : S_NO;
347 darwin_release_type = (strstr(release_type, "Darwin") != NULL) ? S_YES : S_NO;
348 recovery_release_type = (strstr(release_type, "Recovery") != NULL) ? S_YES : S_NO;
349 }
350
351 xpc_release(system_version_plist);
352
353 return true;
354}
355#endif //!TARGET_OS_SIMULATOR
356
357/*
358 * This set of criteria was taken from copyInternalBuild in MobileGestalt.c
359 */
360static bool _check_internal_release_type(void)
361{
362#if TARGET_OS_SIMULATOR
363 return _check_internal_content();
364#else // TARGET_OS_SIMULATOR
365 if (internal_release_type == S_UNKNOWN) {
366 if (!_parse_system_version_plist()) {
367 internal_release_type = (access(INTERNAL_SETTINGS_PATH, F_OK) == 0) ? S_YES : S_NO;
368 }
369 }
370
371 return status2bool(internal_release_type);
372#endif // TARGET_OS_SIMULATOR
373}
374
375static bool _check_factory_release_type(void)
376{
377#if TARGET_OS_SIMULATOR
378 return false;
379#else // TARGET_OS_SIMULATOR
380 if (factory_release_type == S_UNKNOWN) {
381 if (!_parse_system_version_plist()) {
382 factory_release_type = S_NO;
383 }
384 }
385
386 return status2bool(factory_release_type);
387#endif // TARGET_OS_SIMULATOR
388}
389
390static bool _check_darwin_release_type(void)
391{
392#if TARGET_OS_SIMULATOR
393 return false;
394#else // TARGET_OS_SIMULATOR
395 if (darwin_release_type == S_UNKNOWN) {
396 if (!_parse_system_version_plist()) {
397 darwin_release_type = S_NO;
398 }
399 }
400
401 return status2bool(darwin_release_type);
402#endif // TARGET_OS_SIMULATOR
403}
404
405static bool _check_recovery_release_type(void)
406{
407#if TARGET_OS_SIMULATOR
408 return false;
409#else // TARGET_OS_SIMULATOR
410 if (recovery_release_type == S_UNKNOWN) {
411 if (!_parse_system_version_plist()) {
412 recovery_release_type = S_NO;
413 }
414 }
415
416 return status2bool(recovery_release_type);
417#endif // TARGET_OS_SIMULATOR
418}
419
420#else // TARGET_OS_IPHONE
421
422static bool _check_internal_diags_profile(void)
423{
424 if (internal_diags_profile == S_UNKNOWN) {
425 xpc_object_t profile_settings = read_plist(INTERNAL_DIAGS_PROFILE_PATH);
426 if (profile_settings) {
427 internal_diags_profile = xpc_dictionary_get_bool(profile_settings, "AppleInternal") ? S_YES : S_NO;
428 xpc_release(profile_settings);
429 } else {
430 internal_diags_profile = S_NO;
431 }
432 }
433
434 return status2bool(internal_diags_profile);
435}
436
437static bool _check_base_system_content(void)
438{
439 if (base_system_content == S_UNKNOWN) {
440 const char * path = BASE_SYSTEM_CONTENT_PATH;
441 base_system_content = (access(path, F_OK) == 0) ? S_YES : S_NO;
442 }
443 return status2bool(base_system_content);
444}
445
446#endif
447
448#if !TARGET_OS_SIMULATOR
449static bool _check_can_has_debugger(void)
450{
451 if (can_has_debugger == S_UNKNOWN) {
452#if TARGET_OS_IPHONE
453 can_has_debugger = *((uint32_t *)_COMM_PAGE_DEV_FIRM) ? S_YES : S_NO;
454#else
455 /*
456 * The comm page bit does exist on macOS, but also requires kernel
457 * debugging in the CSR configuration. We don't need to be that strict
458 * here.
459 */
460 can_has_debugger = (csr_check(CSR_ALLOW_APPLE_INTERNAL) == 0) ? S_YES : S_NO;
461#endif
462 }
463 return status2bool(can_has_debugger);
464}
465#endif // !TARGET_OS_SIMULATOR
466
467#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
468static bool _check_development_kernel(void)
469{
470 if (development_kernel == S_UNKNOWN) {
471 /*
472 * Whitelist values from SUPPORTED_KERNEL_CONFIGS.
473 */
474 char *osbuildconfig = NULL;
475 size_t osbuildconfig_sz = 0;
476 errno_t err = sysctlbyname_get_data_np("kern.osbuildconfig", (void **)&osbuildconfig, &osbuildconfig_sz);
477 if (err == 0) {
478 if (strcmp(osbuildconfig, "development") == 0 ||
479 strcmp(osbuildconfig, "debug") == 0 ||
480 strcmp(osbuildconfig, "profile") == 0 ||
481 strcmp(osbuildconfig, "kasan") == 0) {
482 development_kernel = S_YES;
483 }
484 }
485 free(osbuildconfig);
486
487 if (development_kernel == S_UNKNOWN) {
488 development_kernel = S_NO;
489 }
490 }
491 return status2bool(development_kernel);
492}
493#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
494
495// For unit tests
496#ifndef VARIANT_SKIP_EXPORTED
497
498bool
499os_variant_has_internal_content(const char * __unused subsystem)
500{
501 if (_check_disabled(VP_CONTENT)) {
502 return false;
503 }
504
505#if TARGET_OS_IPHONE
506 return _check_internal_release_type();
507#else
508 return _check_internal_content();
509#endif
510}
511
512
513bool
514os_variant_has_internal_diagnostics(const char * __unused subsystem)
515{
516 if (_check_disabled(VP_DIAGNOSTICS)) {
517 return false;
518 }
519
520#if TARGET_OS_IPHONE
521 return _check_internal_release_type();
522#else
523 return _check_internal_content() || _check_internal_diags_profile();
524#endif
525}
526
527bool
528os_variant_has_internal_ui(const char * __unused subsystem)
529{
530 if (_check_disabled(VP_UI)) {
531 return false;
532 }
533
534#if TARGET_OS_IPHONE
535 return _check_internal_release_type();
536#else
537 return _check_internal_content();
538#endif
539}
540
541bool
542os_variant_allows_internal_security_policies(const char * __unused subsystem)
543{
544 if (_check_disabled(VP_SECURITY)) {
545 return false;
546 }
547
548#if TARGET_OS_SIMULATOR
549 return _check_internal_content();
550#elif TARGET_OS_IPHONE
551 return _check_can_has_debugger() || _check_development_kernel();
552#else
553 return _check_can_has_debugger();
554#endif
555}
556
557bool
558os_variant_has_factory_content(const char * __unused subsystem)
559{
560#if TARGET_OS_IPHONE
561 return _check_factory_release_type();
562#else
563 return _check_factory_content();
564#endif
565}
566
567bool
568os_variant_is_darwinos(const char * __unused subsystem)
569{
570
571#if TARGET_OS_IPHONE
572 return _check_darwin_release_type();
573#else
574 return false;
575#endif
576}
577
578bool
579os_variant_is_recovery(const char * __unused subsystem)
580{
581#if TARGET_OS_IPHONE
582 return _check_recovery_release_type();
583#else
584 return _check_base_system_content();
585#endif
586}
587
588bool
589os_variant_uses_ephemeral_storage(const char * __unused subsystem)
590{
591 if (is_ephemeral == S_UNKNOWN) {
592 uint32_t buffer = 0;
593 size_t buffer_size = sizeof(buffer);
594
595 sysctlbyname("hw.ephemeral_storage", (void *)&buffer, &buffer_size, NULL, 0);
596
597 is_ephemeral = (buffer != 0) ? S_YES : S_NO;
598 }
599
600 return status2bool(is_ephemeral);
601}
602
603bool
604os_variant_check(const char * __unused subsystem, const char *variant)
605{
606 static const variant_check_mapping map[] = {
607 {.variant = "HasInternalContent", .function = os_variant_has_internal_content},
608 {.variant = "HasInternalDiagnostics", .function = os_variant_has_internal_diagnostics},
609 {.variant = "HasInternalUI", .function = os_variant_has_internal_ui},
610 {.variant = "AllowsInternalSecurityPolicies", .function = os_variant_allows_internal_security_policies},
611 {.variant = "HasFactoryContent", .function = os_variant_has_factory_content},
612 {.variant = "IsDarwinOS", .function = os_variant_is_darwinos},
613 {.variant = "UsesEphemeralStorage", .function = os_variant_uses_ephemeral_storage},
614 {.variant = "IsRecovery", .function = os_variant_is_recovery},
615 {.variant = NULL, .function = NULL}
616 };
617 variant_check_mapping *current = (variant_check_mapping *)map;
618
619 while (current->variant) {
620 if (0 == strncasecmp(current->variant, variant, strlen(current->variant))) {
621 return current->function("");
622 }
623 current ++;
624 }
625
626 return false;
627}
628
629#endif // VARIANT_SKIP_EXPORTED
630
631#define STATUS_INITIAL_BITS 0x70000000F0000000ULL
632#define STATUS_BIT_WIDTH 2
633#define STATUS_SET 0x2
634#define STATUS_MASK 0x3
635
636enum status_flags_positions {
637 SFP_INTERNAL_CONTENT = 0,
638 SFP_CAN_HAS_DEBUGGER = 1,
639 SFP_INTERNAL_RELEASE_TYPE = 2,
640 SFP_INTERNAL_DIAGS_PROFILE = 3,
641 SFP_FACTORY_CONTENT = 4,
642 SFP_FACTORY_RELEASE_TYPE = 5,
643 SFP_DARWINOS_RELEASE_TYPE = 6,
644 SFP_EPHEMERAL_VOLUME = 7,
645 SFP_RECOVERY_RELEASE_TYPE = 8,
646 SFP_BASE_SYSTEM_CONTENT = 9,
647 SFP_DEVELOPMENT_KERNEL = 10,
648};
649
650#if !TARGET_OS_SIMULATOR
651static uint64_t _get_cached_check_status(void)
652{
653 uint64_t res = STATUS_INITIAL_BITS;
654
655#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
656 _check_internal_content();
657 if (internal_content != S_UNKNOWN)
658 res |= internal_content << SFP_INTERNAL_CONTENT * STATUS_BIT_WIDTH;
659#endif
660
661 _check_can_has_debugger();
662 if (can_has_debugger != S_UNKNOWN)
663 res |= can_has_debugger << SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH;
664
665 (void)os_variant_uses_ephemeral_storage("");
666 if (is_ephemeral != S_UNKNOWN)
667 res |= is_ephemeral << SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH;
668
669#if TARGET_OS_IPHONE
670 _check_internal_release_type();
671 if (internal_release_type != S_UNKNOWN)
672 res |= internal_release_type << SFP_INTERNAL_RELEASE_TYPE * STATUS_BIT_WIDTH;
673
674 _check_factory_release_type();
675 if (factory_release_type != S_UNKNOWN)
676 res |= factory_release_type << SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH;
677
678 _check_darwin_release_type();
679 if (darwin_release_type != S_UNKNOWN)
680 res |= darwin_release_type << SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH;
681
682 _check_recovery_release_type();
683 if (recovery_release_type != S_UNKNOWN)
684 res |= recovery_release_type << SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH;
685
686 _check_development_kernel();
687 if (development_kernel != S_UNKNOWN)
688 res |= development_kernel << SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH;
689#else
690 _check_internal_diags_profile();
691 if (internal_diags_profile != S_UNKNOWN)
692 res |= internal_diags_profile << SFP_INTERNAL_DIAGS_PROFILE * STATUS_BIT_WIDTH;
693
694 _check_factory_content();
695 if (factory_content != S_UNKNOWN)
696 res |= factory_content << SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH;
697
698 _check_base_system_content();
699 if (base_system_content != S_UNKNOWN)
700 res |= base_system_content << SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH;
701#endif
702
703 _parse_disabled_status(NULL);
704 for (int i = 0; i < VP_MAX; i++) {
705 if (disabled_status[i]) {
706 res |= 0x1ULL << (i + 32);
707 }
708 }
709
710 return res;
711}
712
713static void _restore_cached_check_status(uint64_t status)
714{
715#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
716 if ((status >> (SFP_INTERNAL_CONTENT * STATUS_BIT_WIDTH)) & STATUS_SET)
717 internal_content = (status >> (SFP_INTERNAL_CONTENT * STATUS_BIT_WIDTH)) & STATUS_MASK;
718#endif
719
720 if ((status >> (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH)) & STATUS_SET)
721 can_has_debugger = (status >> (SFP_CAN_HAS_DEBUGGER * STATUS_BIT_WIDTH)) & STATUS_MASK;
722
723 if ((status >> (SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH)) & STATUS_SET)
724 is_ephemeral = (status >> (SFP_EPHEMERAL_VOLUME * STATUS_BIT_WIDTH)) & STATUS_MASK;
725
726#if TARGET_OS_IPHONE
727 if ((status >> (SFP_INTERNAL_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
728 internal_release_type = (status >> (SFP_INTERNAL_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
729
730 if ((status >> (SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
731 factory_release_type = (status >> (SFP_FACTORY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
732
733 if ((status >> (SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
734 darwin_release_type = (status >> (SFP_DARWINOS_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
735
736 if ((status >> (SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_SET)
737 recovery_release_type = (status >> (SFP_RECOVERY_RELEASE_TYPE * STATUS_BIT_WIDTH)) & STATUS_MASK;
738
739 if ((status >> (SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH)) & STATUS_SET)
740 development_kernel = (status >> (SFP_DEVELOPMENT_KERNEL * STATUS_BIT_WIDTH)) & STATUS_MASK;
741#else
742 if ((status >> (SFP_INTERNAL_DIAGS_PROFILE * STATUS_BIT_WIDTH)) & STATUS_SET)
743 internal_diags_profile = (status >> (SFP_INTERNAL_DIAGS_PROFILE * STATUS_BIT_WIDTH)) & STATUS_MASK;
744
745 if ((status >> (SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH)) & STATUS_SET)
746 factory_content = (status >> (SFP_FACTORY_CONTENT * STATUS_BIT_WIDTH)) & STATUS_MASK;
747
748 if ((status >> (SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH)) & STATUS_SET)
749 base_system_content = (status >> (SFP_BASE_SYSTEM_CONTENT * STATUS_BIT_WIDTH)) & STATUS_MASK;
750#endif
751
752 for (int i = 0; i < VP_MAX; i++) {
753 disabled_status[i] = (status >> (32 + i)) & 0x1;
754 }
755}
756#endif // !TARGET_OS_SIMULATOR