From c0bbac3af796bf66522d3c580f1596aef9d86002 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 19 Nov 2020 01:06:54 +0000 Subject: [PATCH] system_cmds-880.40.5.tar.gz --- arch.tproj/arch.1 | 16 +- arch.tproj/arch.c | 139 ++- fs_usage.tproj/fs_usage.c | 207 +++- gcore.tproj/dyld.c | 6 +- gcore.tproj/dyld_shared_cache.c | 7 +- gcore.tproj/main.c | 6 +- getty.tproj/com.apple.getty.internal.plist | 33 + .../com.apple.serialdebugconsole.plist | 39 + iosim.tproj/iosim.c | 41 +- login.tproj/login.entitlements | 2 - lskq.tproj/lskq.1 | 2 + lskq.tproj/lskq.c | 5 +- lsmp.tproj/common.h | 23 +- lsmp.tproj/port_details.c | 49 +- lsmp.tproj/task_details.c | 2 +- memory_pressure.tproj/memory_pressure.c | 52 +- nvram.tproj/nvram.c | 93 +- passwd.tproj/passwd.c | 20 +- passwd.tproj/passwd.entitlements | 2 + reboot.tproj/reboot.c | 16 + shutdown.tproj/shutdown.c | 19 + stackshot.tproj/stackshot.c | 36 +- sysctl.tproj/sysctl.c | 22 +- system_cmds.xcodeproj/project.pbxproj | 85 +- .../xcshareddata/WorkspaceSettings.xcsettings | 4 +- .../xcschemes/All_MacOSX.xcscheme | 6 +- tests/system_cmds.plist | 73 +- zic.tproj/build_zichost.sh | 3 +- zic.tproj/generate_zoneinfo.sh | 2 +- zlog.tproj/zlog.c | 16 + zprint.tproj/entitlements.plist | 4 - zprint.tproj/test_zprint.lua | 89 ++ zprint.tproj/zprint.c | 987 ++++++++++-------- zprint.tproj/zprint.lua | 192 +++- 34 files changed, 1601 insertions(+), 697 deletions(-) create mode 100644 getty.tproj/com.apple.getty.internal.plist create mode 100644 getty.tproj/com.apple.serialdebugconsole.plist create mode 100644 zprint.tproj/test_zprint.lua diff --git a/arch.tproj/arch.1 b/arch.tproj/arch.1 index afc984c..daad0af 100644 --- a/arch.tproj/arch.1 +++ b/arch.tproj/arch.1 @@ -62,16 +62,12 @@ command is to run a selected architecture of a universal binary. A universal binary contains code that can run on different architectures. By default, the operating system will select the architecture that most closely matches the processor type. -This means that an intel architecture is selected on intel processors and a -powerpc architecture is selected on powerpc processors. A 64-bit architecture is preferred over a 32-bit architecture on a 64-bit processor, while only 32-bit architectures can run on a 32-bit processor. .Pp When the most natural architecture is unavailable, the operating system will try to pick another architecture. On 64-bit processors, a 32-bit architecture is tried. -If this is also unavailable, the operating system on an intel processor will -try running a 32-bit powerpc architecture. Otherwise, no architecture is run, and an error results. .Pp The @@ -83,11 +79,13 @@ even if a 64-bit architecture is available. The .Ar arch_name argument must be one of the currently supported architectures: -.Bl -tag -width x86_64 -offset indent +.Bl -tag -width x86_64h -offset indent .It i386 32-bit intel .It x86_64 64-bit intel +.It x86_64h +64-bit intel (haswell) .El .Pp Either prefix the architecture with a hyphen, or (for compatibility with @@ -209,17 +207,17 @@ If not specified as a second field in a specifier, the executable path will be looked up in the corresponding property list file. .Ss Example ARCHPREFERENCE Values .Bl -tag -width " " -.It i386,x86_64 +.It i386,x86_64,x86_64h A specifier that matches any name. -.It foo:i386,x86_64 +.It foo:i386,x86_64,x86_64h A specifier that matches the program named .Nm foo (the full executable path is in the .Pa foo.plist file). -.It foo:/op/bin/boo:i386,x86_64 +.It foo:/op/bin/boo:i386,x86_64,x86_64h A specifier with all fields specified. -.It baz:i386;x86_64 +.It baz:i386;x86_64;x86_64h A specifier for .Nm baz and a second specifier that would match any other name. diff --git a/arch.tproj/arch.c b/arch.tproj/arch.c index 86df70a..3a38c68 100644 --- a/arch.tproj/arch.c +++ b/arch.tproj/arch.c @@ -43,6 +43,15 @@ #include #include +#if defined(__x86_64__) +#include +#endif + +#if TARGET_OS_OSX +#include +#include +#endif + #ifndef ARCH_PROG #define ARCH_PROG "arch" #endif @@ -61,7 +70,8 @@ static const char envname[] = "ARCHPREFERENCE"; /* The CPU struct contains the argument buffer to posix_spawnattr_setbinpref_np */ typedef struct { - cpu_type_t *buf; + cpu_type_t *types; + cpu_subtype_t *subtypes; int errs; size_t count; size_t capacity; @@ -70,19 +80,17 @@ typedef struct { typedef struct { const char *arch; cpu_type_t cpu; + cpu_subtype_t cpusubtype; } CPUTypes; static const CPUTypes knownArchs[] = { -#if defined(__i386__) || defined(__x86_64__) - {"i386", CPU_TYPE_I386}, - {"x86_64", CPU_TYPE_X86_64}, -#elif defined(__arm64__) - {"arm64", CPU_TYPE_ARM64}, -#elif defined(__arm__) - {"arm", CPU_TYPE_ARM}, -#else -#error "Unsupported architecture" -#endif + {"i386", CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL}, + {"x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL}, + {"x86_64h", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H}, + {"arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL}, + {"arm64", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL}, + {"arm64e", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64E}, + {"arm64_32", CPU_TYPE_ARM64_32, CPU_SUBTYPE_ARM64_32_ALL}, }; /* environment SPI */ @@ -96,20 +104,63 @@ extern char **environ; /* * The native 32 and 64-bit architectures (this is relative to the architecture - * the arch command is running. NULL means unsupported. + * the arch command is running). NULL means unsupported. */ + +static const char* +native32(void) +{ #if defined(__i386__) || defined(__x86_64__) - #define NATIVE_32 "i386" - #define NATIVE_64 "x86_64" + return "i386"; +#elif defined(__arm64__) && !defined(__LP64__) + return "arm64_32"; +#elif defined(__arm__) + return "arm"; +#else + return NULL; +#endif +} + +static const char* +native64(void) +{ +#if defined(__x86_64__) + // FIXME: It is not clear if we should do this check, given the comment above which states "this is relative to the architecture the arch command is running". + if (((*(uint64_t*)_COMM_PAGE_CPU_CAPABILITIES64) & kIsTranslated)) + return "arm64"; + return "x86_64"; +#elif defined(__i386__) + return "x86_64"; +#elif defined(__arm64__) && defined(__LP64__) + return "arm64"; #elif defined(__arm64__) - #define NATIVE_64 "arm64" - #define NATIVE_32 NULL + return "arm64_32"; +#else + return NULL; +#endif +} + +static bool +isSupportedCPU(cpu_type_t cpu) +{ +#if defined(__x86_64__) + if (((*(uint64_t*)_COMM_PAGE_CPU_CAPABILITIES64) & kIsTranslated)) + return cpu == CPU_TYPE_X86_64 || cpu == CPU_TYPE_ARM64; + return cpu == CPU_TYPE_X86_64; +#elif defined(__i386__) + return cpu == CPU_TYPE_I386 || cpu == CPU_TYPE_X86_64; +#elif defined(__arm64__) && defined(__LP64__) && TARGET_OS_OSX + return cpu == CPU_TYPE_X86_64 || cpu == CPU_TYPE_ARM64; +#elif defined(__arm64__) && defined(__LP64__) + return cpu == CPU_TYPE_ARM64; +#elif defined(__arm64__) + return cpu == CPU_TYPE_ARM64_32; #elif defined(__arm__) - #define NATIVE_32 "arm" - #define NATIVE_64 NULL + return cpu == CPU_TYPE_ARM; #else #error "Unsupported architecture" #endif +} bool unrecognizednative32seen = false; bool unrecognizednative64seen = false; @@ -149,7 +200,8 @@ spawnIt(CPU *cpu, int pflag, const char *str, char **argv) int ret; size_t copied; size_t count = cpu->count; - cpu_type_t *prefs = cpu->buf; + cpu_type_t *prefs = cpu->types; + cpu_subtype_t *subprefs = cpu->subtypes; if(count == 0) { if(unrecognizednative32seen) @@ -169,8 +221,19 @@ spawnIt(CPU *cpu, int pflag, const char *str, char **argv) /* do the equivalent of exec, rather than creating a separate process */ if((ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC)) != 0) errc(1, ret, "posix_spawnattr_setflags"); - if((ret = posix_spawnattr_setbinpref_np(&attr, count, prefs, &copied)) != 0) - errc(1, ret, "posix_spawnattr_setbinpref_np"); + if((ret = posix_spawnattr_setarchpref_np(&attr, count, prefs, subprefs, &copied)) != 0) + errc(1, ret, "posix_spawnattr_setbinpref_np"); + +#if TARGET_OS_OSX + for (size_t i = 0; i < copied; i++) { + if (prefs[i] == CPU_TYPE_ARM64) { + int affinity = 0; + size_t asize = sizeof(affinity); + sysctlbyname("kern.curproc_arch_affinity", NULL, NULL, &affinity, asize); + } + } +#endif /* TARGET_OS_OSX */ + if(copied != count) errx(1, "posix_spawnattr_setbinpref_np only copied %lu of %lu", copied, count); if(pflag) @@ -190,9 +253,12 @@ initCPU(CPU *cpu) cpu->errs = 0; cpu->count = 0; cpu->capacity = 1; - cpu->buf = (cpu_type_t *)malloc(cpu->capacity * sizeof(cpu_type_t)); - if(!cpu->buf) - err(1, "Failed to malloc CPU buffer"); + cpu->types = (cpu_type_t *)malloc(cpu->capacity * sizeof(cpu_type_t)); + if(!cpu->types) + err(1, "Failed to malloc CPU type buffer"); + cpu->subtypes = (cpu_subtype_t *)malloc(cpu->capacity * sizeof(cpu_subtype_t)); + if(!cpu->subtypes) + err(1, "Failed to malloc CPU subtype buffer"); } /* @@ -200,18 +266,25 @@ initCPU(CPU *cpu) * the array as necessary. */ static void -addCPU(CPU *cpu, cpu_type_t n) +addCPU(CPU *cpu, cpu_type_t n, cpu_subtype_t s) { if(cpu->count == cpu->capacity) { cpu_type_t *newcpubuf; + cpu_subtype_t *newcpusubbuf; cpu->capacity *= 2; - newcpubuf = (cpu_type_t *)realloc(cpu->buf, cpu->capacity * sizeof(cpu_type_t)); + newcpubuf = (cpu_type_t *)realloc(cpu->types, cpu->capacity * sizeof(cpu_type_t)); if(!newcpubuf) - err(1, "Out of memory realloc-ing CPU structure"); - cpu->buf = newcpubuf; + err(1, "Out of memory realloc-ing CPU types structure"); + cpu->types = newcpubuf; + newcpusubbuf = (cpu_subtype_t *)realloc(cpu->subtypes, cpu->capacity * sizeof(cpu_subtype_t)); + if(!newcpusubbuf) + err(1, "Out of memory realloc-ing CPU subtypes structure"); + cpu->subtypes = newcpusubbuf; + } - cpu->buf[cpu->count++] = n; + cpu->types[cpu->count] = n; + cpu->subtypes[cpu->count++] = s; } /* @@ -225,8 +298,10 @@ addCPUbyname(CPU *cpu, const char *name) int i; for (i=0; i < sizeof(knownArchs)/sizeof(knownArchs[0]); i++) { + if (!isSupportedCPU(knownArchs[i].cpu)) + continue; if (0 == strcasecmp(name, knownArchs[i].arch)) { - addCPU(cpu, knownArchs[i].cpu); + addCPU(cpu, knownArchs[i].cpu, knownArchs[i].cpusubtype); return; } } @@ -622,13 +697,13 @@ spawnFromArgs(CPU *cpu, char **argv) if((ret = MATCHARGWITHVALUE(argv, "-arch", 5, "-arch without architecture"))) { ap = ret; } else if(MATCHARG(argv, "-32")) { - ap = NATIVE_32; + ap = native32(); if(!ap) { unrecognizednative32seen = true; continue; } } else if(MATCHARG(argv, "-64")) { - ap = NATIVE_64; + ap = native64(); if(!ap) { unrecognizednative64seen = true; continue; diff --git a/fs_usage.tproj/fs_usage.c b/fs_usage.tproj/fs_usage.c index 8612ae1..ef81b48 100644 --- a/fs_usage.tproj/fs_usage.c +++ b/fs_usage.tproj/fs_usage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2019 Apple Inc. All rights reserved. + * Copyright (c) 1999-2020 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -2131,6 +2132,191 @@ format_print(th_info_t ti, char *sc_name, ktrace_event_t event, p = "CACHING ON (GLOBAL)"; break; + case F_FLUSH_DATA: + p = "FLUSH_DATA"; + break; + + case F_CHKCLEAN: + p = "CHKCLEAN"; + break; + + case F_RDAHEAD: + if (ti->arg3) { + p = "RDAHEAD ON"; + } else { + p = "RDAHEAD OFF"; + } + break; + + case F_LOG2PHYS: + p = "LOG2PHYS"; + break; + + case F_FREEZE_FS: + p = "FREEZE_FS"; + break; + + case F_THAW_FS: + p = "THAW_FS"; + break; + + case F_ADDSIGS: + p = "ADDSIGS"; + break; + + case F_MARKDEPENDENCY: + p = "MARKDEPENDENCY"; + break; + + case F_ADDFILESIGS: + p = "ADDFILESIGS"; + break; + + case F_NODIRECT: + p = "NODIRECT"; + break; + + case F_GETPROTECTIONCLASS: + p = "GETPROTECTIONCLASS"; + break; + + case F_SETPROTECTIONCLASS: + p = "SETPROTECTIONCLASS"; + break; + + case F_LOG2PHYS_EXT: + p = "LOG2PHYS_EXT"; + break; + + case F_SETSTATICCONTENT: + if (ti->arg3) { + p = "STATICCONTENT ON"; + } else { + p = "STATICCONTENT OFF"; + } + break; + + case F_MOVEDATAEXTENTS: + p = "MOVEDATAEXTENTS"; + break; + + case F_DUPFD_CLOEXEC: + p = "DUPFD_CLOEXEC"; + break; + + case F_SETBACKINGSTORE: + p = "SETBACKINGSTORE"; + break; + + case F_GETPATH_MTMINFO: + p = "GETPATH_MTMINFO"; + break; + + case F_GETCODEDIR: + p = "GETCODEDIR"; + break; + + case F_SETNOSIGPIPE: + p = "SETNOSIGPIPE"; + break; + + case F_GETNOSIGPIPE: + p = "GETNOSIGPIPE"; + break; + + case F_TRANSCODEKEY: + p = "TRANSCODEKEY"; + break; + + case F_SINGLE_WRITER: + p = "SINGLE_WRITER"; + break; + + case F_GETPROTECTIONLEVEL: + p = "GETPROTECTIONLEVEL"; + break; + + case F_FINDSIGS: + p = "FINDSIGS"; + break; + + case F_GETDEFAULTPROTLEVEL: + p = "GETDEFAULTPROTLEVEL"; + break; + + case F_MAKECOMPRESSED: + p = "MAKECOMPRESSED"; + break; + + case F_SET_GREEDY_MODE: + if (ti->arg3) { + p = "GREEDY_MODE ON"; + } else { + p = "GREEDY_MODE OFF"; + } + break; + + case F_SETIOTYPE: + p = "SETIOTYPE"; + break; + + case F_ADDFILESIGS_FOR_DYLD_SIM: + p = "ADDFILESIGS_FOR_DYLD_SIM"; + break; + + case F_RECYCLE: + p = "RECYCLE"; + break; + + case F_BARRIERFSYNC: + p = "BARRIERFSYNC"; + break; + + case F_SETCONFINED: + p = "SETCONFINED"; + break; + + case F_GETCONFINED: + p = "GETCONFINED"; + break; + + case F_ADDFILESIGS_RETURN: + p = "ADDFILESIGS_RETURN"; + break; + + case F_CHECK_LV: + p = "CHECK_LV"; + break; + + case F_PUNCHHOLE: + p = "PUNCHHOLE"; + break; + + case F_TRIM_ACTIVE_FILE: + p = "TRIM_ACTIVE_FILE"; + break; + + case F_SPECULATIVE_READ: + p = "SPECULATIVE_READ"; + break; + + case F_GETPATH_NOFIRMLINK: + p = "GETPATH_NOFIRMLINK"; + break; + + case F_ADDFILESIGS_INFO: + p = "ADDFILESIGS_INFO"; + break; + + case F_ADDFILESUPPL: + p = "ADDFILESUPPL"; + break; + +#ifdef F_GETSIGSINFO + case F_GETSIGSINFO: + p = "GETSIGSINFO"; + break; +#endif // F_GETSIGSINFO } if (p) { @@ -3148,7 +3334,7 @@ struct library_info { char *name; }; -struct library_range framework32 = {0, 0}; +struct library_range frameworkArm64e = {0, 0}; struct library_range framework64 = {0, 0}; struct library_range framework64h = {0, 0}; @@ -3350,16 +3536,21 @@ read_shared_cache_map(const char *path, struct library_range *lr, char *linkedit return 1; } +#define DYLD_SHARED_CACHE_LOCATION "/System/Library/dyld/" + void init_shared_cache_mapping(void) { - read_shared_cache_map("/var/db/dyld/dyld_shared_cache_i386.map", &framework32, "/var/db/dyld/dyld_shared_cache_i386"); - - if (0 == read_shared_cache_map("/var/db/dyld/dyld_shared_cache_x86_64h.map", &framework64h, "/var/db/dyld/dyld_shared_cache_x86_64h")) { - read_shared_cache_map("/var/db/dyld/dyld_shared_cache_x86_64.map", &framework64, "/var/db/dyld/dyld_shared_cache_x86_64"); +#if TARGET_OS_OSX +#if TARGET_CPU_ARM64 + read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_arm64e.map", &frameworkArm64e, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_arm64e"); +#else //!TARGET_CPU_ARM64 + if (0 == read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64h.map", &framework64h, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64h")) { + read_shared_cache_map(DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64.map", &framework64, DYLD_SHARED_CACHE_LOCATION"dyld_shared_cache_x86_64"); } - +#endif //TARGET_CPU_ARM64 sort_library_addresses(); +#endif //TARGET_OS_OSX } void @@ -3382,7 +3573,7 @@ lookup_name(uint64_t user_addr, char **type, char **name) *type = NULL; if (num_libraries) { - if ((user_addr >= framework32.b_address && user_addr < framework32.e_address) || + if ((user_addr >= frameworkArm64e.b_address && user_addr < frameworkArm64e.e_address) || (user_addr >= framework64.b_address && user_addr < framework64.e_address) || (user_addr >= framework64h.b_address && user_addr < framework64h.e_address)) { diff --git a/gcore.tproj/dyld.c b/gcore.tproj/dyld.c index 0ff3958..92aeac1 100644 --- a/gcore.tproj/dyld.c +++ b/gcore.tproj/dyld.c @@ -174,9 +174,9 @@ libent_insert(const char *rawnm, const uuid_t uuid, uint64_t mhaddr, const nativ if (NULL != le) return le; // disallow multiple names for the same uuid - char *nm = realpath(rawnm, NULL); - if (NULL == nm) - nm = strdup(rawnm); + char *nm = realpath(rawnm, NULL); + if (NULL == nm) + nm = strdup(rawnm); const unsigned long nmhash = simple_namehash(nm); le = libent_lookup_bypathname_withhash(nm, nmhash); if (NULL != le) { diff --git a/gcore.tproj/dyld_shared_cache.c b/gcore.tproj/dyld_shared_cache.c index c65ffca..0e21163 100644 --- a/gcore.tproj/dyld_shared_cache.c +++ b/gcore.tproj/dyld_shared_cache.c @@ -18,6 +18,7 @@ #include #include #include +#include static const size_t dyld_cache_header_size = sizeof (struct copied_dyld_cache_header); @@ -47,9 +48,9 @@ shared_cache_filename(const uuid_t uu) { assert(!uuid_is_null(uu)); static char *sc_argv[] = { -#if defined(__i386__) || defined(__x86_64__) - "/var/db/dyld", -#elif defined(__arm__) || defined(__arm64__) +#if TARGET_OS_OSX + "/System/Library/dyld", +#elif TARGET_OS_IPHONE "/System/Library/Caches/com.apple.dyld", #else #error undefined diff --git a/gcore.tproj/main.c b/gcore.tproj/main.c index 64be227..abefa14 100644 --- a/gcore.tproj/main.c +++ b/gcore.tproj/main.c @@ -472,7 +472,7 @@ gcore_main(int argc, char *const *argv) if (!opt->extended && opt->allfilerefs) errx(EX_USAGE, "unknown flag"); - setpageshift(); + setpageshift(); if (opt->ncthresh < ((vm_offset_t)1 << pageshift_host)) errx(EX_USAGE, "threshold %lu less than host pagesize", opt->ncthresh); @@ -812,8 +812,8 @@ gcore_conv_main(int argc, char *argv[]) errx(EX_USAGE, "no input corefile"); if (optind == argc - 1) errx(EX_USAGE, "no output corefile"); - if (optind < argc - 2) - errx(EX_USAGE, "too many arguments"); + if (optind < argc - 2) + errx(EX_USAGE, "too many arguments"); const char *incore = argv[optind]; char *corefname = strdup(argv[optind+1]); diff --git a/getty.tproj/com.apple.getty.internal.plist b/getty.tproj/com.apple.getty.internal.plist new file mode 100644 index 0000000..bbd8345 --- /dev/null +++ b/getty.tproj/com.apple.getty.internal.plist @@ -0,0 +1,33 @@ + + + + + EnablePressuredExit + + EnableTransactions + + KeepAlive + + Label + com.apple.getty + POSIXSpawnType + Interactive + _LimitLoadFromVariant + IsBaseSystem + LimitLoadToHardware + + serialdebugmode + + 1 + + + ProgramArguments + + /usr/libexec/getty + std.9600 + console + + SessionCreate + + + diff --git a/getty.tproj/com.apple.serialdebugconsole.plist b/getty.tproj/com.apple.serialdebugconsole.plist new file mode 100644 index 0000000..9be51e9 --- /dev/null +++ b/getty.tproj/com.apple.serialdebugconsole.plist @@ -0,0 +1,39 @@ + + + + + EnablePressuredExit + + EnableTransactions + + KeepAlive + + Label + com.apple.serialdebugconsole + POSIXSpawnType + Interactive + _LimitLoadToVariant + AllowsInternalSecurityPolicies + LimitLoadToHardware + + serialdebugmode + + 2 + + + ProgramArguments + + /bin/sh + -i + -l + + StandardInPath + /dev/console + StandardOutPath + /dev/console + StandardErrorPath + /dev/console + SessionCreate + + + diff --git a/iosim.tproj/iosim.c b/iosim.tproj/iosim.c index cc37ad0..7a0efce 100644 --- a/iosim.tproj/iosim.c +++ b/iosim.tproj/iosim.c @@ -38,8 +38,9 @@ #define BLOCKSIZE 1024 #define MAX_CMD_SIZE 256 #define PG_MASK ~(0xFFF) -#define kIONVMeANS2ControllerString "AppleANS2Controller" -#define kIONVMeControllerString "AppleNVMeController" +#define kIONVMeANS2ControllerString "AppleANS2Controller" +#define kIONVMeANS2EmbeddedControllerString "AppleANS2NVMeController" +#define kIONVMeControllerString "AppleNVMeController" typedef enum { kDefaultDevice = 0, @@ -217,22 +218,34 @@ void setup_qos_device(void) if ( iterator != IO_OBJECT_NULL ) { printf ( "Found NVMe ANS2 Device \n" ); qos_device = kNVMeDeviceANS2; - } else { + return; + } - status= IOServiceGetMatchingServices ( kIOMasterPortDefault, IOServiceMatching ( kIONVMeControllerString ), &iterator ); + status = IOServiceGetMatchingServices ( kIOMasterPortDefault, IOServiceMatching ( kIONVMeANS2EmbeddedControllerString ), &iterator ); - if ( status != kIOReturnSuccess ) - return; + if ( status != kIOReturnSuccess ) + return; - if ( iterator != IO_OBJECT_NULL ) { - printf ( "Found NVMe Device \n" ); - qos_device = kNVMeDevice; - } - else { - printf ( "NVMe Device not found, not setting qos timeout\n" ); - qos_device = kDefaultDevice; - } + if ( iterator != IO_OBJECT_NULL ) { + printf ( "Found NVMe ANS2 Embedded Device \n" ); + qos_device = kNVMeDeviceANS2; + return; } + + status= IOServiceGetMatchingServices ( kIOMasterPortDefault, IOServiceMatching ( kIONVMeControllerString ), &iterator ); + + if ( status != kIOReturnSuccess ) + return; + + if ( iterator != IO_OBJECT_NULL ) { + printf ( "Found NVMe Device \n" ); + qos_device = kNVMeDevice; + return; + } + + printf ( "NVMe Device not found, not setting qos timeout\n" ); + qos_device = kDefaultDevice; + return; } void assertASP(CFRunLoopTimerRef timer, void *info ) diff --git a/login.tproj/login.entitlements b/login.tproj/login.entitlements index 6e47a16..a9f77f2 100644 --- a/login.tproj/login.entitlements +++ b/login.tproj/login.entitlements @@ -2,8 +2,6 @@ - com.apple.private.opendirectoryd.identity - com.apple.private.security.clear-library-validation diff --git a/lskq.tproj/lskq.1 b/lskq.tproj/lskq.1 index 88200e1..86e31d8 100644 --- a/lskq.tproj/lskq.1 +++ b/lskq.tproj/lskq.1 @@ -95,6 +95,8 @@ NOTE_LINK NOTE_RENAME .It Sy v NOTE_REVOKE +.It Sy u +NOTE_FUNLOCK .Pp .It EVFILT_PROC: .It Sy x diff --git a/lskq.tproj/lskq.c b/lskq.tproj/lskq.c index 6eaa3a8..a48bb26 100644 --- a/lskq.tproj/lskq.c +++ b/lskq.tproj/lskq.c @@ -101,14 +101,15 @@ fflags_build(struct kevent_extinfo *info, char *str, int len) } case EVFILT_VNODE: { - snprintf(str, len, "%c%c%c%c%c%c%c", + snprintf(str, len, "%c%c%c%c%c%c%c%c", (ff & NOTE_DELETE) ? 'd' : '-', (ff & NOTE_WRITE) ? 'w' : '-', (ff & NOTE_EXTEND) ? 'e' : '-', (ff & NOTE_ATTRIB) ? 'a' : '-', (ff & NOTE_LINK) ? 'l' : '-', (ff & NOTE_RENAME) ? 'r' : '-', - (ff & NOTE_REVOKE) ? 'v' : '-' + (ff & NOTE_REVOKE) ? 'v' : '-', + (ff & NOTE_FUNLOCK) ? 'u' : '-' ); break; } diff --git a/lsmp.tproj/common.h b/lsmp.tproj/common.h index 8ab5eab..9a47012 100644 --- a/lsmp.tproj/common.h +++ b/lsmp.tproj/common.h @@ -97,8 +97,8 @@ typedef struct my_per_task_info { * Need to stay in sync to print accurate results. */ #define IKOT_NONE 0 -#define IKOT_THREAD 1 -#define IKOT_TASK 2 +#define IKOT_THREAD_CONTROL 1 +#define IKOT_TASK_CONTROL 2 #define IKOT_HOST 3 #define IKOT_HOST_PRIV 4 #define IKOT_PROCESSOR 5 @@ -135,12 +135,19 @@ typedef struct my_per_task_info { #define IKOT_TASK_RESUME 36 #define IKOT_VOUCHER 37 #define IKOT_VOUCHER_ATTR_CONTROL 38 -#define IKOT_WORK_INTERVAL 39 -#define IKOT_UX_HANDLER 40 -#define IKOT_UEXT_OBJECT 41 -#define IKOT_ARCADE_REG 42 - -#define IKOT_UNKNOWN 43 /* magic catchall */ +#define IKOT_WORK_INTERVAL 39 +#define IKOT_UX_HANDLER 40 +#define IKOT_UEXT_OBJECT 41 +#define IKOT_ARCADE_REG 42 +#define IKOT_EVENTLINK 43 +#define IKOT_TASK_INSPECT 44 +#define IKOT_TASK_READ 45 +#define IKOT_THREAD_INSPECT 46 +#define IKOT_THREAD_READ 47 +#define IKOT_SUID_CRED 48 +#define IKOT_HYPERVISOR 49 + +#define IKOT_UNKNOWN 50 /* magic catchall */ #define IKOT_MAX_TYPE (IKOT_UNKNOWN+1) /* # of IKOT_ types */ diff --git a/lsmp.tproj/port_details.c b/lsmp.tproj/port_details.c index de85246..fb888e4 100644 --- a/lsmp.tproj/port_details.c +++ b/lsmp.tproj/port_details.c @@ -35,8 +35,8 @@ const char * kobject_name(natural_t kotype) { switch (kotype) { case IKOT_NONE: return "message-queue"; - case IKOT_THREAD: return "THREAD"; - case IKOT_TASK: return "TASK"; + case IKOT_THREAD_CONTROL: return "THREAD-CONTROL"; + case IKOT_TASK_CONTROL: return "TASK-CONTROL"; case IKOT_HOST: return "HOST"; case IKOT_HOST_PRIV: return "HOST-PRIV"; case IKOT_PROCESSOR: return "PROCESSOR"; @@ -77,6 +77,13 @@ const char * kobject_name(natural_t kotype) case IKOT_UX_HANDLER: return "UX_HANDLER"; case IKOT_UEXT_OBJECT: return "UEXT_OBJECT"; case IKOT_ARCADE_REG: return "ARCADE_REG"; + case IKOT_EVENTLINK: return "EVENTLINK"; + case IKOT_TASK_INSPECT: return "TASK-INSPECT"; + case IKOT_TASK_READ: return "TASK-READ"; + case IKOT_THREAD_INSPECT: return "THREAD-INSPECT"; + case IKOT_THREAD_READ: return "THREAD-READ"; + case IKOT_SUID_CRED: return "SUID_CRED"; + case IKOT_HYPERVISOR: return "HYPERVISOR"; case IKOT_UNKNOWN: default: return "UNKNOWN"; } @@ -154,25 +161,21 @@ uint32_t show_recipe_detail(mach_voucher_attr_recipe_t recipe, char *voucher_out JSON_OBJECT_SET(json, previous_voucher, "0x%x", recipe->previous_voucher); JSON_OBJECT_SET(json, content_size, %u, recipe->content_size); - switch (recipe->key) { - case MACH_VOUCHER_ATTR_KEY_ATM: - JSON_OBJECT_SET(json, ATM_ID, %llu, *(uint64_t *)(uintptr_t)recipe->content); - len += snprintf(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX "ATM ID: %llu", *(uint64_t *)(uintptr_t)recipe->content); - break; - case MACH_VOUCHER_ATTR_KEY_IMPORTANCE: - // content may not be valid JSON, exclude - // JSON_OBJECT_SET(json, importance_info, "%s", (char *)recipe->content); - len += snprintf(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX "IMPORTANCE INFO: %s", (char *)recipe->content); - break; - case MACH_VOUCHER_ATTR_KEY_BANK: - // content may not be valid JSON, exclude - // JSON_OBJECT_SET(json, resource_accounting_info, "%s", (char *)recipe->content); - len += snprintf(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX "RESOURCE ACCOUNTING INFO: %s", (char *)recipe->content); - break; - default: - len += print_hex_data(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX, "Recipe Contents", (void *)recipe->content, MIN(recipe->content_size, lsmp_config.voucher_detail_length)); - break; - } + switch (recipe->key) { + case MACH_VOUCHER_ATTR_KEY_IMPORTANCE: + // content may not be valid JSON, exclude + // JSON_OBJECT_SET(json, importance_info, "%s", (char *)recipe->content); + len += snprintf(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX "IMPORTANCE INFO: %s", (char *)recipe->content); + break; + case MACH_VOUCHER_ATTR_KEY_BANK: + // content may not be valid JSON, exclude + // JSON_OBJECT_SET(json, resource_accounting_info, "%s", (char *)recipe->content); + len += snprintf(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX "RESOURCE ACCOUNTING INFO: %s", (char *)recipe->content); + break; + default: + len += print_hex_data(&voucher_outstr[len], safesize(maxlen - len), VOUCHER_DETAIL_PREFIX, "Recipe Contents", (void *)recipe->content, MIN(recipe->content_size, lsmp_config.voucher_detail_length)); + break; + } if (len + 1 < maxlen && voucher_outstr[len - 1] != '\n') { voucher_outstr[len++] = '\n'; @@ -628,7 +631,7 @@ static void show_task_table_entry(ipc_info_name_t *entry, my_per_task_info_t *ta } else { printf(" 0x%08x %s", (natural_t)kobject, kobject_name(kotype)); } - if ((kotype == IKOT_TASK_RESUME) || (kotype == IKOT_TASK) || (kotype == IKOT_TASK_NAME)) { + if ((kotype == IKOT_TASK_RESUME) || (kotype == IKOT_TASK_CONTROL) || (kotype == IKOT_TASK_NAME)) { if (taskinfo->task_kobject == kobject) { /* neat little optimization since in most cases tasks have themselves in their ipc space */ JSON_OBJECT_SET(json, pid, %d, taskinfo->pid); @@ -642,7 +645,7 @@ static void show_task_table_entry(ipc_info_name_t *entry, my_per_task_info_t *ta } } - if (kotype == IKOT_THREAD) { + if (kotype == IKOT_THREAD_CONTROL) { for (int i = 0; i < taskinfo->threadCount; i++) { if (taskinfo->threadInfos[i].th_kobject == kobject) { printf(" (%#llx)", taskinfo->threadInfos[i].th_id); diff --git a/lsmp.tproj/task_details.c b/lsmp.tproj/task_details.c index f642e0d..bf9ef51 100644 --- a/lsmp.tproj/task_details.c +++ b/lsmp.tproj/task_details.c @@ -237,7 +237,7 @@ kern_return_t collect_per_task_info(my_per_task_info_t *taskinfo, task_t target_ ret = mach_port_kernel_object(mach_task_self(), taskinfo->task, &kotype, (unsigned *)&kobject); - if (ret == KERN_SUCCESS && kotype == IKOT_TASK) { + if (ret == KERN_SUCCESS && kotype == IKOT_TASK_CONTROL) { taskinfo->task_kobject = kobject; taskinfo->valid = TRUE; } diff --git a/memory_pressure.tproj/memory_pressure.c b/memory_pressure.tproj/memory_pressure.c index 2b2784e..1713fcb 100644 --- a/memory_pressure.tproj/memory_pressure.c +++ b/memory_pressure.tproj/memory_pressure.c @@ -38,7 +38,7 @@ #include #include -unsigned long phys_mem = 0; /* amount of physical memory in bytes */ +long long phys_mem = 0; /* amount of physical memory in bytes */ unsigned int phys_pages = 0; /* number of physical memory pages */ int sleep_seconds = 1; int requested_hysteresis_seconds = 0; @@ -109,6 +109,22 @@ read_sysctl_int(const char* name) return var; } +static long long +read_sysctl_long_long(const char* name) +{ + long long var; + size_t var_size; + int error; + + var_size = sizeof(var); + error = sysctlbyname(name, &var, &var_size, NULL, 0); + if( error ) { + perror(name); + exit(-1); + } + return var; +} + static int get_percent_free(unsigned int* level) { @@ -172,6 +188,22 @@ print_vm_statistics(void) } } +/* + this will work for up to 64 TB of RAM -- beyond that we exceed Intel's max for VRAM (48 bits of addressable space). + By the time we get there Intel probably will have increased this + */ +static unsigned long long +get_max_range_size() +{ + unsigned long long the_max_range_size = MAX_RANGE_SIZE; + + if (phys_mem * 4 > the_max_range_size) { + the_max_range_size = phys_mem * 4; + } + + return the_max_range_size; +} + static int reached_or_bypassed_desired_result(void) { @@ -283,9 +315,13 @@ process_pages(int num_pages, int page_op) //printf("stopped faulting after %d pages\n", i); break; } - - memcpy(range_current_addr, random_data, PAGE_SIZE); - range_current_addr += PAGE_SIZE; + if ((uintptr_t)range_current_addr < get_max_range_size()) { + memcpy(range_current_addr, random_data, PAGE_SIZE); + range_current_addr += PAGE_SIZE; + } else { + printf("\nRun out of allocable memory\n"); + exit(0); + } } pthread_mutex_lock(&reference_pages_mutex); @@ -643,10 +679,10 @@ main(int argc, char * const argv[]) } } - phys_mem = read_sysctl_int("hw.physmem"); + phys_mem = read_sysctl_long_long("hw.memsize"); phys_pages = (unsigned int) (phys_mem / PAGE_SIZE); - printf("The system has %lu (%d pages with a page size of %d).\n", phys_mem, phys_pages, PAGE_SIZE); + printf("The system has %lld (%d pages with a page size of %lu).\n", phys_mem, phys_pages, PAGE_SIZE); print_vm_statistics(); @@ -712,7 +748,7 @@ main(int argc, char * const argv[]) printf("Reset system state\n"); } else { - range_start_addr = mmap(NULL, MAX_RANGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); + range_start_addr = mmap(NULL, get_max_range_size(), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0); if (range_start_addr == MAP_FAILED) { perror("mmap failed"); @@ -724,7 +760,7 @@ main(int argc, char * const argv[]) error = pthread_create(&thread, NULL, (void*) reference_pages, NULL); range_current_addr = range_start_addr; - range_end_addr = range_start_addr + MAX_RANGE_SIZE; + range_end_addr = range_start_addr + get_max_range_size(); start_allocing_pages = 1; if (desired_level) { diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c index 7bdf9c6..20d1927 100644 --- a/nvram.tproj/nvram.c +++ b/nvram.tproj/nvram.c @@ -442,23 +442,32 @@ static void ParseXMLFile(char *fileName) // SetOrGetOFVariable(str) // -// Parse the input string, then set or get the specified -// firmware variable. +// Parse the input string, then set, append or get +// the specified firmware variable. // static void SetOrGetOFVariable(char *str) { long set = 0; + long append = 0; char *name; char *value; - CFStringRef nameRef; - CFTypeRef valueRef; + CFStringRef nameRef = NULL; + CFTypeRef valueRef = NULL; + CFMutableStringRef appended = NULL; kern_return_t result; // OF variable name is first. name = str; - // Find the equal sign for set + // Find the equal sign for set or += for append while (*str) { + if (*str == '+' && *(str+1) == '=') { + append = 1; + *str++ = '\0'; + *str++ = '\0'; + break; + } + if (*str == '=') { set = 1; *str++ = '\0'; @@ -467,24 +476,8 @@ static void SetOrGetOFVariable(char *str) str++; } - if (set == 1) { - // On sets, the OF variable's value follows the equal sign. - value = str; -#if TARGET_OS_BRIDGE - if (gBridgeToIntel) { - result = SetMacOFVariable(name, value); - } - else -#endif - { - result = SetOFVariable(name, value); - NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ - } - if (result != KERN_SUCCESS) { - errx(1, "Error setting variable - '%s': %s", name, - mach_error_string(result)); - } - } else { + // Read the current value if appending or if no =/+= + if (append == 1 || (set == 0 && append == 0)) { #if TARGET_OS_BRIDGE if (gBridgeToIntel) { result = GetMacOFVariable(name, &value); @@ -505,11 +498,41 @@ static void SetOrGetOFVariable(char *str) mach_error_string(result)); } } + } + if (set == 1) { + // On sets, the OF variable's value follows the equal sign. + value = str; + } + + if (append == 1) { + // On append, the value to append follows the += substring + appended = CFStringCreateMutableCopy(NULL, 0, valueRef); + CFStringAppendCString(appended, str, kCFStringEncodingUTF8); + value = (char*)CFStringGetCStringPtr(appended, kCFStringEncodingUTF8); + } + + if (set == 1 || append == 1) { +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + result = SetMacOFVariable(name, value); + } + else +#endif + { + result = SetOFVariable(name, value); + NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ + } + if (result != KERN_SUCCESS) { + errx(1, "Error setting variable - '%s': %s", name, + mach_error_string(result)); + } + } else { PrintOFVariable(nameRef, valueRef, 0); - CFRelease(nameRef); - CFRelease(valueRef); } + if ( nameRef ) CFRelease(nameRef); + if ( valueRef ) CFRelease(valueRef); + if ( appended ) CFRelease(appended); } #if TARGET_OS_BRIDGE @@ -853,7 +876,25 @@ static void ClearOFVariable(const void *key, const void *value, void *context) result = IORegistryEntrySetCFProperty(gOptionsRef, CFSTR(kIONVRAMDeletePropertyKey), key); if (result != KERN_SUCCESS) { - errx(1, "Error clearing firmware variables: %s", mach_error_string(result)); + assert(CFGetTypeID(key) == CFStringGetTypeID()); + const char *keyStr = CFStringGetCStringPtr(key, kCFStringEncodingUTF8); + char *keyBuffer = NULL; + size_t keyBufferLen = 0; + if (!keyStr) { + keyBufferLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(key), kCFStringEncodingUTF8) + 1; + keyBuffer = (char *)malloc(keyBufferLen); + if (keyBuffer != NULL && CFStringGetCString(key, keyBuffer, keyBufferLen, kCFStringEncodingUTF8)) { + keyStr = keyBuffer; + } else { + warnx("Unable to convert property name to C string"); + keyStr = ""; + } + } + + warnx("Error clearing firmware variable %s: %s", keyStr, mach_error_string(result)); + if (keyBuffer) { + free(keyBuffer); + } } } diff --git a/passwd.tproj/passwd.c b/passwd.tproj/passwd.c index 5d243f6..877036e 100644 --- a/passwd.tproj/passwd.c +++ b/passwd.tproj/passwd.c @@ -170,6 +170,7 @@ main(int argc, char *argv[]) char* auth = NULL; int infosystem, ch; int free_user = 0; + int res = -1; #ifdef INFO_PAM infosystem = INFO_PAM; @@ -264,25 +265,36 @@ main(int argc, char *argv[]) switch (infosystem) { case INFO_FILE: - file_passwd(user, locn); + res = file_passwd(user, locn); break; #ifdef INFO_NIS case INFO_NIS: - nis_passwd(user, locn); + res = nis_passwd(user, locn); break; #endif #ifdef INFO_OPEN_DIRECTORY case INFO_OPEN_DIRECTORY: - od_passwd(user, locn, auth); + res = od_passwd(user, locn, auth); break; #endif #ifdef INFO_PAM case INFO_PAM: - pam_passwd(user); + res = pam_passwd(user); break; #endif } + if (res == 0) + { + printf("\n"); + printf("################################### WARNING ###################################\n"); + printf("# This tool does not update the login keychain password. #\n"); + printf("# To update it, run `security set-keychain-password` as the user in question, #\n"); + printf("# or as root providing a path to such user's login keychain. #\n"); + printf("###############################################################################\n"); + printf("\n"); + } + if (free_user == 1) free(user); diff --git a/passwd.tproj/passwd.entitlements b/passwd.tproj/passwd.entitlements index 6e47a16..a63c168 100644 --- a/passwd.tproj/passwd.entitlements +++ b/passwd.tproj/passwd.entitlements @@ -2,6 +2,8 @@ + com.apple.keystore.console + com.apple.private.opendirectoryd.identity com.apple.private.security.clear-library-validation diff --git a/reboot.tproj/reboot.c b/reboot.tproj/reboot.c index 372efc7..5478704 100644 --- a/reboot.tproj/reboot.c +++ b/reboot.tproj/reboot.c @@ -304,6 +304,17 @@ get_pageins(void) #if defined(__APPLE__) && !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) // XX this routine is also in shutdown.tproj; it would be nice to share +static bool +kextdDisabled(void) +{ + uint32_t disabled = 0; + size_t sizeOfDisabled = sizeof(disabled); + if (sysctlbyname("hw.use_kernelmanagerd", &disabled, &sizeOfDisabled, NULL, 0) != 0) { + return false; + } + return (disabled != 0); +} + #define WAITFORLOCK 1 /* * contact kextd to lock for reboot @@ -317,6 +328,11 @@ reserve_reboot(void) int busyStatus = ELAST + 1; mountpoint_t busyVol; + if (kextdDisabled()) { + /* no need to talk with kextd if it's not running */ + return 0; + } + macherr = bootstrap_look_up2(bootstrap_port, KEXTD_SERVER_NAME, &kxport, 0, BOOTSTRAP_PRIVILEGED_SERVER); if (macherr) goto finish; diff --git a/shutdown.tproj/shutdown.c b/shutdown.tproj/shutdown.c index 904110c..597f9f2 100644 --- a/shutdown.tproj/shutdown.c +++ b/shutdown.tproj/shutdown.c @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD: src/sbin/shutdown/shutdown.c,v 1.28 2005/01/25 08:40:51 delp #include #include #include +#include +#include #include #include @@ -717,6 +719,18 @@ audit_shutdown(int exitstatus) } +static bool +kextdDisabled(void) +{ + uint32_t disabled = 0; + size_t sizeOfDisabled = sizeof(disabled); + if (sysctlbyname("hw.use_kernelmanagerd", &disabled, &sizeOfDisabled, NULL, 0) != 0) { + return false; + } + return (disabled != 0); +} + + // XX copied from reboot.tproj/reboot.c; it would be nice to share the code #define WAITFORLOCK 1 @@ -732,6 +746,11 @@ reserve_reboot(void) int busyStatus = ELAST + 1; mountpoint_t busyVol; + if (kextdDisabled()) { + /* no need to talk with kextd if it's not running */ + return 0; + } + macherr = bootstrap_look_up2(bootstrap_port, KEXTD_SERVER_NAME, &kxport, 0, BOOTSTRAP_PRIVILEGED_SERVER); if (macherr) goto finish; diff --git a/stackshot.tproj/stackshot.c b/stackshot.tproj/stackshot.c index 0a67d50..ecb3687 100644 --- a/stackshot.tproj/stackshot.c +++ b/stackshot.tproj/stackshot.c @@ -17,7 +17,7 @@ #include -uint64_t +static uint64_t stackshot_get_mach_absolute_time(void *buffer, uint32_t size) { kcdata_iter_t iter = kcdata_iter_find_type(kcdata_iter(buffer, size), KCDATA_TYPE_MACH_ABSOLUTE_TIME); @@ -28,9 +28,9 @@ stackshot_get_mach_absolute_time(void *buffer, uint32_t size) return *(uint64_t *)kcdata_iter_payload(iter); } -static void usage(char **argv) +__dead2 static void usage(char **argv) { - fprintf (stderr, "usage: %s [-d] [-t] >file\n", argv[0]); + fprintf (stderr, "usage: %s [options] [file]\n", argv[0]); fprintf (stderr, " -d : take delta stackshot\n"); fprintf (stderr, " -b : get bootprofile\n"); fprintf (stderr, " -c : get coalition data\n"); @@ -43,10 +43,11 @@ static void usage(char **argv) fprintf (stderr, " -S : stress test: while(1) stackshot; \n"); fprintf (stderr, " -p PID : target a pid\n"); fprintf (stderr, " -E : grab existing kernel buffer\n"); + fprintf (stderr, "If no file is provided and stdout is not a TTY, the stackshot will be written to stdout.\n"); exit(1); } -void forksleep() { +static void forksleep() { pid_t pid = fork(); if (pid < 0) { perror("fork"); @@ -76,8 +77,10 @@ int main(int argc, char **argv) { boolean_t stress = FALSE; pid_t pid = -1; int c; + FILE *file; + bool closefile; - while ((c = getopt(argc, argv, "SgIikbcLdtsp:E")) != EOF) { + while ((c = getopt(argc, argv, "SgIikbcLdtsp:E")) != -1) { switch(c) { case 'I': iostats |= STACKSHOT_NO_IO_STATS; @@ -129,7 +132,19 @@ int main(int argc, char **argv) { return 1; } - if (optind < argc) { + if (optind == argc - 1) { + const char *const filename = argv[optind]; + file = fopen(filename, "wx"); + closefile = true; + + if (file == NULL) { + perror("fopen"); + return EX_CANTCREAT; + } + } else if (optind == argc && !isatty(STDOUT_FILENO)) { + file = stdout; + closefile = false; + } else { usage(argv); } @@ -215,7 +230,6 @@ top: } - if (stress) { if (config) { stackshot_config_dealloc(config); @@ -224,5 +238,11 @@ top: goto top; } - fwrite(buf, size, 1, stdout); + fwrite(buf, size, 1, file); + + if (closefile) { + fclose(file); + } + + return 0; } diff --git a/sysctl.tproj/sysctl.c b/sysctl.tproj/sysctl.c index 606459a..ca86999 100644 --- a/sysctl.tproj/sysctl.c +++ b/sysctl.tproj/sysctl.c @@ -60,6 +60,8 @@ __unused static const char rcsid[] = #include #include #include +#ifdef __APPLE__ +#endif #include #include #include @@ -748,6 +750,14 @@ show_var(int *oid, int nlen) bzero(name, BUFSIZ); qoid[0] = 0; memcpy(qoid + 2, oid, nlen * sizeof(int)); + fmt = (char *)buf; + oidfmt(oid, nlen, fmt, &kind); + +#ifdef __APPLE__ + if (!show_masked && (kind & CTLFLAG_MASKED)) { + return (1); + } +#endif #ifdef __APPLE__ // Support for CTL_USER @@ -815,20 +825,11 @@ show_var(int *oid, int nlen) return (0); } val[len] = '\0'; - fmt = (char *)buf; - oidfmt(oid, nlen, fmt, &kind); p = val; ctltype = (kind & CTLTYPE); sign = ctl_sign[ctltype]; intlen = ctl_size[ctltype]; -#ifdef __APPLE__ - if (!show_masked && (kind & CTLFLAG_MASKED)) { - free(oval); - return (1); - } -#endif - switch (ctltype) { case CTLTYPE_STRING: if (!nflag) @@ -954,6 +955,9 @@ sysctl_all_user(int *oid, int len) static int sysctl_all(int *oid, int len) { +#ifdef __APPLE__ +#endif + int name1[22], name2[22]; int i, j; size_t l1, l2; diff --git a/system_cmds.xcodeproj/project.pbxproj b/system_cmds.xcodeproj/project.pbxproj index 400fcee..ba1a85a 100644 --- a/system_cmds.xcodeproj/project.pbxproj +++ b/system_cmds.xcodeproj/project.pbxproj @@ -71,6 +71,8 @@ buildConfigurationList = BA4FD2FF1372FE4E0025925C /* Build configuration list for PBXAggregateTarget "All_MacOSX" */; buildPhases = ( C9D64CD21B91066B00CFA43B /* CopyFiles */, + 587B8CAD2489CB170001CD8D /* Copy internal getty */, + 587B8CAE2489CB9C0001CD8D /* Copy Files */, ); dependencies = ( 358407D22245AD40006A0D8E /* PBXTargetDependency */, @@ -329,6 +331,7 @@ 55CCB16E16B84EDA00B56979 /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA4B7A091373BA4600003422 /* libutil.dylib */; }; 55CCB17416B84EF800B56979 /* vm_purgeable_stat.c in Sources */ = {isa = PBXBuildFile; fileRef = 55CCB16916B84ED100B56979 /* vm_purgeable_stat.c */; }; 55CCB17616B84F3600B56979 /* vm_purgeable_stat.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 55CCB16816B84ED100B56979 /* vm_purgeable_stat.1 */; }; + 587B8CAF2489CBAD0001CD8D /* com.apple.serialdebugconsole.plist in Copy Files */ = {isa = PBXBuildFile; fileRef = 58775F6D2489B8CE0098F7DE /* com.apple.serialdebugconsole.plist */; }; 72D1FDD918C4140600C1E05F /* task_details.c in Sources */ = {isa = PBXBuildFile; fileRef = 72D1FDD818C4140600C1E05F /* task_details.c */; }; 72F9316D18C26A8600D804C5 /* port_details.c in Sources */ = {isa = PBXBuildFile; fileRef = 72F9316C18C26A8600D804C5 /* port_details.c */; }; 78DE9DFE1B504D7F00FE6DF5 /* wait4path.c in Sources */ = {isa = PBXBuildFile; fileRef = 78DE9DFC1B504D7F00FE6DF5 /* wait4path.c */; }; @@ -346,7 +349,7 @@ B3F0E6DD16E9706E008FAD09 /* memory_pressure.c in Sources */ = {isa = PBXBuildFile; fileRef = B3F0E6DC16E9706E008FAD09 /* memory_pressure.c */; }; BA0A860B13968E8500D2272C /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA4B7A091373BA4600003422 /* libutil.dylib */; }; BA0A861313968EAD00D2272C /* zprint.c in Sources */ = {isa = PBXBuildFile; fileRef = BA4FD2E61372FAFA0025925C /* zprint.c */; }; - BA0A861413968EB100D2272C /* zprint.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA4FD2E51372FAFA0025925C /* zprint.1 */; }; + BA0A861413968EB100D2272C /* zprint.1 in Copy man page */ = {isa = PBXBuildFile; fileRef = BA4FD2E51372FAFA0025925C /* zprint.1 */; }; BA28FB891396DA8A004986CB /* private in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA28FB851396DA01004986CB /* private */; }; BA4B79CF1373A74B00003422 /* dmesg.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA4FD2201372FAFA0025925C /* dmesg.8 */; }; BA4B79D01373A74F00003422 /* dmesg.c in Sources */ = {isa = PBXBuildFile; fileRef = BA4FD2211372FAFA0025925C /* dmesg.c */; }; @@ -517,12 +520,15 @@ C96F50BD15BDFEFB008682F7 /* lsmp.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C96F50AC15BDCBF0008682F7 /* lsmp.1 */; }; C96F50BE15BDFF03008682F7 /* lsmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C96F50AD15BDCE8E008682F7 /* lsmp.c */; }; C9779F6E159A2A0C009436FD /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA4B7A091373BA4600003422 /* libutil.dylib */; }; - C99490E52090F56F00246D9D /* zprint.lua in CopyFiles */ = {isa = PBXBuildFile; fileRef = C99490E32090F55D00246D9D /* zprint.lua */; }; + C99490E52090F56F00246D9D /* zprint.lua in Copy Lua library */ = {isa = PBXBuildFile; fileRef = C99490E32090F55D00246D9D /* zprint.lua */; }; C9D64CD11B91065D00CFA43B /* system_cmds.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = C9D64CCF1B91063200CFA43B /* system_cmds.plist */; }; C9D64CD31B91067500CFA43B /* system_cmds.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = C9D64CCF1B91063200CFA43B /* system_cmds.plist */; }; C9E0691A1C58BD7E00C956EB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BA9B766D13739D27001BB39F /* CoreFoundation.framework */; }; C9E0691C1C58BDA000C956EB /* CoreSymbolication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9E0691B1C58BDA000C956EB /* CoreSymbolication.framework */; }; C9E0691E1C58BDB800C956EB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9E0691D1C58BDB800C956EB /* IOKit.framework */; }; + CEB165CC246C599A00228592 /* test_zprint.lua in CopyFiles */ = {isa = PBXBuildFile; fileRef = CEB165CB246C599A00228592 /* test_zprint.lua */; }; + CEB165CE246C59C100228592 /* test_zprint.lua in Copy test */ = {isa = PBXBuildFile; fileRef = CEB165CB246C599A00228592 /* test_zprint.lua */; }; + D37CC32C2395D9F100288C74 /* mslutil.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0D06BC671E8F0B4100C6EC2D /* mslutil.1 */; }; F2291F551FFEBB6A00161936 /* CoreSymbolication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9E0691B1C58BDA000C956EB /* CoreSymbolication.framework */; }; F2291F601FFEBB9E00161936 /* zlog.c in Sources */ = {isa = PBXBuildFile; fileRef = F2291F5F1FFEBB9E00161936 /* zlog.c */; }; F27B70282044CB40003C04FC /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F27B70272044CB40003C04FC /* CoreFoundation.framework */; }; @@ -535,6 +541,8 @@ isa = PBXBuildRule; compilerSpec = com.apple.compilers.proxy.script; fileType = pattern.proxy; + inputFiles = ( + ); isEditable = 1; outputFiles = ( "$(DERIVED_SOURCES_DIR)/$(CURRENT_ARCH)/darwin_version.c", @@ -1731,9 +1739,10 @@ 0D06BC5C1E8F08CB00C6EC2D /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; + dstPath = /usr/local/share/man/man1; dstSubfolderSpec = 0; files = ( + D37CC32C2395D9F100288C74 /* mslutil.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; @@ -1787,6 +1796,17 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 587B8CAE2489CB9C0001CD8D /* Copy Files */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /AppleInternal/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 587B8CAF2489CBAD0001CD8D /* com.apple.serialdebugconsole.plist in Copy Files */, + ); + name = "Copy Files"; + runOnlyForDeploymentPostprocessing = 1; + }; 78DE9DDE1B5045DE00FE6DF5 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -1837,14 +1857,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - BA0A860C13968E8500D2272C /* CopyFiles */ = { + BA0A860C13968E8500D2272C /* Copy man page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1; dstSubfolderSpec = 0; files = ( - BA0A861413968EB100D2272C /* zprint.1 in CopyFiles */, + BA0A861413968EB100D2272C /* zprint.1 in Copy man page */, ); + name = "Copy man page"; runOnlyForDeploymentPostprocessing = 1; }; BA28FB881396DA67004986CB /* CopyFiles */ = { @@ -2310,14 +2331,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - C99490E22090F53B00246D9D /* CopyFiles */ = { + C99490E22090F53B00246D9D /* Copy Lua library */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /usr/local/share/recon; dstSubfolderSpec = 0; files = ( - C99490E52090F56F00246D9D /* zprint.lua in CopyFiles */, + C99490E52090F56F00246D9D /* zprint.lua in Copy Lua library */, ); + name = "Copy Lua library"; runOnlyForDeploymentPostprocessing = 1; }; C9D64CD01B91064700CFA43B /* CopyFiles */ = { @@ -2337,7 +2359,19 @@ dstSubfolderSpec = 0; files = ( C9D64CD31B91067500CFA43B /* system_cmds.plist in CopyFiles */, + CEB165CC246C599A00228592 /* test_zprint.lua in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + CEB165CD246C599F00228592 /* Copy test */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /AppleInternal/Tests/system_cmds; + dstSubfolderSpec = 0; + files = ( + CEB165CE246C59C100228592 /* test_zprint.lua in Copy test */, ); + name = "Copy test"; runOnlyForDeploymentPostprocessing = 1; }; F29F5A5E203E532B005B0099 /* CopyFiles */ = { @@ -2377,6 +2411,8 @@ 55CCB16816B84ED100B56979 /* vm_purgeable_stat.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = vm_purgeable_stat.1; sourceTree = ""; }; 55CCB16916B84ED100B56979 /* vm_purgeable_stat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vm_purgeable_stat.c; sourceTree = ""; }; 55CCB17316B84EDA00B56979 /* vm_purgeable_stat */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = vm_purgeable_stat; sourceTree = BUILT_PRODUCTS_DIR; }; + 58775F6B2489B8AA0098F7DE /* com.apple.getty.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.getty.internal.plist; sourceTree = ""; }; + 58775F6D2489B8CE0098F7DE /* com.apple.serialdebugconsole.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.serialdebugconsole.plist; sourceTree = ""; }; 72D1FDD818C4140600C1E05F /* task_details.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = task_details.c; path = lsmp.tproj/task_details.c; sourceTree = SOURCE_ROOT; }; 72F9316B18C269E500D804C5 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = lsmp.tproj/common.h; sourceTree = SOURCE_ROOT; }; 72F9316C18C26A8600D804C5 /* port_details.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = port_details.c; path = lsmp.tproj/port_details.c; sourceTree = SOURCE_ROOT; }; @@ -2477,7 +2513,7 @@ BA4FD22C1372FAFA0025925C /* dynamic_pager.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = dynamic_pager.8; sourceTree = ""; }; BA4FD22D1372FAFA0025925C /* dynamic_pager.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dynamic_pager.c; sourceTree = ""; }; BA4FD2301372FAFA0025925C /* fs_usage.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = fs_usage.1; sourceTree = ""; }; - BA4FD2311372FAFA0025925C /* fs_usage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fs_usage.c; sourceTree = ""; }; + BA4FD2311372FAFA0025925C /* fs_usage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fs_usage.c; sourceTree = ""; usesTabs = 1; }; BA4FD2351372FAFA0025925C /* confstr.gperf */ = {isa = PBXFileReference; lastKnownFileType = text; path = confstr.gperf; sourceTree = ""; }; BA4FD2361372FAFA0025925C /* fake-gperf.awk */ = {isa = PBXFileReference; lastKnownFileType = text; path = "fake-gperf.awk"; sourceTree = ""; }; BA4FD2371372FAFA0025925C /* getconf.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = getconf.1; sourceTree = ""; }; @@ -2651,6 +2687,7 @@ C9D64CCF1B91063200CFA43B /* system_cmds.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = system_cmds.plist; path = tests/system_cmds.plist; sourceTree = ""; }; C9E0691B1C58BDA000C956EB /* CoreSymbolication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSymbolication.framework; path = System/Library/PrivateFrameworks/CoreSymbolication.framework; sourceTree = SDKROOT; }; C9E0691D1C58BDB800C956EB /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + CEB165CB246C599A00228592 /* test_zprint.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_zprint.lua; sourceTree = ""; }; F2291F5D1FFEBB6A00161936 /* zlog */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = zlog; sourceTree = BUILT_PRODUCTS_DIR; }; F2291F5F1FFEBB9E00161936 /* zlog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = zlog.c; sourceTree = ""; }; F27B70272044CB40003C04FC /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; @@ -3461,6 +3498,8 @@ children = ( BA4FD2401372FAFA0025925C /* chat.c */, BA4FD2411372FAFA0025925C /* com.apple.getty.plist */, + 58775F6D2489B8CE0098F7DE /* com.apple.serialdebugconsole.plist */, + 58775F6B2489B8AA0098F7DE /* com.apple.getty.internal.plist */, BA4FD2421372FAFA0025925C /* extern.h */, BA4FD2431372FAFA0025925C /* getty.8 */, BA4FD2441372FAFA0025925C /* gettytab.5 */, @@ -3741,6 +3780,7 @@ BA4FD2E31372FAFA0025925C /* zprint.tproj */ = { isa = PBXGroup; children = ( + CEB165CB246C599A00228592 /* test_zprint.lua */, C99490E32090F55D00246D9D /* zprint.lua */, FEBEE5CF1B0EACEB00166A8B /* entitlements.plist */, BA4FD2E51372FAFA0025925C /* zprint.1 */, @@ -4149,8 +4189,9 @@ buildPhases = ( BA0A860813968E8500D2272C /* Sources */, BA0A860A13968E8500D2272C /* Frameworks */, - BA0A860C13968E8500D2272C /* CopyFiles */, - C99490E22090F53B00246D9D /* CopyFiles */, + BA0A860C13968E8500D2272C /* Copy man page */, + C99490E22090F53B00246D9D /* Copy Lua library */, + CEB165CD246C599F00228592 /* Copy test */, ); buildRules = ( ); @@ -4846,7 +4887,6 @@ BA2DE9181372FA9100D1913C /* Project object */ = { isa = PBXProject; attributes = { - DefaultBuildSystemTypeForWorkspace = Original; LastUpgradeCheck = 0600; TargetAttributes = { 08CE3D281E6E22A200DF1B78 = { @@ -5054,6 +5094,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = BA2DE9161372FA9100D1913C; @@ -5131,6 +5172,26 @@ /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ + 587B8CAD2489CB170001CD8D /* Copy internal getty */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "$(SRCROOT)/getty.tproj/com.apple.getty.internal.plist", + ); + name = "Copy internal getty"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DSTROOT)/AppleInternal/Library/LaunchDaemons/com.apple.getty.plist", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "cp -f \"${SCRIPT_INPUT_FILE_0}\" \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + }; BA4B79F91373B6A400003422 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -5183,7 +5244,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = ". \"${SRCROOT}/getty.tproj/generate_plist.sh\""; + shellScript = ". \"${SRCROOT}/getty.tproj/generate_plist.sh\"\n"; }; BA4FD335137306050025925C /* ShellScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/system_cmds.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/system_cmds.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings index a3f43a8..ff23ebc 100644 --- a/system_cmds.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ b/system_cmds.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -2,9 +2,9 @@ - BuildSystemType - Original IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded + PreviewsEnabled + diff --git a/system_cmds.xcodeproj/xcshareddata/xcschemes/All_MacOSX.xcscheme b/system_cmds.xcodeproj/xcshareddata/xcschemes/All_MacOSX.xcscheme index 4a3bb2e..0510fcf 100644 --- a/system_cmds.xcodeproj/xcshareddata/xcschemes/All_MacOSX.xcscheme +++ b/system_cmds.xcodeproj/xcshareddata/xcschemes/All_MacOSX.xcscheme @@ -1,7 +1,7 @@ + version = "1.8"> @@ -29,8 +29,6 @@ shouldUseLaunchSchemeArgsEnv = "YES"> - - - - BATSConfigVersion 0.1.0 IgnoreCrashes - - + Project system_cmds IgnoreOutput @@ -28,13 +27,11 @@ -all IgnoreCrashes - - + TestName test_lsmp TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -48,17 +45,14 @@ /usr/sbin/lsof IgnoreCrashes - - + TestName test_lsof TestSpecificLogs - - + WorkingDirectory /tmp/ - Arch platform-native @@ -69,13 +63,30 @@ /usr/bin/zprint IgnoreCrashes - - + TestName test_zprint TestSpecificLogs + + WorkingDirectory + /tmp/ + + + Arch + platform-native + AsRoot + + Command + recon + /AppleInternal/Tests/system_cmds/test_zprint.lua + IgnoreCrashes + + TestName + test_zprint_lua + TestSpecificLogs + WorkingDirectory /tmp/ @@ -89,13 +100,11 @@ /usr/bin/hostinfo IgnoreCrashes - - + TestName test_hostinfo TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -109,13 +118,11 @@ /usr/local/bin/ltop IgnoreCrashes - - + TestName test_ltop TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -129,13 +136,11 @@ /usr/bin/vm_stat IgnoreCrashes - - + TestName test_vm_stat TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -149,13 +154,11 @@ /sbin/dmesg IgnoreCrashes - - + TestName test_dmesg TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -170,13 +173,11 @@ -a IgnoreCrashes - - + TestName test_sysctl TestSpecificLogs - - + WorkingDirectory /tmp/ @@ -200,13 +201,11 @@ IgnoreCrashes - - + TestName test_proc_uuid_policy TestSpecificLogs - - + WorkingDirectory /tmp/ diff --git a/zic.tproj/build_zichost.sh b/zic.tproj/build_zichost.sh index 9247765..69711cc 100755 --- a/zic.tproj/build_zichost.sh +++ b/zic.tproj/build_zichost.sh @@ -13,6 +13,7 @@ BUILT_PRODUCTS_DIR="$1" # run on the build machine. Build a dedicate copy of zic # for processing zoneinfo files +ZICHOST_OBJROOT="${BUILT_PRODUCTS_DIR}/zic_host-objroot" ZICHOST_SYMROOT="${BUILT_PRODUCTS_DIR}/zic_host-sym" ZICHOST_DSTROOT="${BUILT_PRODUCTS_DIR}/zic_host-dst" ZICHOST="${ZICHOST_DSTROOT}/zic_host" @@ -41,7 +42,7 @@ env -i \ -target zic \ -sdk "macosxinternal" \ SRCROOT="${SRCROOT}" \ - OBJROOT="${OBJROOT}" \ + OBJROOT="${ZICHOST_OBJROOT}" \ SYMROOT="${ZICHOST_SYMROOT}" \ DSTROOT="${ZICHOST_DSTROOT}" \ ARCHS='$(NATIVE_ARCH_ACTUAL)' \ diff --git a/zic.tproj/generate_zoneinfo.sh b/zic.tproj/generate_zoneinfo.sh index feef097..2f25d1c 100755 --- a/zic.tproj/generate_zoneinfo.sh +++ b/zic.tproj/generate_zoneinfo.sh @@ -60,7 +60,7 @@ if [ $? -ne 0 ]; then fi chmod -R og-w "${ZONEINFO}" -for f in "zone.tab" "iso3166.tab"; do +for f in "zone.tab" "iso3166.tab" "leapseconds"; do install -m 0444 "${DATFILES}/$f" "${ZONEINFO}/$f" || exit 1 done if [ $? -ne 0 ]; then diff --git a/zlog.tproj/zlog.c b/zlog.tproj/zlog.c index c08b8bc..c091120 100644 --- a/zlog.tproj/zlog.c +++ b/zlog.tproj/zlog.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -184,6 +185,18 @@ static void list_zones_with_zlog_enabled(void) #define VERSION_STRING "zlog output version: 1" +static void +get_osversion(char *buffer, size_t buffer_len) +{ + int mib[] = {CTL_KERN, KERN_OSVERSION}; + int ret; + ret = sysctl(mib, sizeof(mib) / sizeof(int), buffer, &buffer_len, NULL, 0); + if (ret != 0) { + strlcpy(buffer, "Unknown", buffer_len); + return; + } +} + int main(int argc, char *argv[]) { int c, topN = 0; @@ -191,6 +204,9 @@ int main(int argc, char *argv[]) /* Identifier string for SpeedTracer parsing */ printf("%s\n\n", VERSION_STRING); + char version_buffer[32] = {0}; + get_osversion(version_buffer, sizeof(version_buffer)); + printf("Collected on build: %s\n\n", version_buffer); if (argc == 1) { /* default when no arguments are specified */ diff --git a/zprint.tproj/entitlements.plist b/zprint.tproj/entitlements.plist index 50ad69c..600122d 100644 --- a/zprint.tproj/entitlements.plist +++ b/zprint.tproj/entitlements.plist @@ -2,10 +2,6 @@ - com.apple.system-task-ports - - task_for_pid-allow - com.apple.private.kernel.get-kext-info diff --git a/zprint.tproj/test_zprint.lua b/zprint.tproj/test_zprint.lua new file mode 100644 index 0000000..b46d6ca --- /dev/null +++ b/zprint.tproj/test_zprint.lua @@ -0,0 +1,89 @@ +#!/usr/local/bin/recon + +local darwin = require 'darwin' +local proc = require 'proc' +local zprint = require 'zprint' + +if darwin.geteuid() ~= 0 then + io.stderr:write(arg[0], ': must be run as root (under sudo)\n') + os.exit(1) +end + +local function test_output(zpout) + -- These should be present in the output of zprint. + local expectations = { + { + region = 'zones', + name = 'vm.pages', + }, { + region = 'tags', + name = 'VM_KERN_MEMORY_DIAG', + }, { + region = 'maps', + name = 'VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE', + }, { + region = 'zone_views', + -- This ties the kernel's hands when it comes to naming. + name = 'data.kalloc.16[raw]', + } + } + + local found_all = true + for i = 1, #expectations do + local region = expectations[i].region + local name = expectations[i].name + local iter = zprint[region] + if not iter then + io.stderr:write('zprint library has no iterator for ', region, '\n') + os.exit(4) + end + + local found = false + for elt in zprint[region](zpout) do + if elt.name == name then + found = true + break + end + end + if found then + io.stdout:write('PASS: found ', name, ' in ', region, '\n') + else + io.stdout:write('FAIL: could not find ', name, ' in ', region, '\n') + found_all = false + end + end + return found_all +end + +local function run_zprint(args) + if not args then + args = {} + end + + table.insert(args, 1, 'zprint') + local zpout, err, status, code = proc.run(args) + if not zpout then + io.stderr:write(arg[0], ': failed to run zprint: ', err, '\n') + os.exit(2) + end + + if code ~= 0 then + io.stderr:write(arg[0], ': zprint ', status, 'ed with code ', tostring(code), + ', stderr = ', err, '\n') + os.exit(3) + end + return zpout +end + +local function run_and_test(...) + local zpout = run_zprint(table.pack(...)) + local passed = test_output(zpout) + if not passed then + os.exit(5) + end +end + +print("TEST: zprint output") +run_and_test() +print("\nTEST: zprint -t output") +run_and_test("-t") diff --git a/zprint.tproj/zprint.c b/zprint.tproj/zprint.c index a968dc3..5c90f2d 100644 --- a/zprint.tproj/zprint.c +++ b/zprint.tproj/zprint.c @@ -85,10 +85,14 @@ #include #include -#define streql(a, b) (strcmp((a), (b)) == 0) -#define strneql(a, b, n) (strncmp((a), (b), (n)) == 0) -#define PRINTK(fmt, value) \ - printf(fmt "K", (value) / 1024 ) /* ick */ +#ifndef VM_KERN_SITE_ZONE_VIEW +#define VM_KERN_SITE_ZONE_VIEW 0x00001000 +#endif + +#define streql(a, b) (strcmp((a), (b)) == 0) +#define strneql(a, b, n) (strncmp((a), (b), (n)) == 0) +#define PRINTK(fmt, value) \ + printf(fmt "K", (value) / 1024 ) /* ick */ static void usage(FILE *stream); static void printzone(mach_zone_name_t *, mach_zone_info_t *); @@ -100,9 +104,9 @@ static boolean_t substr(const char *a, size_t alen, const char *b, size_t blen); static int SortName(void * thunk, const void * left, const void * right); static int SortSize(void * thunk, const void * left, const void * right); static void PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt, - mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames, - unsigned int zoneCnt, uint64_t zoneElements, - int (*func)(void *, const void *, const void *), boolean_t column); + mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames, + unsigned int zoneCnt, uint64_t zoneElements, + int (*func)(void *, const void *, const void *), boolean_t column); static char *program; @@ -122,8 +126,8 @@ static unsigned long long totalcollectable = 0; static int last_time = 0; -static char *zname = NULL; -static size_t znamelen = 0; +static char *zname = NULL; +static size_t znamelen = 0; #define LEFTALIGN -1 #define RIGHTALIGN 1 @@ -158,20 +162,20 @@ enum { * the order in which the values are printed in colprintzone(). */ static column_format columns[] = { - [COL_ZONE_NAME] = { "", "zone name", 25, LEFTALIGN, true }, - [COL_ELEM_SIZE] = { "elem", "size", 6, RIGHTALIGN, true }, - [COL_CUR_SIZE] = { "cur", "size", 11, RIGHTALIGN, true }, - [COL_MAX_SIZE] = { "max", "size", 11, RIGHTALIGN, true }, - [COL_CUR_ELTS] = { "cur", "#elts", 10, RIGHTALIGN, true }, - [COL_MAX_ELTS] = { "max", "#elts", 11, RIGHTALIGN, true }, - [COL_CUR_INUSE] = { "cur", "inuse", 11, RIGHTALIGN, true }, - [COL_ALLOC_SIZE] = { "alloc", "size", 6, RIGHTALIGN, true }, - [COL_ALLOC_COUNT] = { "alloc", "count", 6, RIGHTALIGN, true }, - [COL_ZONE_FLAGS] = { "", "", 2, RIGHTALIGN, true }, - /* additional columns for special flags, not visible by default */ - [COL_FRAG_SIZE] = { "frag", "size", 9, RIGHTALIGN, false }, - [COL_FREE_SIZE] = { "free", "size", 9, RIGHTALIGN, false }, - [COL_TOTAL_ALLOCS] = { "total", "allocs", 17, RIGHTALIGN, false } + [COL_ZONE_NAME] = { "", "zone name", 25, LEFTALIGN, true }, + [COL_ELEM_SIZE] = { "elem", "size", 6, RIGHTALIGN, true }, + [COL_CUR_SIZE] = { "cur", "size", 11, RIGHTALIGN, true }, + [COL_MAX_SIZE] = { "max", "size", 11, RIGHTALIGN, true }, + [COL_CUR_ELTS] = { "cur", "#elts", 10, RIGHTALIGN, true }, + [COL_MAX_ELTS] = { "max", "#elts", 11, RIGHTALIGN, true }, + [COL_CUR_INUSE] = { "cur", "inuse", 11, RIGHTALIGN, true }, + [COL_ALLOC_SIZE] = { "alloc", "size", 6, RIGHTALIGN, true }, + [COL_ALLOC_COUNT] = { "alloc", "count", 6, RIGHTALIGN, true }, + [COL_ZONE_FLAGS] = { "", "", 2, RIGHTALIGN, true }, + /* additional columns for special flags, not visible by default */ + [COL_FRAG_SIZE] = { "frag", "size", 9, RIGHTALIGN, false }, + [COL_FREE_SIZE] = { "free", "size", 9, RIGHTALIGN, false }, + [COL_TOTAL_ALLOCS] = { "total", "allocs", 17, RIGHTALIGN, false } }; static void @@ -207,71 +211,73 @@ main(int argc, char **argv) mach_memory_info_t *wiredInfo = NULL; unsigned int wiredInfoCnt = 0; mach_zone_info_t *max_info = NULL; - char *deltas = NULL; + char *deltas = NULL; uint64_t zoneElements; - kern_return_t kr; - int i, j; - int first_time = 1; - int must_print = 1; - int interval = 1; + kern_return_t kr; + int i, j; + int first_time = 1; + int must_print = 1; + int interval = 1; signal(SIGINT, sigintr); program = strrchr(argv[0], '/'); - if (program == NULL) + if (program == NULL) { program = argv[0]; - else + } else { program++; + } for (i = 1; i < argc; i++) { - if (streql(argv[i], "-d")) + if (streql(argv[i], "-d")) { ShowDeltas = TRUE; - else if (streql(argv[i], "-t")) + } else if (streql(argv[i], "-t")) { ShowTotal = TRUE; - else if (streql(argv[i], "-T")) + } else if (streql(argv[i], "-T")) { ShowTotal = FALSE; - else if (streql(argv[i], "-w")) + } else if (streql(argv[i], "-w")) { ShowWasted = TRUE; - else if (streql(argv[i], "-W")) + } else if (streql(argv[i], "-W")) { ShowWasted = FALSE; - else if (streql(argv[i], "-l")) + } else if (streql(argv[i], "-l")) { ShowLarge = TRUE; - else if (streql(argv[i], "-L")) + } else if (streql(argv[i], "-L")) { ShowLarge = FALSE; - else if (streql(argv[i], "-s")) + } else if (streql(argv[i], "-s")) { SortZones = TRUE; - else if (streql(argv[i], "-S")) + } else if (streql(argv[i], "-S")) { SortZones = FALSE; - else if (streql(argv[i], "-c")) + } else if (streql(argv[i], "-c")) { ColFormat = TRUE; - else if (streql(argv[i], "-C")) + } else if (streql(argv[i], "-C")) { ColFormat = FALSE; - else if (streql(argv[i], "-h")) + } else if (streql(argv[i], "-h")) { usage(stdout); - else if (streql(argv[i], "-H")) + } else if (streql(argv[i], "-H")) { PrintHeader = FALSE; - else if (streql(argv[i], "--")) { + } else if (streql(argv[i], "--")) { i++; break; - } else if (argv[i][0] == '-') + } else if (argv[i][0] == '-') { usage(stderr); - else + } else { break; + } } switch (argc - i) { - case 0: + case 0: zname = ""; znamelen = 0; break; - case 1: + case 1: zname = argv[i]; znamelen = strlen(zname); break; - default: + default: usage(stderr); } @@ -291,17 +297,17 @@ main(int argc, char **argv) for (;;) { kr = mach_memory_info(mach_host_self(), - &name, &nameCnt, &info, &infoCnt, - &wiredInfo, &wiredInfoCnt); + &name, &nameCnt, &info, &infoCnt, + &wiredInfo, &wiredInfoCnt); if (kr != KERN_SUCCESS) { fprintf(stderr, "%s: mach_memory_info: %s (try running as root)\n", - program, mach_error_string(kr)); + program, mach_error_string(kr)); exit(1); } if (nameCnt != infoCnt) { fprintf(stderr, "%s: mach_zone_name/ mach_zone_info: counts not equal?\n", - program); + program); exit(1); } @@ -311,16 +317,16 @@ main(int argc, char **argv) } if (SortZones) { - for (i = 0; i < nameCnt-1; i++) { - for (j = i+1; j < nameCnt; j++) { + for (i = 0; i < nameCnt - 1; i++) { + for (j = i + 1; j < nameCnt; j++) { unsigned long long wastei, wastej; wastei = (info[i].mzi_cur_size - - (info[i].mzi_elem_size * - info[i].mzi_count)); + (info[i].mzi_elem_size * + info[i].mzi_count)); wastej = (info[j].mzi_cur_size - - (info[j].mzi_elem_size * - info[j].mzi_count)); + (info[j].mzi_elem_size * + info[j].mzi_count)); if (wastej > wastei) { mach_zone_info_t tinfo; @@ -342,16 +348,18 @@ main(int argc, char **argv) zoneElements = 0; if (must_print) { if (ColFormat) { - if (!first_time) + if (!first_time) { printf("\n"); + } colprintzoneheader(); } for (i = 0; i < nameCnt; i++) { if (deltas[i]) { - if (ColFormat) + if (ColFormat) { colprintzone(&name[i], &info[i]); - else + } else { printzone(&name[i], &info[i]); + } zoneElements += info[i].mzi_count; } } @@ -359,43 +367,43 @@ main(int argc, char **argv) if (ShowLarge && first_time) { PrintLarge(wiredInfo, wiredInfoCnt, &info[0], &name[0], - nameCnt, zoneElements, - SortZones ? &SortSize : &SortName, ColFormat); + nameCnt, zoneElements, + SortZones ? &SortSize : &SortName, ColFormat); } first_time = 0; if ((name != NULL) && (nameCnt != 0)) { kr = vm_deallocate(mach_task_self(), (vm_address_t) name, - (vm_size_t) (nameCnt * sizeof *name)); + (vm_size_t) (nameCnt * sizeof *name)); if (kr != KERN_SUCCESS) { fprintf(stderr, "%s: vm_deallocate: %s\n", - program, mach_error_string(kr)); + program, mach_error_string(kr)); exit(1); } } if ((info != NULL) && (infoCnt != 0)) { kr = vm_deallocate(mach_task_self(), (vm_address_t) info, - (vm_size_t) (infoCnt * sizeof *info)); + (vm_size_t) (infoCnt * sizeof *info)); if (kr != KERN_SUCCESS) { fprintf(stderr, "%s: vm_deallocate: %s\n", - program, mach_error_string(kr)); + program, mach_error_string(kr)); exit(1); } } if ((wiredInfo != NULL) && (wiredInfoCnt != 0)) { kr = vm_deallocate(mach_task_self(), (vm_address_t) wiredInfo, - (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo)); + (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo)); if (kr != KERN_SUCCESS) { fprintf(stderr, "%s: vm_deallocate: %s\n", - program, mach_error_string(kr)); + program, mach_error_string(kr)); exit(1); } } - if ((ShowWasted||ShowTotal) && PrintHeader && !ShowDeltas) { + if ((ShowWasted || ShowTotal) && PrintHeader && !ShowDeltas) { printf("\nZONE TOTALS\n"); printf("---------------------------------------------\n"); printf("TOTAL SIZE = %llu\n", totalsize); @@ -405,16 +413,18 @@ main(int argc, char **argv) printf("TOTAL FRAGMENTED = %llu\n", totalfragmented); printf("TOTAL COLLECTABLE = %llu\n", totalcollectable); } - if (ShowTotal) + if (ShowTotal) { printf("TOTAL ALLOCS = %llu\n", totalsum); + } } - if (ShowDeltas == FALSE || last_time) + if (ShowDeltas == FALSE || last_time) { break; + } sleep(interval); } - exit(0); + exit(0); } static boolean_t @@ -422,11 +432,15 @@ substr(const char *a, size_t alen, const char *b, size_t blen) { int i; - if (alen > blen) return FALSE; + if (alen > blen) { + return FALSE; + } - for (i = 0; i <= blen - alen; i++) - if (strneql(a, b+i, alen)) + for (i = 0; i <= blen - alen; i++) { + if (strneql(a, b + i, alen)) { return TRUE; + } + } return FALSE; } @@ -438,25 +452,27 @@ printzone(mach_zone_name_t *name, mach_zone_info_t *info) printf("%.*s zone:\n", (int)sizeof name->mzn_name, name->mzn_name); printf("\tcur_size: %lluK bytes (%llu elements)\n", - info->mzi_cur_size/1024, - (info->mzi_elem_size == 0) ? 0 : - info->mzi_cur_size/info->mzi_elem_size); + info->mzi_cur_size / 1024, + (info->mzi_elem_size == 0) ? 0 : + info->mzi_cur_size / info->mzi_elem_size); printf("\tmax_size: %lluK bytes (%llu elements)\n", - info->mzi_max_size/1024, - (info->mzi_elem_size == 0) ? 0 : - info->mzi_max_size/info->mzi_elem_size); + info->mzi_max_size / 1024, + (info->mzi_elem_size == 0) ? 0 : + info->mzi_max_size / info->mzi_elem_size); printf("\telem_size: %llu bytes\n", - info->mzi_elem_size); + info->mzi_elem_size); printf("\t# of elems: %llu\n", - info->mzi_count); + info->mzi_count); printf("\talloc_size: %lluK bytes (%llu elements)\n", - info->mzi_alloc_size/1024, - (info->mzi_elem_size == 0) ? 0 : - info->mzi_alloc_size/info->mzi_elem_size); - if (info->mzi_exhaustible) + info->mzi_alloc_size / 1024, + (info->mzi_elem_size == 0) ? 0 : + info->mzi_alloc_size / info->mzi_elem_size); + if (info->mzi_exhaustible) { printf("\tEXHAUSTIBLE\n"); - if (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable)) + } + if (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable)) { printf("\tCOLLECTABLE\n"); + } if (ShowWasted) { totalused += used = info->mzi_elem_size * info->mzi_count; totalsize += size = info->mzi_cur_size; @@ -501,25 +517,25 @@ colprintzone(mach_zone_name_t *zone_name, mach_zone_info_t *info) } -#define PRINTCOL(value, index) \ - if (columns[(index)].visible) { \ - printf(" %*llu", columns[(index)].colwidth * columns[(index)].alignment, (value)); \ +#define PRINTCOL(value, index) \ + if (columns[(index)].visible) { \ + printf(" %*llu", columns[(index)].colwidth * columns[(index)].alignment, (value)); \ } -#define PRINTCOLSTR(value, index) \ - if (columns[(index)].visible) { \ - printf(" %*s", columns[(index)].colwidth * columns[(index)].alignment, (value)); \ +#define PRINTCOLSTR(value, index) \ + if (columns[(index)].visible) { \ + printf(" %*s", columns[(index)].colwidth * columns[(index)].alignment, (value)); \ } -#define PRINTCOLK(value, index) \ - if (columns[(index)].visible) { \ - printf(" %*lluK", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value) / 1024 ); \ +#define PRINTCOLK(value, index) \ + if (columns[(index)].visible) { \ + printf(" %*lluK", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value) / 1024 ); \ } -#define PRINTCOLSZ(value, index) \ - if (columns[(index)].visible) { \ - if ((value) < 1024) { \ - printf(" %*lluB", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value)); \ - } else { \ - PRINTCOLK(value, index) \ - } \ +#define PRINTCOLSZ(value, index) \ + if (columns[(index)].visible) { \ + if ((value) < 1024) { \ + printf(" %*lluB", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value)); \ + } else { \ + PRINTCOLK(value, index) \ + } \ } @@ -551,8 +567,8 @@ colprintzone(mach_zone_name_t *zone_name, mach_zone_info_t *info) totalfragmented += fragmented = size - used - collectable; printf(" %c%c", - (info->mzi_exhaustible ? 'X' : ' '), - (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable) ? 'C' : ' ')); + (info->mzi_exhaustible ? 'X' : ' '), + (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable) ? 'C' : ' ')); PRINTCOLSZ(fragmented, COL_FRAG_SIZE); PRINTCOLSZ(collectable, COL_FREE_SIZE); @@ -567,7 +583,7 @@ colprintzoneheader(void) { int i, totalwidth = 0; - if (! PrintHeader) { + if (!PrintHeader) { return; } @@ -594,27 +610,27 @@ colprintzoneheader(void) int find_deltas(mach_zone_name_t *name, mach_zone_info_t *info, mach_zone_info_t *max_info, - char *deltas, int cnt, int first_time) + char *deltas, int cnt, int first_time) { - int i; - int found_one = 0; - - for (i = 0; i < cnt; i++) { - deltas[i] = 0; - if (substr(zname, znamelen, name[i].mzn_name, - strnlen(name[i].mzn_name, sizeof name[i].mzn_name))) { - if (first_time || info->mzi_cur_size > max_info->mzi_cur_size || - (ShowTotal && ((info->mzi_sum_size >> 1) > max_info->mzi_sum_size))) { - max_info->mzi_cur_size = info->mzi_cur_size; - max_info->mzi_sum_size = info->mzi_sum_size; - deltas[i] = 1; - found_one = 1; - } - } - info++; - max_info++; - } - return(found_one); + int i; + int found_one = 0; + + for (i = 0; i < cnt; i++) { + deltas[i] = 0; + if (substr(zname, znamelen, name[i].mzn_name, + strnlen(name[i].mzn_name, sizeof name[i].mzn_name))) { + if (first_time || info->mzi_cur_size > max_info->mzi_cur_size || + (ShowTotal && ((info->mzi_sum_size >> 1) > max_info->mzi_sum_size))) { + max_info->mzi_cur_size = info->mzi_cur_size; + max_info->mzi_sum_size = info->mzi_sum_size; + deltas[i] = 1; + found_one = 1; + } + } + info++; + max_info++; + } + return found_one; } /********************************************************************* @@ -623,389 +639,454 @@ find_deltas(mach_zone_name_t *name, mach_zone_info_t *info, mach_zone_info_t *ma static char * kern_vm_tag_name(uint64_t tag) { - char * result; - const char * name; - switch (tag) - { - case (VM_KERN_MEMORY_NONE): name = "VM_KERN_MEMORY_NONE"; break; - case (VM_KERN_MEMORY_OSFMK): name = "VM_KERN_MEMORY_OSFMK"; break; - case (VM_KERN_MEMORY_BSD): name = "VM_KERN_MEMORY_BSD"; break; - case (VM_KERN_MEMORY_IOKIT): name = "VM_KERN_MEMORY_IOKIT"; break; - case (VM_KERN_MEMORY_LIBKERN): name = "VM_KERN_MEMORY_LIBKERN"; break; - case (VM_KERN_MEMORY_OSKEXT): name = "VM_KERN_MEMORY_OSKEXT"; break; - case (VM_KERN_MEMORY_KEXT): name = "VM_KERN_MEMORY_KEXT"; break; - case (VM_KERN_MEMORY_IPC): name = "VM_KERN_MEMORY_IPC"; break; - case (VM_KERN_MEMORY_STACK): name = "VM_KERN_MEMORY_STACK"; break; - case (VM_KERN_MEMORY_CPU): name = "VM_KERN_MEMORY_CPU"; break; - case (VM_KERN_MEMORY_PMAP): name = "VM_KERN_MEMORY_PMAP"; break; - case (VM_KERN_MEMORY_PTE): name = "VM_KERN_MEMORY_PTE"; break; - case (VM_KERN_MEMORY_ZONE): name = "VM_KERN_MEMORY_ZONE"; break; - case (VM_KERN_MEMORY_KALLOC): name = "VM_KERN_MEMORY_KALLOC"; break; - case (VM_KERN_MEMORY_COMPRESSOR): name = "VM_KERN_MEMORY_COMPRESSOR"; break; - case (VM_KERN_MEMORY_COMPRESSED_DATA): name = "VM_KERN_MEMORY_COMPRESSED_DATA"; break; - case (VM_KERN_MEMORY_PHANTOM_CACHE): name = "VM_KERN_MEMORY_PHANTOM_CACHE"; break; - case (VM_KERN_MEMORY_WAITQ): name = "VM_KERN_MEMORY_WAITQ"; break; - case (VM_KERN_MEMORY_DIAG): name = "VM_KERN_MEMORY_DIAG"; break; - case (VM_KERN_MEMORY_LOG): name = "VM_KERN_MEMORY_LOG"; break; - case (VM_KERN_MEMORY_FILE): name = "VM_KERN_MEMORY_FILE"; break; - case (VM_KERN_MEMORY_MBUF): name = "VM_KERN_MEMORY_MBUF"; break; - case (VM_KERN_MEMORY_UBC): name = "VM_KERN_MEMORY_UBC"; break; - case (VM_KERN_MEMORY_SECURITY): name = "VM_KERN_MEMORY_SECURITY"; break; - case (VM_KERN_MEMORY_MLOCK): name = "VM_KERN_MEMORY_MLOCK"; break; - case (VM_KERN_MEMORY_REASON): name = "VM_KERN_MEMORY_REASON"; break; - case (VM_KERN_MEMORY_SKYWALK): name = "VM_KERN_MEMORY_SKYWALK"; break; - case (VM_KERN_MEMORY_LTABLE): name = "VM_KERN_MEMORY_LTABLE"; break; - case (VM_KERN_MEMORY_ANY): name = "VM_KERN_MEMORY_ANY"; break; - default: name = NULL; break; - } - if (name) asprintf(&result, "%s", name); - else asprintf(&result, "VM_KERN_MEMORY_%lld", tag); - return (result); - } + char * result; + const char * name; + switch (tag) { + case (VM_KERN_MEMORY_NONE): name = "VM_KERN_MEMORY_NONE"; break; + case (VM_KERN_MEMORY_OSFMK): name = "VM_KERN_MEMORY_OSFMK"; break; + case (VM_KERN_MEMORY_BSD): name = "VM_KERN_MEMORY_BSD"; break; + case (VM_KERN_MEMORY_IOKIT): name = "VM_KERN_MEMORY_IOKIT"; break; + case (VM_KERN_MEMORY_LIBKERN): name = "VM_KERN_MEMORY_LIBKERN"; break; + case (VM_KERN_MEMORY_OSKEXT): name = "VM_KERN_MEMORY_OSKEXT"; break; + case (VM_KERN_MEMORY_KEXT): name = "VM_KERN_MEMORY_KEXT"; break; + case (VM_KERN_MEMORY_IPC): name = "VM_KERN_MEMORY_IPC"; break; + case (VM_KERN_MEMORY_STACK): name = "VM_KERN_MEMORY_STACK"; break; + case (VM_KERN_MEMORY_CPU): name = "VM_KERN_MEMORY_CPU"; break; + case (VM_KERN_MEMORY_PMAP): name = "VM_KERN_MEMORY_PMAP"; break; + case (VM_KERN_MEMORY_PTE): name = "VM_KERN_MEMORY_PTE"; break; + case (VM_KERN_MEMORY_ZONE): name = "VM_KERN_MEMORY_ZONE"; break; + case (VM_KERN_MEMORY_KALLOC): name = "VM_KERN_MEMORY_KALLOC"; break; + case (VM_KERN_MEMORY_COMPRESSOR): name = "VM_KERN_MEMORY_COMPRESSOR"; break; + case (VM_KERN_MEMORY_COMPRESSED_DATA): name = "VM_KERN_MEMORY_COMPRESSED_DATA"; break; + case (VM_KERN_MEMORY_PHANTOM_CACHE): name = "VM_KERN_MEMORY_PHANTOM_CACHE"; break; + case (VM_KERN_MEMORY_WAITQ): name = "VM_KERN_MEMORY_WAITQ"; break; + case (VM_KERN_MEMORY_DIAG): name = "VM_KERN_MEMORY_DIAG"; break; + case (VM_KERN_MEMORY_LOG): name = "VM_KERN_MEMORY_LOG"; break; + case (VM_KERN_MEMORY_FILE): name = "VM_KERN_MEMORY_FILE"; break; + case (VM_KERN_MEMORY_MBUF): name = "VM_KERN_MEMORY_MBUF"; break; + case (VM_KERN_MEMORY_UBC): name = "VM_KERN_MEMORY_UBC"; break; + case (VM_KERN_MEMORY_SECURITY): name = "VM_KERN_MEMORY_SECURITY"; break; + case (VM_KERN_MEMORY_MLOCK): name = "VM_KERN_MEMORY_MLOCK"; break; + case (VM_KERN_MEMORY_REASON): name = "VM_KERN_MEMORY_REASON"; break; + case (VM_KERN_MEMORY_SKYWALK): name = "VM_KERN_MEMORY_SKYWALK"; break; + case (VM_KERN_MEMORY_LTABLE): name = "VM_KERN_MEMORY_LTABLE"; break; + case (VM_KERN_MEMORY_ANY): name = "VM_KERN_MEMORY_ANY"; break; + default: name = NULL; break; + } + if (name) { + asprintf(&result, "%s", name); + } else { + asprintf(&result, "VM_KERN_MEMORY_%lld", tag); + } + return result; +} static char * kern_vm_counter_name(uint64_t tag) { - char * result; - const char * name; - switch (tag) - { - case (VM_KERN_COUNT_MANAGED): name = "VM_KERN_COUNT_MANAGED"; break; - case (VM_KERN_COUNT_RESERVED): name = "VM_KERN_COUNT_RESERVED"; break; - case (VM_KERN_COUNT_WIRED): name = "VM_KERN_COUNT_WIRED"; break; - case (VM_KERN_COUNT_WIRED_BOOT): name = "VM_KERN_COUNT_WIRED_BOOT"; break; - case (VM_KERN_COUNT_WIRED_MANAGED): name = "VM_KERN_COUNT_WIRED_MANAGED"; break; - case (VM_KERN_COUNT_STOLEN): name = "VM_KERN_COUNT_STOLEN"; break; - case (VM_KERN_COUNT_BOOT_STOLEN): name = "VM_KERN_COUNT_BOOT_STOLEN"; break; - case (VM_KERN_COUNT_LOPAGE): name = "VM_KERN_COUNT_LOPAGE"; break; - case (VM_KERN_COUNT_MAP_KERNEL): name = "VM_KERN_COUNT_MAP_KERNEL"; break; - case (VM_KERN_COUNT_MAP_ZONE): name = "VM_KERN_COUNT_MAP_ZONE"; break; - case (VM_KERN_COUNT_MAP_KALLOC): name = "VM_KERN_COUNT_MAP_KALLOC"; break; - default: name = NULL; break; - } - if (name) asprintf(&result, "%s", name); - else asprintf(&result, "VM_KERN_COUNT_%lld", tag); - return (result); + char * result; + const char * name; + switch (tag) { + case (VM_KERN_COUNT_MANAGED): name = "VM_KERN_COUNT_MANAGED"; break; + case (VM_KERN_COUNT_RESERVED): name = "VM_KERN_COUNT_RESERVED"; break; + case (VM_KERN_COUNT_WIRED): name = "VM_KERN_COUNT_WIRED"; break; + case (VM_KERN_COUNT_WIRED_BOOT): name = "VM_KERN_COUNT_WIRED_BOOT"; break; + case (VM_KERN_COUNT_WIRED_MANAGED): name = "VM_KERN_COUNT_WIRED_MANAGED"; break; + case (VM_KERN_COUNT_STOLEN): name = "VM_KERN_COUNT_STOLEN"; break; + case (VM_KERN_COUNT_BOOT_STOLEN): name = "VM_KERN_COUNT_BOOT_STOLEN"; break; + case (VM_KERN_COUNT_LOPAGE): name = "VM_KERN_COUNT_LOPAGE"; break; + case (VM_KERN_COUNT_MAP_KERNEL): name = "VM_KERN_COUNT_MAP_KERNEL"; break; + case (VM_KERN_COUNT_MAP_ZONE): name = "VM_KERN_COUNT_MAP_ZONE"; break; + case (VM_KERN_COUNT_MAP_KALLOC): name = "VM_KERN_COUNT_MAP_KALLOC"; break; + case (VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE): + name = "VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE"; + break; + default: name = NULL; break; + } + if (name) { + asprintf(&result, "%s", name); + } else { + asprintf(&result, "VM_KERN_COUNT_%lld", tag); + } + return result; } static void MakeLoadTagKeys(const void * key, const void * value, void * context) { - CFMutableDictionaryRef newDict = context; - CFDictionaryRef kextInfo = value; - CFNumberRef loadTag; - uint32_t loadTagValue; - - loadTag = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleLoadTagKey)); - CFNumberGetValue(loadTag, kCFNumberSInt32Type, &loadTagValue); - key = (const void *)(uintptr_t) loadTagValue; - CFDictionarySetValue(newDict, key, value); + CFMutableDictionaryRef newDict = context; + CFDictionaryRef kextInfo = value; + CFNumberRef loadTag; + uint32_t loadTagValue; + + loadTag = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleLoadTagKey)); + CFNumberGetValue(loadTag, kCFNumberSInt32Type, &loadTagValue); + key = (const void *)(uintptr_t) loadTagValue; + CFDictionarySetValue(newDict, key, value); } -static CSSymbolicatorRef gSym; +static CSSymbolicatorRef gSym; static CFMutableDictionaryRef gTagDict; static mach_memory_info_t * gSites; static char * GetSiteName(int siteIdx, mach_zone_name_t * zoneNames, unsigned int zoneNamesCnt) { - const char * name; - uintptr_t kmodid; - char * result; - char * append; - mach_vm_address_t addr; - CFDictionaryRef kextInfo; - CFStringRef bundleID; - uint32_t type; - - const mach_memory_info_t * site; - const char * fileName; - CSSymbolRef symbol; - const char * symbolName; - CSSourceInfoRef sourceInfo; - - name = NULL; - result = NULL; - site = &gSites[siteIdx]; - addr = site->site; - type = (VM_KERN_SITE_TYPE & site->flags); - kmodid = 0; - - if (VM_KERN_SITE_NAMED & site->flags) - { - asprintf(&result, "%s", &site->name[0]); - } - else switch (type) - { - case VM_KERN_SITE_TAG: - result = kern_vm_tag_name(addr); - break; - - case VM_KERN_SITE_COUNTER: - result = kern_vm_counter_name(addr); - break; - - case VM_KERN_SITE_KMOD: - - kmodid = (uintptr_t) addr; - kextInfo = CFDictionaryGetValue(gTagDict, (const void *)kmodid); - if (kextInfo) - { - bundleID = (CFStringRef)CFDictionaryGetValue(kextInfo, kCFBundleIdentifierKey); - name = CFStringGetCStringPtr(bundleID, kCFStringEncodingUTF8); - // wiredSize = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleWiredSizeKey)); - } - - if (name) asprintf(&result, "%s", name); - else asprintf(&result, "(unloaded kmod)"); - break; - - case VM_KERN_SITE_KERNEL: - symbolName = NULL; - if (addr) - { - symbol = CSSymbolicatorGetSymbolWithAddressAtTime(gSym, addr, kCSNow); - symbolName = CSSymbolGetName(symbol); - } - if (symbolName) - { - asprintf(&result, "%s", symbolName); - sourceInfo = CSSymbolicatorGetSourceInfoWithAddressAtTime(gSym, addr, kCSNow); - fileName = CSSourceInfoGetPath(sourceInfo); - if (fileName) printf(" (%s:%d)", fileName, CSSourceInfoGetLineNumber(sourceInfo)); - } - else - { - asprintf(&result, "site 0x%qx", addr); - } - break; - default: - asprintf(&result, ""); - break; - } - - if (result - && (VM_KERN_SITE_ZONE & site->flags) - && zoneNames - && (site->zone < zoneNamesCnt)) - { - size_t namelen, zonelen; - namelen = strlen(result); - zonelen = strnlen(zoneNames[site->zone].mzn_name, sizeof(zoneNames[site->zone].mzn_name)); - if (((namelen + zonelen) > 61) && (zonelen < 61)) namelen = (61 - zonelen); - asprintf(&append, "%.*s[%.*s]", + const char * name; + uintptr_t kmodid; + char * result; + char * append; + mach_vm_address_t addr; + CFDictionaryRef kextInfo; + CFStringRef bundleID; + uint32_t type; + + const mach_memory_info_t * site; + const char * fileName; + CSSymbolRef symbol; + const char * symbolName; + CSSourceInfoRef sourceInfo; + + name = NULL; + result = NULL; + site = &gSites[siteIdx]; + addr = site->site; + type = (VM_KERN_SITE_TYPE & site->flags); + kmodid = 0; + + if (VM_KERN_SITE_NAMED & site->flags) { + asprintf(&result, "%s", &site->name[0]); + } else { + switch (type) { + case VM_KERN_SITE_TAG: + result = kern_vm_tag_name(addr); + break; + + case VM_KERN_SITE_COUNTER: + result = kern_vm_counter_name(addr); + break; + + case VM_KERN_SITE_KMOD: + + kmodid = (uintptr_t) addr; + kextInfo = CFDictionaryGetValue(gTagDict, (const void *)kmodid); + if (kextInfo) { + bundleID = (CFStringRef)CFDictionaryGetValue(kextInfo, kCFBundleIdentifierKey); + name = CFStringGetCStringPtr(bundleID, kCFStringEncodingUTF8); + // wiredSize = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleWiredSizeKey)); + } + + if (name) { + asprintf(&result, "%s", name); + } else { + asprintf(&result, "(unloaded kmod)"); + } + break; + + case VM_KERN_SITE_KERNEL: + symbolName = NULL; + if (addr) { + symbol = CSSymbolicatorGetSymbolWithAddressAtTime(gSym, addr, kCSNow); + symbolName = CSSymbolGetName(symbol); + } + if (symbolName) { + asprintf(&result, "%s", symbolName); + sourceInfo = CSSymbolicatorGetSourceInfoWithAddressAtTime(gSym, addr, kCSNow); + fileName = CSSourceInfoGetPath(sourceInfo); + if (fileName) { + printf(" (%s:%d)", fileName, CSSourceInfoGetLineNumber(sourceInfo)); + } + } else { + asprintf(&result, "site 0x%qx", addr); + } + break; + default: + asprintf(&result, ""); + break; + } + } + + if (result + && (VM_KERN_SITE_ZONE & site->flags) + && zoneNames + && (site->zone < zoneNamesCnt)) { + size_t namelen, zonelen; + namelen = strlen(result); + zonelen = strnlen(zoneNames[site->zone].mzn_name, sizeof(zoneNames[site->zone].mzn_name)); + if (((namelen + zonelen) > 61) && (zonelen < 61)) { + namelen = (61 - zonelen); + } + asprintf(&append, "%.*s[%.*s]", (int)namelen, result, (int)zonelen, zoneNames[site->zone].mzn_name); - free(result); - result = append; - } - if (result && kmodid) - { - asprintf(&append, "%-64s%3ld", result, kmodid); - free(result); - result = append; - } - - return (result); + free(result); + result = append; + } + if (result && kmodid) { + asprintf(&append, "%-64s%3ld", result, kmodid); + free(result); + result = append; + } + + return result; } -struct CompareThunk -{ - mach_zone_name_t *zoneNames; - unsigned int zoneNamesCnt; +struct CompareThunk { + mach_zone_name_t *zoneNames; + unsigned int zoneNamesCnt; }; static int SortName(void * thunk, const void * left, const void * right) { - const struct CompareThunk * t = (typeof(t)) thunk; - const int * idxL; - const int * idxR; - char * l; - char * r; - CFStringRef lcf; - CFStringRef rcf; - int result; - - idxL = (typeof(idxL)) left; - idxR = (typeof(idxR)) right; - l = GetSiteName(*idxL, t->zoneNames, t->zoneNamesCnt); - r = GetSiteName(*idxR, t->zoneNames, t->zoneNamesCnt); - - lcf = CFStringCreateWithCString(kCFAllocatorDefault, l, kCFStringEncodingUTF8); - rcf = CFStringCreateWithCString(kCFAllocatorDefault, r, kCFStringEncodingUTF8); - - result = (int) CFStringCompareWithOptionsAndLocale(lcf, rcf, CFRangeMake(0, CFStringGetLength(lcf)), kCFCompareNumerically, NULL); - - CFRelease(lcf); - CFRelease(rcf); - free(l); - free(r); - - return (result); + const struct CompareThunk * t = (typeof(t))thunk; + const int * idxL; + const int * idxR; + char * l; + char * r; + CFStringRef lcf; + CFStringRef rcf; + int result; + + idxL = (typeof(idxL))left; + idxR = (typeof(idxR))right; + l = GetSiteName(*idxL, t->zoneNames, t->zoneNamesCnt); + r = GetSiteName(*idxR, t->zoneNames, t->zoneNamesCnt); + + lcf = CFStringCreateWithCString(kCFAllocatorDefault, l, kCFStringEncodingUTF8); + rcf = CFStringCreateWithCString(kCFAllocatorDefault, r, kCFStringEncodingUTF8); + + result = (int) CFStringCompareWithOptionsAndLocale(lcf, rcf, CFRangeMake(0, CFStringGetLength(lcf)), kCFCompareNumerically, NULL); + + CFRelease(lcf); + CFRelease(rcf); + free(l); + free(r); + + return result; } static int SortSize(void * thunk, const void * left, const void * right) { - const mach_memory_info_t * siteL; - const mach_memory_info_t * siteR; - const int * idxL; - const int * idxR; - - idxL = (typeof(idxL)) left; - idxR = (typeof(idxR)) right; - siteL = &gSites[*idxL]; - siteR = &gSites[*idxR]; - - if (siteL->size > siteR->size) return (-1); - else if (siteL->size < siteR->size) return (1); - return (0); + const mach_memory_info_t * siteL; + const mach_memory_info_t * siteR; + const int * idxL; + const int * idxR; + + idxL = (typeof(idxL))left; + idxR = (typeof(idxR))right; + siteL = &gSites[*idxL]; + siteR = &gSites[*idxR]; + + if (siteL->size > siteR->size) { + return -1; + } else if (siteL->size < siteR->size) { + return 1; + } + return 0; } static void PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt, - mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames, - unsigned int zoneCnt, uint64_t zoneElements, - int (*func)(void *, const void *, const void *), boolean_t column) + mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames, + unsigned int zoneCnt, uint64_t zoneElements, + int (*func)(void *, const void *, const void *), boolean_t column) { - uint64_t zonetotal; - uint64_t top_wired; - uint64_t size; - uint64_t elemsTagged; + uint64_t zonetotal; + uint64_t top_wired; + uint64_t size; + uint64_t elemsTagged; - CFDictionaryRef allKexts; - unsigned int idx, site, first; - int sorted[wiredInfoCnt]; - char totalstr[40]; - char * name; - bool headerPrinted; + CFDictionaryRef allKexts; + unsigned int idx, site, first; + int sorted[wiredInfoCnt]; + char totalstr[40]; + char * name; + bool headerPrinted; - zonetotal = totalsize; + zonetotal = totalsize; - gSites = wiredInfo; + gSites = wiredInfo; - gSym = CSSymbolicatorCreateWithMachKernel(); + gSym = CSSymbolicatorCreateWithMachKernel(); - allKexts = OSKextCopyLoadedKextInfo(NULL, NULL); - gTagDict = CFDictionaryCreateMutable( - kCFAllocatorDefault, (CFIndex) 0, - (CFDictionaryKeyCallBacks *) 0, - &kCFTypeDictionaryValueCallBacks); + allKexts = OSKextCopyLoadedKextInfo(NULL, NULL); + gTagDict = CFDictionaryCreateMutable( + kCFAllocatorDefault, (CFIndex) 0, + (CFDictionaryKeyCallBacks *) 0, + &kCFTypeDictionaryValueCallBacks); - CFDictionaryApplyFunction(allKexts, &MakeLoadTagKeys, gTagDict); - CFRelease(allKexts); + CFDictionaryApplyFunction(allKexts, &MakeLoadTagKeys, gTagDict); + CFRelease(allKexts); - top_wired = 0; + top_wired = 0; - for (idx = 0; idx < wiredInfoCnt; idx++) sorted[idx] = idx; - first = 0; // VM_KERN_MEMORY_FIRST_DYNAMIC - struct CompareThunk thunk; - thunk.zoneNames = zoneNames; - thunk.zoneNamesCnt = zoneCnt; - qsort_r(&sorted[first], + for (idx = 0; idx < wiredInfoCnt; idx++) { + sorted[idx] = idx; + } + first = 0; // VM_KERN_MEMORY_FIRST_DYNAMIC + struct CompareThunk thunk; + thunk.zoneNames = zoneNames; + thunk.zoneNamesCnt = zoneCnt; + qsort_r(&sorted[first], wiredInfoCnt - first, sizeof(sorted[0]), &thunk, func); - elemsTagged = 0; - for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) - { - site = sorted[idx]; - if ((VM_KERN_SITE_COUNTER & gSites[site].flags) - && (VM_KERN_COUNT_WIRED == gSites[site].site)) top_wired = gSites[site].size; - if (VM_KERN_SITE_HIDE & gSites[site].flags) continue; - if (!((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) continue; + elemsTagged = 0; + for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) { + site = sorted[idx]; + if ((VM_KERN_SITE_COUNTER & gSites[site].flags) + && (VM_KERN_COUNT_WIRED == gSites[site].site)) { + top_wired = gSites[site].size; + } + if (VM_KERN_SITE_HIDE & gSites[site].flags) { + continue; + } + if (!((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) { + continue; + } - if ((VM_KERN_SITE_ZONE & gSites[site].flags) - && gSites[site].zone < zoneCnt) - { - elemsTagged += gSites[site].size / zoneInfo[gSites[site].zone].mzi_elem_size; - } + if ((VM_KERN_SITE_ZONE & gSites[site].flags) + && gSites[site].zone < zoneCnt) { + elemsTagged += gSites[site].size / zoneInfo[gSites[site].zone].mzi_elem_size; + } - if ((gSites[site].size < 1024) && (gSites[site].peak < 1024)) continue; + if ((gSites[site].size < 1024) && (gSites[site].peak < 1024)) { + continue; + } - name = GetSiteName(site, zoneNames, zoneCnt); - if (!substr(zname, znamelen, name, strlen(name))) continue; - if (!headerPrinted) - { - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf(" kmod vm peak cur\n"); - printf("wired memory id tag size waste size\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - headerPrinted = true; - } - printf("%-67s", name); - free(name); - printf("%12d", gSites[site].tag); + name = GetSiteName(site, zoneNames, zoneCnt); + if (!substr(zname, znamelen, name, strlen(name))) { + continue; + } + if (!headerPrinted) { + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" kmod vm peak cur\n"); + printf("wired memory id tag size waste size\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + headerPrinted = true; + } + printf("%-67s", name); + free(name); + printf("%12d", gSites[site].tag); - if (gSites[site].peak) PRINTK(" %10llu", gSites[site].peak); - else printf(" %11s", ""); + if (gSites[site].peak) { + PRINTK(" %10llu", gSites[site].peak); + } else { + printf(" %11s", ""); + } - if (gSites[site].collectable_bytes) PRINTK(" %5llu", gSites[site].collectable_bytes); - else printf(" %6s", ""); + if (gSites[site].collectable_bytes) { + PRINTK(" %5llu", gSites[site].collectable_bytes); + } else { + printf(" %6s", ""); + } - PRINTK(" %9llu", gSites[site].size); + PRINTK(" %9llu", gSites[site].size); - if (!(VM_KERN_SITE_ZONE & gSites[site].flags)) totalsize += gSites[site].size; + if (!(VM_KERN_SITE_ZONE & gSites[site].flags)) { + totalsize += gSites[site].size; + } - printf("\n"); - } - - if (!znamelen) - { - printf("%-67s", "zones"); - printf("%12s", ""); - printf(" %11s", ""); - printf(" %6s", ""); - PRINTK(" %9llu", zonetotal); - printf("\n"); - } - if (headerPrinted) - { - if (elemsTagged) - { - snprintf(totalstr, sizeof(totalstr), "%lld of %lld", elemsTagged, zoneElements); - printf("zone tags%100s\n", totalstr); - } - snprintf(totalstr, sizeof(totalstr), "%6.2fM of %6.2fM", totalsize / 1024.0 / 1024.0, top_wired / 1024.0 / 1024.0); - printf("total%104s\n", totalstr); - } - for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) - { - site = sorted[idx]; - size = gSites[site].mapped; - if (!size) continue; - if (VM_KERN_SITE_HIDE & gSites[site].flags) continue; - if ((size == gSites[site].size) - && ((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) continue; - - name = GetSiteName(site, NULL, 0); - if (!substr(zname, znamelen, name, strlen(name))) continue; - if (!headerPrinted) - { - printf("-------------------------------------------------------------------------------------------------------------\n"); - printf(" largest peak cur\n"); - printf("maps free free size size\n"); - printf("-------------------------------------------------------------------------------------------------------------\n"); - headerPrinted = true; - } - printf("%-55s", name); - free(name); - - if (gSites[site].free) PRINTK(" %10llu", gSites[site].free); - else printf(" %11s", ""); - if (gSites[site].largest) PRINTK(" %10llu", gSites[site].largest); - else printf(" %11s", ""); - if (gSites[site].peak) PRINTK(" %10llu", gSites[site].peak); - else printf(" %11s", ""); - PRINTK(" %16llu", size); + printf("\n"); + } - printf("\n"); - } + if (!znamelen) { + printf("%-67s", "zones"); + printf("%12s", ""); + printf(" %11s", ""); + printf(" %6s", ""); + PRINTK(" %9llu", zonetotal); + printf("\n"); + } + if (headerPrinted) { + if (elemsTagged) { + snprintf(totalstr, sizeof(totalstr), "%lld of %lld", elemsTagged, zoneElements); + printf("zone tags%100s\n", totalstr); + } + snprintf(totalstr, sizeof(totalstr), "%6.2fM of %6.2fM", totalsize / 1024.0 / 1024.0, top_wired / 1024.0 / 1024.0); + printf("total%104s\n", totalstr); + } + for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) { + site = sorted[idx]; + size = gSites[site].mapped; + if (!size) { + continue; + } + if (VM_KERN_SITE_HIDE & gSites[site].flags) { + continue; + } + if ((size == gSites[site].size) + && ((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) { + continue; + } + + name = GetSiteName(site, NULL, 0); + if (!substr(zname, znamelen, name, strlen(name))) { + continue; + } + if (!headerPrinted) { + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" largest peak cur\n"); + printf("maps free free size size\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + headerPrinted = true; + } + printf("%-55s", name); + free(name); + + if (gSites[site].free) { + PRINTK(" %10llu", gSites[site].free); + } else { + printf(" %11s", ""); + } + if (gSites[site].largest) { + PRINTK(" %10llu", gSites[site].largest); + } else { + printf(" %11s", ""); + } + if (gSites[site].peak) { + PRINTK(" %10llu", gSites[site].peak); + } else { + printf(" %11s", ""); + } + PRINTK(" %16llu", size); + + printf("\n"); + } + for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) { + site = sorted[idx]; + size = gSites[site].size; + if (!size || !(VM_KERN_SITE_ZONE_VIEW & gSites[site].flags)) { + continue; + } + + name = GetSiteName(site, NULL, 0); + if (!substr(zname, znamelen, name, strlen(name))) { + continue; + } + if (!headerPrinted) { + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" cur\n"); + printf("zone views inuse\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + headerPrinted = true; + } + printf("%-55s", name); + free(name); + + printf(" %11s", ""); + printf(" %11s", ""); + printf(" %11s", ""); + PRINTK(" %16llu", size); + + printf("\n"); + } totalsize = zonetotal; } diff --git a/zprint.tproj/zprint.lua b/zprint.tproj/zprint.lua index 3c7d5fc..a5ca245 100644 --- a/zprint.tproj/zprint.lua +++ b/zprint.tproj/zprint.lua @@ -33,7 +33,7 @@ function zprint.zones(zpout) local zones = lines_inside_dashes(zpout, 1) -- Create an iterator for each line, for use in our own iteration function. - local lines = zones:gmatch('([^\n]+)\n') + local lines = zones:gmatch('([^\n]+)') return function () -- Grab the next line. @@ -65,12 +65,35 @@ function zprint.zones(zpout) end end +-- Match the output of a vm_tag line +-- This line has a variable number of columns. +-- This function returns the name and a table containing each numeric column's +-- value. +local function match_tag(line, ncols) + -- First try to match names with C++ symbol names. + -- These can have whitespace in the argument list. + local name_pattern = '^(%S+%b()%S*)' + local name = line:match(name_pattern) + if not name then + name = line:match('(%S+)') + if not name then + return nil + end + end + local after_name = line:sub(#name) + local t = {} + for v in line:gmatch('%s+(%d+)K?') do + table.insert(t, v) + end + return name, t +end + -- Iterate through the tags listed in the given zprint(1) output `zpout`. function zprint.tags(zpout) -- Get to the third zone delimited by dashes, where the tags are recorded. local tags = lines_inside_dashes(zpout, 3) - local lines = tags:gmatch('([^\n]+)\n') + local lines = tags:gmatch('([^\n]+)') return function () local line = lines() @@ -87,24 +110,18 @@ function zprint.tags(zpout) return nil end - -- The line representing a region can take 4 different forms, depending on - -- the type of region. Check for each of them. + local name, matches = match_tag(line) + if not name or #matches == 0 then + return nil + end - -- Check for 4 columns. - local name, maxsz_kb, cursz_kb = line:match( - '(%S+)%s+%d+%s+%d+%s+(%d+)K%s+(%d+)K$') - if not name then - -- Check for 3 columns. - name, maxsz_kb, cursz_kb = line:match('(%S+)%s+%d+%s+(%d+)K%s+(%d+)K$') - if not name then - -- Check for a two columns. - name, cursz_kb = line:match('(%S+)%s+%d+%s+(%d+)K') - if not name then - -- Check for a single column. - name, cursz_kb = line:match('(%S+)%s+(%d+)K') - end - end + local cursz_kb = matches[#matches] + -- If there are fewer than 3 numeric columns, there's no reported peak size + local maxsz_kb = nil + if #matches > 3 then + maxsz_kb = matches[#matches - 1] end + -- Convert numeric fields to numbers and then into bytes. local cursz = tonumber(cursz_kb) * 1024 local maxsz = maxsz_kb and (tonumber(maxsz_kb) * 1024) @@ -118,10 +135,147 @@ function zprint.tags(zpout) end end +-- Iterate through the maps listed in the given zprint(1) output `zpout`. +function zprint.maps(zpout) + local maps = lines_inside_dashes(zpout, 5) + local lines = maps:gmatch('([^\n]+)') + + return function() + -- Grab the next line. + local line = lines() + if not line then + return nil + end + + -- The line can take on 3 different forms. Check for each of them + + -- Check for 3 columns + local name, free_kb, largest_free_kb, curr_size_kb = line:match( + '(%S+)%s+(%d+)K%s+(%d+)K%s+(%d+)K') + local free, largest_free, peak_size_kb, peak_size, size + if not name then + -- Check for 2 columns + name, peak_size_kb, curr_size_kb = line:match('(%S+)%s+(%d+)K%s+(%d+)K') + if not name then + -- Check for a single column + name, curr_size_kb = line:match('(%S+)%s+(%d+)K') + assert(name) + else + peak_size = tonumber(peak_size_kb) * 1024 + end + else + free = tonumber(free_kb) * 1024 + largest_free = tonumber(largest_free_kb) * 1024 + end + size = tonumber(curr_size_kb) * 1024 + + return { + name = name, + size = size, + max_size = peak_size, + free = free, + largest_free = largest_free + } + end +end + +-- Iterate through the zone views listed in the given zprint(1) output `zpout`. +function zprint.zone_views(zpout) + -- Skip to the zone views + local prev_pos = 1 + -- Look for a line that starts with "zone views" and is followed by a -- line. + while true do + local start_pos, end_pos = zpout:find('\n[-]+\n', prev_pos) + if start_pos == nil then + return nil + end + local before = zpout:sub(prev_pos, start_pos) + local zone_views_index = zpout:find('\n%s*zone views%s+[^\n]+\n', prev_pos + 1) + prev_pos = end_pos + if zone_views_index and zone_views_index < end_pos then + break + end + end + + local zone_views + local zone_totals_index = zpout:find("\nZONE TOTALS") + if zone_totals_index then + zone_views = zpout:sub(prev_pos + 1, zone_totals_index) + else + zone_views = zpout:sub(prev_pos+ 1) + end + + local lines = zone_views:gmatch('([^\n]+)') + + return function() + -- Grab the next line. + local line = lines() + if not line then + return nil + end + + local name, curr_size_kb = line:match('(%S+)%s+(%d+)') + local size = tonumber(curr_size_kb) * 1024 + + return { + name = name, + size = size, + } + end +end + function zprint.total(zpout) local total = zpout:match('total[^%d]+(%d+.%d+)M of') local bytes = tonumber(total) * 1024 * 1024 return bytes end -return zprint +-- Return a library object, if called from require or dofile. +local calling_func = debug.getinfo(2).func +if calling_func == require or calling_func == dofile then + return zprint +end + +-- Otherwise, 'recon zprint.lua ...' runs as a script. + +local cjson = require 'cjson' + +if not arg[1] then + io.stderr:write('usage: ', arg[0], ' \n') + os.exit(1) +end + +local file +if arg[1] == '-' then + file = io.stdin +else + local err + file, err = io.open(arg[1]) + if not file then + io.stderr:write('zprint.lua: ', arg[1], ': open failed: ', err, '\n') + os.exit(1) + end +end + +local zpout = file:read('all') +file:close() + +local function collect(iter, arg) + local tbl = {} + for elt in iter(arg) do + tbl[#tbl + 1] = elt + end + return tbl +end + +local zones = collect(zprint.zones, zpout) +local tags = collect(zprint.tags, zpout) +local maps = collect(zprint.maps, zpout) +local zone_views = collect(zprint.zone_views, zpout) + +print(cjson.encode({ + zones = zones, + tags = tags, + maps = maps, + zone_views = zone_views, +})) -- 2.45.2