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
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
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.
#include <NSSystemDirectories.h>
#include <sysdir.h>
+#if defined(__x86_64__)
+#include <System/i386/cpu_capabilities.h>
+#endif
+
+#if TARGET_OS_OSX
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
#ifndef ARCH_PROG
#define ARCH_PROG "arch"
#endif
/* 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;
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 */
/*
* 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;
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)
/* 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)
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");
}
/*
* 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;
}
/*
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;
}
}
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;
/*
- * Copyright (c) 1999-2019 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2020 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <errno.h>
#include <err.h>
#include <libutil.h>
+#include <TargetConditionals.h>
#include <ktrace/session.h>
#include <System/sys/kdebug.h>
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) {
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};
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
*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)) {
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) {
#include <assert.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <TargetConditionals.h>
static const size_t dyld_cache_header_size = sizeof (struct copied_dyld_cache_header);
{
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
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);
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]);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <false/>
+ <key>EnableTransactions</key>
+ <false/>
+ <key>KeepAlive</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.getty</string>
+ <key>POSIXSpawnType</key>
+ <string>Interactive</string>
+ <key>_LimitLoadFromVariant</key>
+ <string>IsBaseSystem</string>
+ <key>LimitLoadToHardware</key>
+ <dict>
+ <key>serialdebugmode</key>
+ <array>
+ <integer>1</integer>
+ </array>
+ </dict>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/libexec/getty</string>
+ <string>std.9600</string>
+ <string>console</string>
+ </array>
+ <key>SessionCreate</key>
+ <true/>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EnablePressuredExit</key>
+ <false/>
+ <key>EnableTransactions</key>
+ <false/>
+ <key>KeepAlive</key>
+ <true/>
+ <key>Label</key>
+ <string>com.apple.serialdebugconsole</string>
+ <key>POSIXSpawnType</key>
+ <string>Interactive</string>
+ <key>_LimitLoadToVariant</key>
+ <string>AllowsInternalSecurityPolicies</string>
+ <key>LimitLoadToHardware</key>
+ <dict>
+ <key>serialdebugmode</key>
+ <array>
+ <integer>2</integer>
+ </array>
+ </dict>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/bin/sh</string>
+ <string>-i</string>
+ <string>-l</string>
+ </array>
+ <key>StandardInPath</key>
+ <string>/dev/console</string>
+ <key>StandardOutPath</key>
+ <string>/dev/console</string>
+ <key>StandardErrorPath</key>
+ <string>/dev/console</string>
+ <key>SessionCreate</key>
+ <true/>
+</dict>
+</plist>
#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,
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 )
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>com.apple.private.opendirectoryd.identity</key>
- <true/>
<key>com.apple.private.security.clear-library-validation</key>
<true/>
</dict>
NOTE_RENAME
.It Sy v
NOTE_REVOKE
+.It Sy u
+NOTE_FUNLOCK
.Pp
.It EVFILT_PROC:
.It Sy x
}
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;
}
* 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
#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 */
{
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";
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";
}
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';
} 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);
}
}
- 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);
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;
}
#include <assert.h>
#include <dispatch/private.h>
-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;
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)
{
}
}
+/*
+ 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)
{
//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);
}
}
- 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();
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");
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) {
// 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';
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);
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
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 = "<UNPRINTABLE>";
+ }
+ }
+
+ warnx("Error clearing firmware variable %s: %s", keyStr, mach_error_string(result));
+ if (keyBuffer) {
+ free(keyBuffer);
+ }
}
}
char* auth = NULL;
int infosystem, ch;
int free_user = 0;
+ int res = -1;
#ifdef INFO_PAM
infosystem = INFO_PAM;
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);
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>com.apple.keystore.console</key>
+ <true/>
<key>com.apple.private.opendirectoryd.identity</key>
<true/>
<key>com.apple.private.security.clear-library-validation</key>
#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
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;
#include <util.h>
#include <bsm/libbsm.h>
#include <bsm/audit_uevents.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
#include <vproc.h>
#include <vproc_priv.h>
}
+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
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;
#include <kern/kcdata.h>
-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);
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");
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");
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;
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);
}
}
-
if (stress) {
if (config) {
stackshot_config_dealloc(config);
goto top;
}
- fwrite(buf, size, 1, stdout);
+ fwrite(buf, size, 1, file);
+
+ if (closefile) {
+ fclose(file);
+ }
+
+ return 0;
}
#include <errno.h>
#include <inttypes.h>
#include <locale.h>
+#ifdef __APPLE__
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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
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)
static int
sysctl_all(int *oid, int len)
{
+#ifdef __APPLE__
+#endif
+
int name1[22], name2[22];
int i, j;
size_t l1, l2;
buildConfigurationList = BA4FD2FF1372FE4E0025925C /* Build configuration list for PBXAggregateTarget "All_MacOSX" */;
buildPhases = (
C9D64CD21B91066B00CFA43B /* CopyFiles */,
+ 587B8CAD2489CB170001CD8D /* Copy internal getty */,
+ 587B8CAE2489CB9C0001CD8D /* Copy Files */,
);
dependencies = (
358407D22245AD40006A0D8E /* PBXTargetDependency */,
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 */; };
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 */; };
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 */; };
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
fileType = pattern.proxy;
+ inputFiles = (
+ );
isEditable = 1;
outputFiles = (
"$(DERIVED_SOURCES_DIR)/$(CURRENT_ARCH)/darwin_version.c",
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;
};
);
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;
);
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 */ = {
);
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 */ = {
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 */ = {
55CCB16816B84ED100B56979 /* vm_purgeable_stat.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = vm_purgeable_stat.1; sourceTree = "<group>"; };
55CCB16916B84ED100B56979 /* vm_purgeable_stat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vm_purgeable_stat.c; sourceTree = "<group>"; };
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 = "<group>"; };
+ 58775F6D2489B8CE0098F7DE /* com.apple.serialdebugconsole.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.serialdebugconsole.plist; sourceTree = "<group>"; };
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; };
BA4FD22C1372FAFA0025925C /* dynamic_pager.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = dynamic_pager.8; sourceTree = "<group>"; };
BA4FD22D1372FAFA0025925C /* dynamic_pager.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dynamic_pager.c; sourceTree = "<group>"; };
BA4FD2301372FAFA0025925C /* fs_usage.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = fs_usage.1; sourceTree = "<group>"; };
- BA4FD2311372FAFA0025925C /* fs_usage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fs_usage.c; sourceTree = "<group>"; };
+ BA4FD2311372FAFA0025925C /* fs_usage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fs_usage.c; sourceTree = "<group>"; usesTabs = 1; };
BA4FD2351372FAFA0025925C /* confstr.gperf */ = {isa = PBXFileReference; lastKnownFileType = text; path = confstr.gperf; sourceTree = "<group>"; };
BA4FD2361372FAFA0025925C /* fake-gperf.awk */ = {isa = PBXFileReference; lastKnownFileType = text; path = "fake-gperf.awk"; sourceTree = "<group>"; };
BA4FD2371372FAFA0025925C /* getconf.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = getconf.1; sourceTree = "<group>"; };
C9D64CCF1B91063200CFA43B /* system_cmds.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = system_cmds.plist; path = tests/system_cmds.plist; sourceTree = "<group>"; };
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 = "<group>"; };
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 = "<group>"; };
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; };
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 */,
BA4FD2E31372FAFA0025925C /* zprint.tproj */ = {
isa = PBXGroup;
children = (
+ CEB165CB246C599A00228592 /* test_zprint.lua */,
C99490E32090F55D00246D9D /* zprint.lua */,
FEBEE5CF1B0EACEB00166A8B /* entitlements.plist */,
BA4FD2E51372FAFA0025925C /* zprint.1 */,
buildPhases = (
BA0A860813968E8500D2272C /* Sources */,
BA0A860A13968E8500D2272C /* Frameworks */,
- BA0A860C13968E8500D2272C /* CopyFiles */,
- C99490E22090F53B00246D9D /* CopyFiles */,
+ BA0A860C13968E8500D2272C /* Copy man page */,
+ C99490E22090F53B00246D9D /* Copy Lua library */,
+ CEB165CD246C599F00228592 /* Copy test */,
);
buildRules = (
);
BA2DE9181372FA9100D1913C /* Project object */ = {
isa = PBXProject;
attributes = {
- DefaultBuildSystemTypeForWorkspace = Original;
LastUpgradeCheck = 0600;
TargetAttributes = {
08CE3D281E6E22A200DF1B78 = {
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = BA2DE9161372FA9100D1913C;
/* 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;
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = ". \"${SRCROOT}/getty.tproj/generate_plist.sh\"";
+ shellScript = ". \"${SRCROOT}/getty.tproj/generate_plist.sh\"\n";
};
BA4FD335137306050025925C /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>BuildSystemType</key>
- <string>Original</string>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
+ <key>PreviewsEnabled</key>
+ <false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
- version = "1.7">
+ version = "1.8">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
- <AdditionalOptions>
- </AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
ReferencedContainer = "container:system_cmds.xcodeproj">
</BuildableReference>
</MacroExpansion>
- <AdditionalOptions>
- </AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
<key>BATSConfigVersion</key>
<string>0.1.0</string>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>Project</key>
<string>system_cmds</string>
<key>IgnoreOutput</key>
<string>-all</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_lsmp</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>/usr/sbin/lsof</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_lsof</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
-
<dict>
<key>Arch</key>
<string>platform-native</string>
<string>/usr/bin/zprint</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_zprint</string>
<key>TestSpecificLogs</key>
+ <array/>
+ <key>WorkingDirectory</key>
+ <string>/tmp/</string>
+ </dict>
+ <dict>
+ <key>Arch</key>
+ <string>platform-native</string>
+ <key>AsRoot</key>
+ <true/>
+ <key>Command</key>
<array>
+ <string>recon</string>
+ <string>/AppleInternal/Tests/system_cmds/test_zprint.lua</string>
</array>
+ <key>IgnoreCrashes</key>
+ <array/>
+ <key>TestName</key>
+ <string>test_zprint_lua</string>
+ <key>TestSpecificLogs</key>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>/usr/bin/hostinfo</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_hostinfo</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>/usr/local/bin/ltop</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_ltop</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>/usr/bin/vm_stat</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_vm_stat</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>/sbin/dmesg</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_dmesg</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
<string>-a</string>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_sysctl</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
</dict>
</array>
<key>IgnoreCrashes</key>
- <array>
- </array>
+ <array/>
<key>TestName</key>
<string>test_proc_uuid_policy</string>
<key>TestSpecificLogs</key>
- <array>
- </array>
+ <array/>
<key>WorkingDirectory</key>
<string>/tmp/</string>
</dict>
# 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"
-target zic \
-sdk "macosxinternal" \
SRCROOT="${SRCROOT}" \
- OBJROOT="${OBJROOT}" \
+ OBJROOT="${ZICHOST_OBJROOT}" \
SYMROOT="${ZICHOST_SYMROOT}" \
DSTROOT="${ZICHOST_DSTROOT}" \
ARCHS='$(NATIVE_ARCH_ACTUAL)' \
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
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach_debug/mach_debug.h>
#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;
/* 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 */
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>com.apple.system-task-ports</key>
- <true/>
- <key>task_for_pid-allow</key>
- <true/>
<key>com.apple.private.kernel.get-kext-info</key>
<true/>
</dict>
--- /dev/null
+#!/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")
#include <CoreFoundation/CoreFoundation.h>
#include <CoreSymbolication/CoreSymbolication.h>
-#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 *);
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;
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
* 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
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);
}
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);
}
}
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;
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;
}
}
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);
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
{
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;
}
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;
}
-#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) \
+ } \
}
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);
{
int i, totalwidth = 0;
- if (! PrintHeader) {
+ if (!PrintHeader) {
return;
}
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;
}
/*********************************************************************
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;
}
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.
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()
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)
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], ' <zprint-output-path>\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,
+}))