]> git.saurik.com Git - apple/system_cmds.git/commitdiff
system_cmds-541.tar.gz mac-os-x-107 mac-os-x-1071 mac-os-x-1072 mac-os-x-1073 mac-os-x-1074 mac-os-x-1075 v541
authorApple <opensource@apple.com>
Thu, 24 Feb 2011 00:26:03 +0000 (00:26 +0000)
committerApple <opensource@apple.com>
Thu, 24 Feb 2011 00:26:03 +0000 (00:26 +0000)
79 files changed:
Makefile
ac.tproj/Makefile
accton.tproj/Makefile
arch.tproj/Makefile
arch.tproj/arch.1
arch.tproj/arch.m
at.tproj/Makefile
atrun.tproj/Makefile
bootlog.tproj/Makefile [deleted file]
bootlog.tproj/bootlog.8 [deleted file]
bootlog.tproj/bootlog.c [deleted file]
bootlog.tproj/com.apple.bootlog.plist [deleted file]
chkpasswd.tproj/Makefile
chkpasswd.tproj/file_passwd.c
chpass.tproj/Makefile
chpass.tproj/chpass.c
chpass.tproj/open_directory.c
dirhelper.tproj/Makefile
dirhelper.tproj/dirhelper.c
dmesg.tproj/Makefile
dynamic_pager.tproj/Makefile
dynamic_pager.tproj/dynamic_pager.c
fs_usage.tproj/Makefile
fs_usage.tproj/fs_usage.1
fs_usage.tproj/fs_usage.c
getconf.tproj/Makefile
getconf.tproj/sysconf.gperf
getty.tproj/Makefile
getty.tproj/chat.c
hostinfo.tproj/Makefile
iostat.tproj/Makefile
iostat.tproj/iostat.c
latency.tproj/Makefile
latency.tproj/latency.1
latency.tproj/latency.c
login.tproj/Makefile
login.tproj/login.c
login.tproj/login.h
login.tproj/login.pam [deleted file]
login.tproj/login_audit.c
login.tproj/pam.d/login [new file with mode: 0644]
login.tproj/pam.d/login.term [new file with mode: 0644]
makekey.tproj/Makefile
mean.tproj/mean.c
mkfile.tproj/Makefile
newgrp.tproj/Makefile
nologin.tproj/Makefile
nvram.tproj/Makefile
nvram.tproj/nvram.c
passwd.tproj/Makefile
passwd.tproj/file_passwd.c
passwd.tproj/od_passwd.c
passwd.tproj/passwd.c
passwd.tproj/stringops.c [deleted file]
passwd.tproj/stringops.h [deleted file]
pwd_mkdb.tproj/Makefile
pwd_mkdb.tproj/pwd_mkdb.c
reboot.tproj/Makefile
sa.tproj/Makefile
sadc.tproj/Makefile
sadc.tproj/sadc.c
sar.tproj/Makefile
sc_usage.tproj/Makefile
sc_usage.tproj/trace.codes [deleted file]
shutdown.tproj/Makefile
sync.tproj/Makefile
sysctl.tproj/Makefile
sysctl.tproj/sysctl.c
trace.tproj/Makefile [new file with mode: 0644]
trace.tproj/trace.1 [new file with mode: 0644]
trace.tproj/trace.c [new file with mode: 0644]
vifs.tproj/Makefile
vipw.tproj/Makefile
vm_stat.tproj/Makefile
zdump.tproj/Makefile
zic.tproj/Makefile
zprint.tproj/Makefile
zprint.tproj/zprint.1
zprint.tproj/zprint.c

index ff782bf633569abb80355a4bc4199abe78f63b3c..a22f7b9bc8dfa904194cc9a62b34b7a22df91707 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,13 +2,13 @@ Project = system_cmds
 
 Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
 
-SubProjects = ac.tproj accton.tproj arch.tproj bootlog.tproj           \
+SubProjects = ac.tproj accton.tproj arch.tproj \
        dmesg.tproj dp_notify_lib dynamic_pager.tproj fs_usage.tproj    \
        getconf.tproj getty.tproj hostinfo.tproj iostat.tproj           \
        latency.tproj login.tproj makekey.tproj mkfile.tproj            \
        newgrp.tproj nologin.tproj nvram.tproj pagesize.tproj           \
        passwd.tproj pwd_mkdb.tproj reboot.tproj sa.tproj sadc.tproj    \
-       sar.tproj sc_usage.tproj sync.tproj sysctl.tproj                \
+       sar.tproj sc_usage.tproj sync.tproj sysctl.tproj trace.tproj    \
        vipw.tproj vifs.tproj vm_stat.tproj zdump.tproj zic.tproj       \
        zprint.tproj
 
@@ -19,6 +19,4 @@ else
 SubProjects += mean.tproj
 endif
 
-Extra_LD_Flags += -lcurses -lutil
-
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 3977061def0cfd6ee3c089fe77a20f6e2c78350c..77e166aa4ac4f408e1e77ab9b47a56d333def1d6 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = ac.c
 MANPAGES = ac.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 6a0e9a127a7365636f6b1b675a0ad6975fd437fd..5e5d34ee5cc06fa5ec36f0350e1e73eab11e67bb 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = accton.c
 MANPAGES = accton.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID
 Extra_LD_Flags = -dead_strip
 
index 7b0f0ea4c13fb07c8a06bd5aa8b45803c8c69c79..b0d2ecaa8c47fdae72228f886a89c88cfe2de3ee 100644 (file)
@@ -6,7 +6,7 @@ Extra_Frameworks = -framework Foundation
 
 MANPAGES = arch.1 machine.1
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -DARCH_PROG=\"arch\" -DMACHINE_PROG=\"machine\"
index 2d12478cecb1d37a02f31f9f87859561fa04ab11..909bac52f7f8396388414d013b8a70b54f2fb16a 100644 (file)
@@ -31,7 +31,7 @@
 .\" Modifications made 8/20/97 (c) Apple Computer, Inc.
 .\" Modifications made 11/12/06 (c) Apple Computer, Inc.
 
-.Dd November 12, 2006
+.Dd July 8, 2010
 .Dt ARCH 1
 .Os "Mac OS X"
 .Sh NAME
 .Sh SYNOPSIS
 .Nm arch
 .Nm arch
-.Op Fl h
+.Op Fl 32
+.Op Fl 64
 .Oo
 .Oo Fl Ns Ar arch_name | Fl arch Ar arch_name Oc Ns ...
 .Oc
+.Op Fl c
+.Oo Fl d Ar envname Oc Ns ...
+.Oo Fl e Ar envname=value Oc Ns ...
+.Op Fl h
 .Ar prog
 .Op Ar args No ...
 .Sh DESCRIPTION
@@ -76,19 +81,11 @@ The most common use is to select the 32-bit architecture on a 64-bit processor,
 even if a 64-bit architecture is available.
 .Pp
 The
-.Fl h
-option prints a usage message and exits.
-.Pp
-The
 .Ar arch_name
 argument must be one of the currently supported architectures:
 .Bl -tag -width x86_64 -offset indent
 .It i386
 32-bit intel
-.It ppc
-32-bit powerpc
-.It ppc64
-64-bit powerpc
 .It x86_64
 64-bit intel
 .El
@@ -102,6 +99,25 @@ If more than one architecture is specified, the operating system will try each
 one in order, skipping an architecture that is not supported on the current
 processor, or is unavailable in the universal binary.
 .Pp
+The other options are:
+.Bl -tag -width ".Fl e Ar envname=value"
+.It Fl 32
+Add the native 32-bit architecture to the list of architectures.
+.It Fl 64
+Add the native 64-bit architecture to the list of architectures.
+.It Fl c
+Clears the environment that will be passed to the command to be run.
+.It Fl d Ar envname
+Deletes the named environment variable from the environment that will be passed
+to the command to be run.
+.It Fl e Ar envname=value
+Assigns the given value to the named environment variable in the environment
+that will be passed to the command to be run.
+Any existing environment variable with the same name will be replaced.
+.It Fl h
+Prints a usage message and exits.
+.El
+.Pp
 The
 .Ar prog
 argument is the command to run, followed by any arguments to pass to the
@@ -141,13 +157,7 @@ On an intel processor:
 1234
 .Ed
 .Pp
-shows the intel little endian byte order, while:
-.Bd -literal -offset indent
-% arch -ppc perl -MConfig -e 'printf "%s\\n", $Config{byteorder}'
-4321
-.Ed
-.Pp
-runs the powerpc architecture, and displays big endian byte order.
+shows the intel little endian byte order.
 .Ss Making links to the arch command
 When a link is made to
 .Nm arch
@@ -199,17 +209,17 @@ If not specified as a second field in a specifier, the executable path will
 be looked up in the corresponding property list file.
 .Ss Example ARCHPREFERENCE Values
 .Bl -tag -width "    "
-.It ppc,i386,ppc64,x86_64
+.It i386,x86_64
 A specifier that matches any name.
-.It foo:ppc,i386,ppc64,x86_64
+.It foo:i386,x86_64
 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:ppc,i386,ppc64,x86_64
+.It foo:/op/bin/boo:i386,x86_64
 A specifier with all fields specified.
-.It baz:ppc,i386;i386,ppc
+.It baz:i386;x86_64
 A specifier for
 .Nm baz
 and a second specifier that would match any other name.
index be4b58e30471a1efcd9e3d4315a601c5537bad6e..b36277a3edd0545071241dfcf3ceda241f4e4072 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/cdefs.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
@@ -65,18 +66,69 @@ typedef struct {
 } CPU;
 
 typedef struct {
-    char *str;
-    int i;
-} StrInt;
+    const char *arch;
+    int cpu;
+} CPUTypes;
 
-static StrInt initArches[] = {
+static const CPUTypes initArches[] = {
+#if defined(__i386__) || defined(__x86_64__)
     {"i386", CPU_TYPE_I386},
-    {"ppc", CPU_TYPE_POWERPC},
-    {"ppc64", CPU_TYPE_POWERPC64},
     {"x86_64", CPU_TYPE_X86_64},
-    {NULL, 0}
+#elif defined(__arm__)
+    {"arm", CPU_TYPE_ARM},
+#else
+#error "Unsupported architecture"
+#endif
+    {NULL, 0} // sentinel
 };
 
+/*
+ * ignore contains architectures supported by previous releases, but
+ * now unsupported.  The seen field will be set to true if the corresponding
+ * architecture was specified.
+ */
+
+typedef struct {
+    const char *arch;
+    bool seen;
+} Ignore;
+
+static Ignore ignore[] = {
+#if defined(__i386__) || defined(__x86_64__)
+    {"ppc", false},
+    {"ppc64", false},
+#endif
+    {NULL, false} // sentinel
+};
+
+/* The total number of architectures specified */
+static int archCount = 0;
+
+/* environment SPI */
+char **_copyenv(char **env);
+int _setenvp(const char *name, const char *value, int rewrite, char ***envp, void *state);
+int _unsetenvp(const char *name, char ***envp, void *state);
+
+/* copy of environment */
+char **envCopy = NULL;
+extern char **environ;
+
+/*
+ * The native 32 and 64-bit architectures (this is relative to the architecture
+ * the arch command is running.  NULL means unsupported.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+#define NATIVE_32      "i386"
+#define NATIVE_64      "x86_64"
+#elif defined(__arm__)
+#define NATIVE_32      "arm"
+#define NATIVE_64      NULL
+#else
+#error "Unsupported architecture"
+#endif
+bool native32seen = false;
+bool native64seen = false;
+
 /*
  * arch - perform the original behavior of the arch and machine commands.
  * The archcmd flag is non-zero for the arch command, zero for the machine
@@ -99,20 +151,43 @@ arch(int archcmd)
 }
 
 /*
- * spawnIt - run the posix_spawn command.  count is the number of CPU types
- * in the prefs array.  pflag is non-zero to call posix_spawnp; zero means to
- * call posix_spawn.  str is the name/path to pass to posix_spawn{,p}, and
- * argv and environ are the argument and environment arrays to pass.  This
- * routine never returns.
+ * spawnIt - run the posix_spawn command.  cpu is the auto-sizing CPU structure.
+ * pflag is non-zero to call posix_spawnp; zero means to call posix_spawn.
+ * str is the name/path to pass to posix_spawn{,p}, and argv are
+ * the argument arrays to pass.  This routine never returns.
  */
 static void __dead2
-spawnIt(int count, cpu_type_t *prefs, int pflag, const char *str, char **argv, char **environ)
+spawnIt(CPU *cpu, int pflag, const char *str, char **argv)
 {
-
     posix_spawnattr_t attr;
     pid_t pid;
     int ret;
     size_t copied;
+    const Ignore *ip;
+    int count = CPUCOUNT(cpu);
+    cpu_type_t *prefs = cpu->buf;
+
+    if(count == 0) {
+       if(archCount == 0) // shouldn't happen
+           errx(1, "spawnIt called with no architectures specified");
+       for(ip = ignore; ip->arch; ip++) {
+           if(ip->seen)
+               warnx("Unsupported architecture: %s", ip->arch);
+       }
+       if(native32seen)
+           warnx("Unsupported native 32-bit architecture");
+       if(native64seen)
+           warnx("Unsupported native 64-bit architecture");
+       exit(1);
+    }
+    for(ip = ignore; ip->arch; ip++) {
+       if(ip->seen)
+           fprintf(stderr, "warning: unsupported architecture: %s\n", ip->arch);
+    }
+    if(native32seen)
+       fprintf(stderr, "warning: unsupported native 32-bit architecture\n");
+    if(native64seen)
+       fprintf(stderr, "warning: unsupported native 64-bit architecture\n");
 
     if((ret = posix_spawnattr_init(&attr)) != 0)
        errc(1, ret, "posix_spawnattr_init");
@@ -124,9 +199,9 @@ spawnIt(int count, cpu_type_t *prefs, int pflag, const char *str, char **argv, c
     if(copied != count)
        errx(1, "posix_spawnattr_setbinpref_np only copied %d of %d", (int)copied, count);
     if(pflag)
-       ret = posix_spawnp(&pid, str, NULL, &attr, argv, environ);
+       ret = posix_spawnp(&pid, str, NULL, &attr, argv, envCopy ? envCopy : environ);
     else
-       ret = posix_spawn(&pid, str, NULL, &attr, argv, environ);
+       ret = posix_spawn(&pid, str, NULL, &attr, argv, envCopy ? envCopy : environ);
     errc(1, ret, "posix_spawn%s: %s", (pflag ? "p" : ""), str);
 }
 
@@ -152,6 +227,11 @@ initCPU(CPU *cpu)
 static void
 addCPU(CPU *cpu, int n)
 {
+    archCount++;
+    if(n <= 0) { // ignore values
+       ignore[-n].seen = true; // negate to get real index
+       return;
+    }
     if(cpu->ptr >= cpu->end) {
        cpu_type_t *new = realloc(cpu->buf, (cpu->end - cpu->buf + CPUDELTA) * sizeof(cpu_type_t));
        if(!new)
@@ -235,7 +315,7 @@ useEnv(CPU *cpu, const char *name, char **execpath)
                continue; /* no cpu list, so skip */
            /* if the name matches, or there is no name, process the cpus */
            if(!*n || strcmp(n, cp) == 0) {
-               if(CPUCOUNT(cpu) <= 0) { /* only if we don't already have cpu types */
+               if(archCount <= 0) { /* only if we haven't processed architectures */
                    char *t;
                    while((t = strsep(&blk, ",")) != NULL)
                        addCPUbyname(cpu, t);
@@ -244,7 +324,7 @@ useEnv(CPU *cpu, const char *name, char **execpath)
                break;
            }
        } else { /* no colons at all, so process as default */
-           if(CPUCOUNT(cpu) <= 0) { /* only if we don't already have cpu types */
+           if(archCount <= 0) { /* only if we haven't processed architectures */
                blk = n;
                while((n = strsep(&blk, ",")) != NULL)
                    addCPUbyname(cpu, n);
@@ -255,7 +335,7 @@ useEnv(CPU *cpu, const char *name, char **execpath)
     }
     if(cpu->errs) /* errors during addCPUbyname are fatal */
        exit(1);
-    return CPUCOUNT(cpu); /* return count of cpus */
+    return archCount; /* return count of architectures */
 }
 
 /*
@@ -268,7 +348,7 @@ useEnv(CPU *cpu, const char *name, char **execpath)
  * This routine never returns.
  */
 static void __dead2
-spawnFromPreferences(CPU *cpu, int needexecpath, char **argv, char **environ)
+spawnFromPreferences(CPU *cpu, int needexecpath, char **argv)
 {
     char *epath = NULL;
     int count;
@@ -284,10 +364,10 @@ spawnFromPreferences(CPU *cpu, int needexecpath, char **argv, char **environ)
     if((count = useEnv(cpu, prog, &epath)) > 0) {
        /* if we were called as arch, use posix_spawnp */
        if(!needexecpath)
-           spawnIt(count, cpu->buf, 1, (epath ? epath : *argv), argv, environ);
+           spawnIt(cpu, 1, (epath ? epath : *argv), argv);
        /* otherwise, if we have the executable path, call posix_spawn */
        if(epath)
-           spawnIt(count, cpu->buf, 0, epath, argv, environ);
+           spawnIt(cpu, 0, epath, argv);
     }
 
     /* pathArray is use to build the .plist file path for each domain */
@@ -365,7 +445,7 @@ spawnFromPreferences(CPU *cpu, int needexecpath, char **argv, char **environ)
            warnx("%s: no entries in %s", [path UTF8String], [KeyPrefOrder UTF8String]);
            errs++;
        } else {
-           /* finally but the cpu type array */
+           /* finally build the cpu type array */
            for(i = 0; i < count; i++) {
                id a = [(NSArray *)p objectAtIndex: i];
                NSNumber *n;
@@ -385,7 +465,7 @@ spawnFromPreferences(CPU *cpu, int needexecpath, char **argv, char **environ)
        exit(1);
 
     /* call posix_spawn */
-    spawnIt(count, cpu->buf, 0, [execpath fileSystemRepresentation], argv, environ);
+    spawnIt(cpu, 0, [execpath fileSystemRepresentation], argv);
 }
 
 static void __dead2
@@ -394,10 +474,13 @@ usage(int ret)
     fprintf(stderr,
        "Usage: %s\n"
        "       Display the machine's architecture type\n"
-       "Usage: %s [-h] [[-arch_name | -arch arch_name] ...] prog [arg ...]\n"
+       "Usage: %s {-arch_name | -arch arch_name} ... [-c] [-d envname] ... [-e envname=value] ... [-h] prog [arg ...]\n"
        "       Run prog with any arguments, using the given architecture\n"
        "       order.  If no architectures are specified, use the\n"
        "       ARCHPREFERENCE environment variable, or a property list file.\n"
+       "       -c will clear out all environment variables before running prog.\n"
+       "       -d will delete the given environment variable before running prog.\n"
+       "       -e will add the given environment variable/value before running prog.\n"
        "       -h will print usage message and exit.\n",
        ARCH_PROG, ARCH_PROG);
     exit(ret);
@@ -481,23 +564,89 @@ wrapped(const char *name)
  * If no commandline cpu names are given, the environment variable
  * ARCHPREFERENCE is used.  This routine never returns.
  */
+
+#define MATCHARG(a,m)  ({ \
+    const char *arg = *(a); \
+    if(arg[1] == '-') arg++; \
+    strcmp(arg, (m)) == 0; \
+})
+    
+#define MATCHARGWITHVALUE(a,m,n,e)     ({ \
+    const char *ret = NULL; \
+    const char *arg = *(a); \
+    if(arg[1] == '-') arg++; \
+    if(strcmp(arg, (m)) == 0) { \
+       if(*++(a) == NULL) { \
+           warnx(e); \
+           usage(1); \
+       } \
+       ret = *(a); \
+    } else if(strncmp(arg, (m), (n)) == 0 && arg[n] == '=') { \
+       ret = arg + (n) + 1; \
+    } \
+    ret; \
+})
+
+#define MAKEENVCOPY(e) \
+    if(!envCopy) { \
+       envCopy = _copyenv(environ); \
+       if(envCopy == NULL) \
+           errx(1, (e)); \
+    }
+
 static void __dead2
-spawnFromArgs(CPU *cpu, char **argv, char **environ)
+spawnFromArgs(CPU *cpu, char **argv)
 {
-    char *ap;
+    const char *ap, *ret;
 
-    /* process cpu options */
+    /* process arguments */
     for(argv++; *argv && **argv == '-'; argv++) {
-       if(strcmp(*argv, "-arch") == 0) {
-           if(*++argv == NULL) {
-               warnx("-arch without architecture");
+       if((ret = MATCHARGWITHVALUE(argv, "-arch", 5, "-arch without architecture"))) {
+           ap = ret;
+       } else if(MATCHARG(argv, "-32")) {
+           ap = NATIVE_32;
+           if(!ap) {
+               native32seen = true;
+               archCount++;
+               continue;
+           }
+       } else if(MATCHARG(argv, "-64")) {
+           ap = NATIVE_64;
+           if(!ap) {
+               native64seen = true;
+               archCount++;
+               continue;
+           }
+       } else if(MATCHARG(argv, "-c")) {
+           free(envCopy);
+           envCopy = _copyenv(NULL); // create empty environment
+           if(!envCopy)
+               errx(1, "Out of memory processing -c");
+           continue;
+       } else if((ret = MATCHARGWITHVALUE(argv, "-d", 2, "-d without envname"))) {
+           MAKEENVCOPY("Out of memory processing -d");
+           _unsetenvp(ret, &envCopy, NULL);
+           continue;
+       } else if((ret = MATCHARGWITHVALUE(argv, "-e", 2, "-e without envname=value"))) {
+           MAKEENVCOPY("Out of memory processing -e");
+           const char *cp = strchr(ret, '=');
+           if(!cp) {
+               warnx("-e %s: no equal sign", ret);
                usage(1);
            }
-           ap = *argv;
-       } else if(strcmp(*argv, "-h") == 0) {
+           cp++; // skip to value
+           /*
+            * _setenvp() only uses the name before any equal sign found in
+            * the first argument.
+            */
+           _setenvp(ret, cp, 1, &envCopy, NULL);
+           continue;
+       } else if(MATCHARG(argv, "-h")) {
            usage(0);
-       } else
+       } else {
            ap = *argv + 1;
+           if(*ap == '-') ap++;
+       }
        addCPUbyname(cpu, ap);
     }
     if(cpu->errs)
@@ -513,14 +662,13 @@ spawnFromArgs(CPU *cpu, char **argv, char **environ)
      * If we don't have any architecutures, try ARCHPREFERENCE and plist
      * files.
      */
-    int count = CPUCOUNT(cpu);
-    if(count <= 0 || needexecpath)
-       spawnFromPreferences(cpu, needexecpath, argv, environ); /* doesn't return */
+    if(archCount <= 0 || needexecpath)
+       spawnFromPreferences(cpu, needexecpath, argv); /* doesn't return */
 
     /*
      * Call posix_spawnp on the program name.
      */
-    spawnIt(count, cpu->buf, 1, *argv, argv, environ);
+    spawnIt(cpu, 1, *argv, argv);
 }
 
 /*
@@ -533,14 +681,29 @@ init(CPU *cpu)
     ArchDict = [NSMutableDictionary dictionaryWithCapacity: 4];
     if(!ArchDict)
        errx(1, "Can't create NSMutableDictionary");
-    StrInt *sp;
-    for(sp = initArches; sp->str; sp++) {
-       NSString *s = [NSString stringWithUTF8String: sp->str];
+    const CPUTypes *cp;
+    for(cp = initArches; cp->arch; cp++) {
+       NSString *s = [NSString stringWithUTF8String: cp->arch];
+       if(!s)
+           errx(1, "Can't create NSString for %s", cp->arch);
+       NSNumber *n = [NSNumber numberWithInt: cp->cpu];
+       if(!n)
+           errx(1, "Can't create NSNumber for %s", cp->arch);
+       [ArchDict setObject: n forKey: s];
+    }
+    /*
+     * The valid architecture numbers above are one or greater.  The ignore
+     * values are the negative of the index in the ignore array.
+     */
+    const Ignore *ip;
+    int i;
+    for(ip = ignore, i = 0; ip->arch; ip++, i--) { // i is negative of index
+       NSString *s = [NSString stringWithUTF8String: ip->arch];
        if(!s)
-           errx(1, "Can't create NSString for %s", sp->str);
-       NSNumber *n = [NSNumber numberWithInt: sp->i];
+           errx(1, "Can't create NSString for %s", ip->arch);
+       NSNumber *n = [NSNumber numberWithInt: i];
        if(!n)
-           errx(1, "Can't create NSNumber for %s", sp->str);
+           errx(1, "Can't create NSNumber for %s", ip->arch);
        [ArchDict setObject: n forKey: s];
     }
     initCPU(cpu);
@@ -548,7 +711,7 @@ init(CPU *cpu)
 
 /* the main() routine */
 int
-main(int argc, char **argv, char **environ)
+main(int argc, char **argv)
 {
     const char *prog = getprogname();
     int my_name_is_arch;
@@ -568,9 +731,9 @@ main(int argc, char **argv, char **environ)
     init(&cpu); /* initialize */
 
     if(my_name_is_arch)
-       spawnFromArgs(&cpu, argv, environ);
+       spawnFromArgs(&cpu, argv);
     else
-       spawnFromPreferences(&cpu, 1, argv, environ);
+       spawnFromPreferences(&cpu, 1, argv);
     /* should never get here */
     [pool release];
     errx(1, "returned from spawn");
index 2704d3acd62fa783d7e6d7f8d0f8fcf1ffffdce6..460fd57eae03671c7d2f6968eeabb39df4eea14a 100644 (file)
@@ -7,7 +7,7 @@ MANPAGES = at.1
 
 PROJECT_HEADERS = privs.h pathnames.h
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID -DDAEMON_UID=1 -DDAEMON_GID=1 \
        -DDEFAULT_AT_QUEUE='a' -DDEFAULT_BATCH_QUEUE='b' \
        -DPERM_PATH=\"/usr/lib/cron/\" \
index 2d9ea9d4e91c8a9c77dcd5aee3f9a05ff0eebaa5..8ad9eabacc9d70ed3bff158e8d36dd2a0c398005 100644 (file)
@@ -6,7 +6,7 @@ CFILES = atrun.c
 MANPAGES = atrun.8
 LAUNCHD_PLISTS = com.apple.atrun.plist
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -DDAEMON_UID=1 -DDAEMON_GID=1 -I../at.tproj
 Extra_LD_Flags = -dead_strip
 
diff --git a/bootlog.tproj/Makefile b/bootlog.tproj/Makefile
deleted file mode 100644 (file)
index 2cb67d9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-Project = bootlog
-Install_Dir = /usr/libexec
-
-CFILES = bootlog.c
-MANPAGES = bootlog.8
-LAUNCHD_PLISTS = com.apple.bootlog.plist
-
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
-Extra_LD_Flags = -dead_strip
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       plutil -convert binary1 "$(DSTROOT)/System/Library/LaunchDaemons/$(LAUNCHD_PLISTS)"
diff --git a/bootlog.tproj/bootlog.8 b/bootlog.tproj/bootlog.8
deleted file mode 100644 (file)
index ae14b71..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-.\"
-.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
-.\"
-.\" @APPLE_LICENSE_HEADER_START@
-.\" 
-.\" This file contains Original Code and/or Modifications of Original Code
-.\" as defined in and that are subject to the Apple Public Source License
-.\" Version 2.0 (the 'License'). You may not use this file except in
-.\" compliance with the License. Please obtain a copy of the License at
-.\" http://www.opensource.apple.com/apsl/ and read it before using this
-.\" file.
-.\" 
-.\" The Original Code and all software distributed under the License are
-.\" distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-.\" FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-.\" Please see the License for the specific language governing rights and
-.\" limitations under the License.
-.\" 
-.\" @APPLE_LICENSE_HEADER_END@
-.\"
-.Dd Dec 15, 2006
-.Dt BOOTLOG 8
-.Sh NAME
-.Nm bootlog
-.Nd log a utmpx boot record
-.\"
-.Sh SYOPSIS
-.Nm bootlog
-.Sh DESCRIPTION
-The
-.Nm bootlog
-command simply creates a
-.Xr utmpx 5
-boot record at boot time.
-It is run by
-.Xr launchd 8 .
-.Sh SEE ALSO
-.Xr utmpx 5 ,
-.Xr launchd 8
diff --git a/bootlog.tproj/bootlog.c b/bootlog.tproj/bootlog.c
deleted file mode 100644 (file)
index b7ab68d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <utmpx.h>
-
-#define _PATH_ASL_IN "/var/run/asl_input"
-
-#define REPEAT 100
-#define SLEEP  2
-
-static void
-asl_running(void)
-{
-       int sock, i;
-       struct sockaddr_un server;
-       socklen_t len;
-       int status;
-
-       sock = socket(AF_UNIX, SOCK_STREAM, 0); 
-       if (sock < 0)
-               exit(1);
-
-       memset(&server, 0, sizeof(struct sockaddr_un));
-       server.sun_family = AF_UNIX;
-
-       strcpy(server.sun_path, _PATH_ASL_IN);
-       server.sun_len = strlen(server.sun_path) + 1;
-       len = sizeof(server.sun_len) + sizeof(server.sun_family) + server.sun_len;
-
-       i = REPEAT;
-       for(;;) {
-           status = connect(sock, (const struct sockaddr *)&server, len);
-           if (status >= 0)
-               break;
-           if(--i <= 0)
-               exit(1);
-           sleep(SLEEP);
-       }
-
-       close(sock);
-}
-
-int
-main()
-{
-    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
-    struct utmpx utx;
-    size_t len;
-
-    bzero(&utx, sizeof(utx));
-    utx.ut_type = BOOT_TIME;
-    utx.ut_pid = 1; // on behalf of launchd
-
-    /* get the boot time */
-    len = sizeof(struct timeval);
-    if(sysctl(mib, 2, &utx.ut_tv, &len, NULL, 0) < 0)
-       gettimeofday(&utx.ut_tv, NULL); /* fallback to now */
-
-    /* wait for asl before logging */
-    asl_running();
-    pututxline(&utx);
-    return 0;
-}
diff --git a/bootlog.tproj/com.apple.bootlog.plist b/bootlog.tproj/com.apple.bootlog.plist
deleted file mode 100644 (file)
index 40579f8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>Label</key>
-       <string>com.apple.bootlog</string>
-       <key>ProgramArguments</key>
-       <array>
-               <string>/usr/libexec/bootlog</string>
-       </array>
-       <key>RunAtLoad</key>
-       <true/>
-       <key>LaunchOnlyOnce</key>
-       <true/>
-</dict>
-</plist>
index 6c8926efa0450e87820af5e39f14070ba35347c9..f9f594bf463f53ac50a1c0a52e17d9db985e53b3 100644 (file)
@@ -5,14 +5,14 @@ CFILES = od_passwd.c nis_passwd.c file_passwd.c pam_passwd.c passwd.c\
        stringops.c
 MANPAGES = chkpasswd.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_Frameworks = -framework CoreFoundation -framework OpenDirectory -lpam
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
 
-Install_Program_Mode = 04555
+Install_Program_Mode = 00555
 
 after_install:
        $(INSTALL_DIRECTORY) "$(DSTROOT)"/private/etc/pam.d
index 56e7a00755b9511f28e0fa395031710847da1361..24d49131e7e77107cdd7e8e7839dfb9851da0230 100644 (file)
@@ -39,7 +39,7 @@
 extern void checkpasswd(char *, char *);
 
 char *
-getline(FILE *fp)
+_getline(FILE *fp)
 {
        static char s[BUFSIZE];
        int len;
@@ -115,7 +115,7 @@ find_user(char *uname, FILE *fp)
 
        rewind(fp);
 
-       while (NULL != (line = getline(fp)))
+       while (NULL != (line = _getline(fp)))
        {
                if (line[0] == '#') continue;
                pw = parse_user(line);
@@ -172,7 +172,7 @@ rewrite_file(char *pwname, FILE *fp, struct passwd *newpw)
 
        rewind(fp);
 
-       while (NULL != (line = getline(fp)))
+       while (NULL != (line = _getline(fp)))
        {
                if (line[0] == '#')
                {
@@ -232,7 +232,7 @@ rewrite_file(char *pwname, FILE *fp, struct passwd *newpw)
                exit(1);
        }
 
-       while (NULL != (line = getline(tfp)))
+       while (NULL != (line = _getline(tfp)))
        {
                fprintf(fp, "%s", line);
                if (line[0] != '#') fprintf(fp, "\n");
index c2cca606b4f811753c3119cf8bb9d25ef9336589..b446cd3eec6ed3322e725e71e036f560e3144b60 100644 (file)
@@ -6,7 +6,7 @@ CFILES = chpass.c edit.c field.c pw_copy.c table.c util.c \
         open_directory.c
 MANPAGES = chpass.1
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_CC_Flags += -DOPEN_DIRECTORY -fconstant-cfstrings \
        -I../pwd_mkdb.tproj -I../vipw.tproj
 Extra_LD_Flags = -dead_strip
@@ -15,7 +15,7 @@ Extra_Frameworks = -framework OpenDirectory -framework CoreFoundation
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
 
-Install_Program_Mode = 04555
+Install_Program_Mode = 00555
 
 after_install:
        $(LN) -sf chpass.1 $(DSTROOT)/usr/share/man/man1/chfn.1
index 8195e2c3a5d9b7a62dd79a451fb7d83e981f3c74..44f37d52e7fd7d3714c10c07290f34247d5841fa 100644 (file)
@@ -123,6 +123,7 @@ main(int argc, char *argv[])
        struct passwd *old_pw, *pw;
        int ch, tfd;
        char tfn[MAXPATHLEN];
+       char *tmpdir;
 #endif
        char *arg = NULL;
        uid_t uid;
@@ -331,7 +332,10 @@ main(int argc, char *argv[])
        if (op == EDITENTRY) {
 #ifdef OPEN_DIRECTORY
                setrestricted(attrs_orig);
-               snprintf(tfn, sizeof(tfn), "/etc/%s.XXXXXX", progname);
+               tmpdir = getenv("TMPDIR");
+               if (!tmpdir)
+                       tmpdir = P_tmpdir; // defined in the system headers, defaults to /tmp
+               snprintf(tfn, sizeof(tfn), "%s/%s.XXXXXX", tmpdir, progname);
                if ((tfd = mkstemp(tfn)) == -1)
                        err(1, "%s", tfn);
                attrs = (CFMutableDictionaryRef)edit(tfn, attrs_orig);
index 9627ad32f69ae2b4759ee9951c32da973ead7e86..5f9392bcec9fdf8a9d1534b652137321bb1078da 100644 (file)
@@ -61,11 +61,13 @@ prompt_passwd(CFStringRef user)
 {
        CFStringRef result = NULL;
        CFStringRef prompt = CFStringCreateWithFormat(NULL, NULL, CFSTR("Password for %@: "), user);
-       char buf[128];
-       CFStringGetCString(prompt, buf, sizeof(buf), kCFStringEncodingUTF8);
+       size_t prompt_size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(prompt), kCFStringEncodingUTF8);
+       char* buf = malloc(prompt_size);
+       CFStringGetCString(prompt, buf, prompt_size, kCFStringEncodingUTF8);
        char* pass = getpass(buf);
        result = CFStringCreateWithCString(NULL, pass, kCFStringEncodingUTF8);
        memset(pass, 0, strlen(pass));
+       free(buf);
        CFRelease(prompt);
        return result;
 }
@@ -88,93 +90,24 @@ show_error(CFErrorRef error) {
        }
 }
 
-static int
-is_singleuser(void) {
-       uint32_t su = 0;
-       size_t susz = sizeof(su);
-       if (sysctlbyname("kern.singleuser", &su, &susz, NULL, 0) != 0) {
-               return 0;
-       } else {
-               return (int)su;
-       }
-}
-
-static int
-load_DirectoryServicesLocal() {
-       const char* launchctl = "/bin/launchctl";
-       const char* plist = "/System/Library/LaunchDaemons/com.apple.DirectoryServicesLocal.plist";
-
-       pid_t pid = fork();
-       int status, res;
-       switch (pid) {
-               case -1: // ERROR
-                       perror("launchctl");
-                       return 0;
-               case 0: // CHILD
-                       execl(launchctl, launchctl, "load", plist, NULL);
-                       /* NOT REACHED */
-                       perror("launchctl");
-                       exit(1);
-                       break;
-               default: // PARENT
-                       do {
-                               res = waitpid(pid, &status, 0);
-                       } while (res == -1 && errno == EINTR);
-                       if (res == -1) {
-                               perror("launchctl");
-                               return 0;
-                       }
-                       break;
-       }
-       return (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS));
-}
-
 ODRecordRef
 odGetUser(CFStringRef location, CFStringRef authname, CFStringRef user, CFDictionaryRef* attrs)
 {
-       ODSessionRef session = NULL;
        ODNodeRef node = NULL;
        ODRecordRef rec = NULL;
        CFErrorRef error = NULL;
 
        assert(attrs);
 
-       /*
-        * Connect to DS server
-        */
-       session = ODSessionCreate(NULL, NULL, &error);
-       if ( !session && error && CFErrorGetCode(error) == kODErrorSessionDaemonNotRunning ) {
-               /*
-                * In single-user mode, attempt to load the local DS daemon.
-                */
-               if (is_singleuser() && load_DirectoryServicesLocal()) {
-                       CFTypeRef keys[] = { kODSessionLocalPath };
-                       CFTypeRef vals[] = { CFSTR("/var/db/dslocal") };
-                       CFDictionaryRef opts = CFDictionaryCreate(NULL, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                       if (opts) {
-                               session = ODSessionCreate(NULL, opts, &error);
-                               CFRelease(opts);
-                       }
-
-                       if (!location) {
-                               location = CFRetain(CFSTR("/Local/Default"));
-                       }
-               } else {
-                       show_error(error);
-                       return NULL;
-               }
-       }
-
        /*
         * Open the specified node, or perform a search.
         * Copy the record and put the record's location into DSPath.
         */
        if (location) {
-               node = ODNodeCreateWithName(NULL, session, location, &error);
+               node = ODNodeCreateWithName(NULL, kODSessionDefault, location, &error);
        } else {
-               node = ODNodeCreateWithNodeType(NULL, session, kODNodeTypeAuthentication, &error);
+               node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODNodeTypeAuthentication, &error);
        }
-       if (session) CFRelease(session);
        if (node) {
                CFTypeRef       vals[] = { kODAttributeTypeStandardOnly };
                CFArrayRef desiredAttrs = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks);
index bb05ae40952c8ac21bcd662fd2c7fe8ce5882d33..a0e23f99be3f7e6ca0a65819dab51c02dd9ef043 100644 (file)
@@ -3,14 +3,15 @@ Install_Dir = /usr/libexec
 
 CFILES = dirhelper.c
 SERVERDEFS = /usr/local/include/dirhelper.defs
+USERDEFS = $(SERVERDEFS)
 MANPAGES = dirhelper.8
 LAUNCHD_PLISTS = com.apple.bsd.dirhelper.plist
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_CC_Flags += -D__MigTypeCheck=1
 Extra_LD_Flags = -dead_strip
 Extra_LD_Flags += -lbsm
 
-#CFLAGS = -g -mdynamic-no-pic -Os -Wall -Wextra -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 $(RC_CFLAGS) -I $(OBJDIR)
+#CFLAGS = -g -Os -Wall -Wextra -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror -D__MigTypeCheck=1 $(RC_CFLAGS) -I $(OBJDIR)
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index d6dff172793fcb0f526fcb1749e5b5dc5697a529..d0fcc72d6824fff3932bfabbfe460d32c53aa7bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2007, 2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -30,6 +30,7 @@
 #include <pthread.h>
 #include <pwd.h>
 #include <unistd.h>
+#include <sys/kauth.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 #include <launch.h>
 #include <dirhelper_priv.h>
 
+#include "dirhelper.h"
 #include "dirhelper_server.h"
+/*
+ * Uncomment the next line to define BOOTDEBUG, which will write timing
+ * info for clean_directories() to a file, /Debug.
+ */
+//#define BOOTDEBUG
+#ifdef BOOTDEBUG
+#include <mach/mach_time.h>
+#endif //BOOTDEBUG
 
 // globals for idle exit
 struct idle_globals {
@@ -56,12 +66,19 @@ struct idle_globals {
 
 struct idle_globals idle_globals;
 
+// argument structure for clean_thread
+struct clean_args {
+       const char** dirs;
+       int machineBoot;
+};
+
 void* idle_thread(void* param __attribute__((unused)));
 
-int file_check(const char* path, int mode, int uid, int gid);
-#define is_file(x) file_check((x), S_IFREG, -1, -1)
-#define is_directory(x) file_check((x), S_IFDIR, -1, -1)
-#define is_root_wheel_directory(x) file_check((x), S_IFDIR, 0, 0)
+int file_check(const char* path, int mode, int uid, int gid, uid_t* owner, gid_t* group);
+#define is_file(x) file_check((x), S_IFREG, -1, -1, NULL, NULL)
+#define is_directory(x) file_check((x), S_IFDIR, -1, -1, NULL, NULL)
+#define is_directory_get_owner_group(x,o,g) file_check((x), S_IFDIR, -1, -1, (o), (g))
+#define is_root_wheel_directory(x) file_check((x), S_IFDIR, 0, 0, NULL, NULL)
 
 int is_safeboot(void);
 
@@ -105,6 +122,11 @@ do___dirhelper_create_user_local(
                                "__user_local_dirname: %s", strerror(errno));
                        break;
                }
+
+               // All dirhelper directories are now at the same level, so
+               // we need to remove the DIRHELPER_TOP_STR suffix to get the
+               // parent directory.
+               path[strlen(path) - (sizeof(DIRHELPER_TOP_STR) - 1)] = 0;
                
                //
                // 1. Starting with VAR_FOLDERS_PATH, make each subdirectory
@@ -167,7 +189,7 @@ idle_thread(void* param __attribute__((unused))) {
        return NULL;
 }
 
-// If when == 0, all files are removed.  Otherwise, only regular files older than when.
+// If when == 0, all files are removed.  Otherwise, only regular files that were both created _and_ last modified before `when`.
 void
 clean_files_older_than(const char* path, time_t when) {
        FTS* fts;
@@ -181,23 +203,22 @@ clean_files_older_than(const char* path, time_t when) {
                        switch(ent->fts_info) {
                                case FTS_F:
                                case FTS_DEFAULT:
-                                       // Unlink the file if it has not been accessed since
-                                       // the specified time.  Obtain an exclusive lock so
-                                       // that we can avoid a race with other processes
-                                       // attempting to open the file.
                                        if (when == 0) {
 #if DEBUG
                                                asl_log(NULL, NULL, ASL_LEVEL_ALERT, "unlink(" VAR_FOLDERS_PATH "%s)", ent->fts_path);
 #endif
                                                (void)unlink(ent->fts_path);
-                                       } else if (S_ISREG(ent->fts_statp->st_mode) && ent->fts_statp->st_atime < when) {
+                                       } else if (S_ISREG(ent->fts_statp->st_mode) && (ent->fts_statp->st_birthtime < when) && (ent->fts_statp->st_atime < when)) {
                                                int fd = open(ent->fts_path, O_RDONLY | O_NONBLOCK);
                                                if (fd != -1) {
+                                                       // Obtain an exclusive lock so
+                                               // that we can avoid a race with other processes
+                                               // attempting to open or modify the file.
                                                        int res = flock(fd, LOCK_EX | LOCK_NB);
                                                        if (res == 0) {
                                                                struct stat sb;
                                                                res = fstat(fd, &sb);
-                                                               if (res == 0 && sb.st_atime < when) {
+                                                               if ((res == 0) && (sb.st_birthtime < when) && (sb.st_atime < when)) {
 #if DEBUG
                                                                        asl_log(NULL, NULL, ASL_LEVEL_ALERT, "unlink(" VAR_FOLDERS_PATH "%s)", ent->fts_path);
 #endif
@@ -245,13 +266,17 @@ clean_files_older_than(const char* path, time_t when) {
 }
 
 int
-file_check(const char* path, int mode, int uid, int gid) {
+file_check(const char* path, int mode, int uid, int gid, uid_t* owner, gid_t* group) {
        int check = 1;
        struct stat sb;
        if (lstat(path, &sb) == 0) {
                check = check && ((sb.st_mode & S_IFMT) == mode);
                check = check && ((sb.st_uid == (uid_t)uid) || uid == -1);
                check = check && ((sb.st_gid == (gid_t)gid) || gid == -1);
+               if (check) {
+                       if (owner) *owner = sb.st_uid;
+                       if (group) *group = sb.st_gid;
+               }
        } else {
                if (errno != ENOENT) {
                        /* This will print a shorter path after chroot() */
@@ -274,13 +299,14 @@ is_safeboot(void) {
        }
 }
 
-void
-clean_directories(const char* dirs[], int machineBoot) {
+void *
+clean_thread(void *a) {
+       struct clean_args* args = (struct clean_args*)a;
        DIR* d;
        time_t when = 0;
        int i;
 
-       if (!machineBoot) {
+       if (!args->machineBoot) {
                struct timeval now;
                long days = 3;
                const char* str = getenv("CLEAN_FILES_OLDER_THAN_DAYS");
@@ -288,8 +314,8 @@ clean_directories(const char* dirs[], int machineBoot) {
                        days = strtol(str, NULL, 0);
                }
                (void)gettimeofday(&now, NULL);
-               for (i = 0; dirs[i]; i++)
-                       asl_log(NULL, NULL, ASL_LEVEL_INFO, "Cleaning %s older than %ld days", dirs[i], days);
+               for (i = 0; args->dirs[i]; i++)
+                       asl_log(NULL, NULL, ASL_LEVEL_INFO, "Cleaning %s older than %ld days", args->dirs[i], days);
 
                when = now.tv_sec - (days * 60 * 60 * 24);
        }
@@ -299,18 +325,19 @@ clean_directories(const char* dirs[], int machineBoot) {
        size_t len = sizeof(boottime);
        if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) == -1) {
                asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", "sysctl kern.boottime", strerror(errno));
-               return;
+               return NULL;
        }
 
        if (!is_root_wheel_directory(VAR_FOLDERS_PATH)) {
                asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", VAR_FOLDERS_PATH, "invalid ownership");
-               return;
+               return NULL;
        }
 
        if (chroot(VAR_FOLDERS_PATH)) {
                asl_log(NULL, NULL, ASL_LEVEL_ERR, "chroot(%s) failed: %s",
                        VAR_FOLDERS_PATH, strerror(errno));
        }
+       chdir("/");
        if ((d = opendir("/"))) {
                struct dirent* e;
                char path[PATH_MAX];
@@ -327,18 +354,34 @@ clean_directories(const char* dirs[], int machineBoot) {
                                        
                                        // /var/folders/*/*
                                        while ((e2 = readdir(d2))) {
-                                               char temporary_items[PATH_MAX];
+                                               char dirbuf[PATH_MAX];
+                                               uid_t owner;
+                                               gid_t group;
                                                if (strcmp(e2->d_name, ".") == 0 || strcmp(e2->d_name, "..") == 0) continue;
-                                               for (i = 0; dirs[i]; i++) {
-                                                       const char *name = dirs[i];
-                                                       snprintf(temporary_items, sizeof(temporary_items),
+                                               snprintf(dirbuf, sizeof(dirbuf),
+                                                       "%s/%s", path, e2->d_name);
+                                               if (!is_directory_get_owner_group(dirbuf, &owner, &group)) continue;
+                                               if (pthread_setugid_np(owner, group) != 0) {
+                                                       asl_log(NULL, NULL, ASL_LEVEL_ERR,
+                                                               "skipping %s: pthread_setugid_np(%u, %u): %s",
+                                                               dirbuf, owner, group, strerror(errno));
+                                                       continue;
+                                               }
+                                               for (i = 0; args->dirs[i]; i++) {
+                                                       const char *name = args->dirs[i];
+                                                       snprintf(dirbuf, sizeof(dirbuf),
                                                                 "%s/%s/%s", path, e2->d_name, name);
-                                                       if (is_directory(temporary_items)) {
+                                                       if (is_directory(dirbuf)) {
                                                                // at boot time we clean all files,
                                                                // otherwise only clean regular files.
-                                                               clean_files_older_than(temporary_items, when);
+                                                               clean_files_older_than(dirbuf, when);
                                                        }
                                                }
+                                               if (pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) != 0) {
+                                                       asl_log(NULL, NULL, ASL_LEVEL_ERR,
+                                                               "%s: pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE): %s",
+                                                               dirbuf, strerror(errno));
+                                               }
                                        }
                                        closedir(d2);
                                } else {
@@ -351,6 +394,48 @@ clean_directories(const char* dirs[], int machineBoot) {
        } else {
                asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: %s", VAR_FOLDERS_PATH, strerror(errno));
        }
+       return NULL;
+}
+
+void
+clean_directories(const char* dirs[], int machineBoot) {
+       struct clean_args args;
+       pthread_t t;
+       int ret;
+#ifdef BOOTDEBUG
+       double ratio;
+       struct mach_timebase_info info;
+       uint64_t begin, end;
+       FILE *debug;
+
+       mach_timebase_info(&info);
+       ratio = (double)info.numer / ((double)info.denom * NSEC_PER_SEC);
+       begin = mach_absolute_time();
+       if((debug = fopen("/Debug", "a")) != NULL) {
+           fprintf(debug, "clean_directories: machineBoot=%d\n", machineBoot);
+       }
+#endif //BOOTDEBUG
+
+       args.dirs = dirs;
+       args.machineBoot = machineBoot;
+       ret = pthread_create(&t, NULL, clean_thread, &args);
+       if (ret == 0) {
+               ret = pthread_join(t, NULL);
+               if (ret) {
+                       asl_log(NULL, NULL, ASL_LEVEL_ERR, "clean_directories: pthread_join: %s",
+                               strerror(ret));
+               }
+       } else {
+               asl_log(NULL, NULL, ASL_LEVEL_ERR, "clean_directories: pthread_create: %s",
+                       strerror(ret));
+       }
+#ifdef BOOTDEBUG
+       end = mach_absolute_time();
+       if(debug) {
+           fprintf(debug, "clean_directories: %f secs\n", ratio * (end - begin));
+           fclose(debug);
+       }
+#endif //BOOTDEBUG
 }
 
 int
@@ -359,6 +444,19 @@ main(int argc, char* argv[]) {
        kern_return_t kr;
        long idle_timeout = 30; // default 30 second timeout
 
+#ifdef BOOTDEBUG
+       {
+               FILE *debug;
+               int i;
+               if((debug = fopen("/Debug", "a")) != NULL) {
+                   for(i = 0; i < argc; i++) {
+                           fprintf(debug, " %s", argv[i]);
+                   }
+                   fputc('\n', debug);
+                   fclose(debug);
+               }
+       }
+#endif //BOOTDEBUG
        // Clean up TemporaryItems directory when launched at boot.
        // It is safe to clean all file types at this time.
        if (argc > 1 && strcmp(argv[1], "-machineBoot") == 0) {
index 7ab0dcf7dd8a0ec33698d25f0c4323a13cab950e..c2b646bc154f503ff0de3ee8aac1726d9aeec481 100644 (file)
@@ -5,7 +5,7 @@ CFILES = dmesg.c
 MANPAGES = dmesg.8
 MAKEFILE = tool.make
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 Extra_LD_Flags += -lproc
 
index 8ac4c66a94efe67f2b8eea506e420b5cd84d4aae..ad26fb0f0aee391d301d6800bd098b17e3172bb8 100644 (file)
@@ -8,12 +8,12 @@ USERDEFS = backing_store_alerts.defs
 MANPAGES = dynamic_pager.8
 LAUNCHD_PLISTS = com.apple.dynamic_pager.plist
 
-Extra_CC_Flags = -mdynamic-no-pic -Wall -Werror
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -DNO_DIRECT_RPC
 
-Extra_Frameworks += -framework CoreFoundation -framework IOKit
+Extra_Frameworks += -framework CoreFoundation -framework SystemConfiguration
 Extra_MIG_Flags = -R -untyped -DNO_DIRECT_RPC
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
@@ -27,7 +27,7 @@ endif
 after_install:
 ifeq "$(Embedded)" "YES"
        /usr/libexec/PlistBuddy -x \
-       -c "Add :Disabled bool true" \
+       -c "Add :LaunchOnlyOnce bool true" \
        "$(DSTROOT)/System/Library/LaunchDaemons/com.apple.dynamic_pager.plist"
 endif
        plutil -convert binary1 "$(DSTROOT)/System/Library/LaunchDaemons/com.apple.dynamic_pager.plist"
index b44878f7ffdd8079564a022398fe5dbcb5e348dc..835279160cc04be30d3a2fce2626860b01ec33d7 100644 (file)
@@ -32,8 +32,6 @@
 #include <paths.h>
 #include <dirent.h>
 
-#include <IOKit/ps/IOPowerSourcesPrivate.h>
-#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <default_pager/default_pager_types.h>
@@ -41,7 +39,6 @@
 #include <backing_store_alerts.h>
 #include <backing_store_triggers_server.h>
 
-
 /*
  * HI_WATER_DEFAULT set to this funny value to 
  * match the size that the low space application
 
 #define MAX_LIMITS 8
 
+#if TARGET_OS_EMBEDDED
+
+#include <System/sys/content_protection.h>
+
+#define USE_SYSTEMCONFIGURATION_PRIVATE_HEADERS 1
+#include <SystemConfiguration/SystemConfiguration.h>
+
+enum {
+       VM_PAGING_MODE_DISABLED = 0,
+       VM_PAGING_MODE_FREEZE,
+       VM_PAGING_MODE_DYNAMIC
+};
+
+#define VM_FREEZE_SYSCTL "vm.freeze_enabled"
+#define FREEZE_FIXED_SWAP_SIZE (128 * 1024 * 1024)
+#endif
 
 struct limit {
         unsigned int size;
@@ -238,7 +251,14 @@ default_pager_space_alert(alert_port, flags)
                if (fd == -1) {
                        /* force error recovery below */
                        error = -1;
-               } else {
+               }       
+#if TARGET_OS_EMBEDDED
+               else {
+                       error = fcntl(fd, F_SETPROTECTIONCLASS, PROTECTION_CLASS_F);
+               }
+#endif
+               
+               if(!error) {    
                        error = fcntl(fd, F_SETSIZE, &filesize);
                        if(error) {
                                error = ftruncate(fd, filesize);
@@ -409,6 +429,16 @@ paging_setup(flags, size, priority, low, high, encrypted)
                exit(EXIT_FAILURE);
        }
 
+#if TARGET_OS_EMBEDDED
+       error = fcntl(fd, F_SETPROTECTIONCLASS, PROTECTION_CLASS_F);
+       if (error == -1) {
+               fprintf(stderr, "dynamic_pager: cannot set file protection class!\n");
+               unlink(subfile);
+               close(fd);
+               exit(EXIT_FAILURE);
+       }
+#endif
+
        error = fcntl(fd, F_SETSIZE, &filesize);
        if(error) {
                error = ftruncate(fd, filesize);
@@ -483,8 +513,8 @@ clean_swap_directory(const char *path)
        closedir(dir);
 }
 
-#define VM_PREFS_PLIST                                 "/Library/Preferences/com.apple.virtualMemory.plist"
-#define VM_PREFS_ENCRYPT_SWAP_KEY      "UseEncryptedSwap"
+#define VM_PREFS_PLIST                         "/Library/Preferences/com.apple.virtualMemory.plist"
+#define VM_PREFS_DISABLE_ENCRYPT_SWAP_KEY      "DisableEncryptedSwap"
 
 static boolean_t
 should_encrypt_swap(void)
@@ -495,12 +525,9 @@ should_encrypt_swap(void)
        CFDataRef               resourceData;
        SInt32                  errorCode;
        CFURLRef                fileURL;
-       CFTypeRef               value;
-       boolean_t               should_encrypt;
-       boolean_t               explicit_value;
-
-       explicit_value = false;
-       should_encrypt = true;
+       CFTypeRef               disable_encrypted_swap;
+       boolean_t               should_encrypt = TRUE;
+       boolean_t               explicit_value = FALSE;
 
        fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)VM_PREFS_PLIST, strlen(VM_PREFS_PLIST), false);
        if (fileURL == NULL) {
@@ -525,18 +552,18 @@ should_encrypt_swap(void)
        propertyListType = CFGetTypeID(propertyList);
 
        if (propertyListType == CFDictionaryGetTypeID()) {      
-               value = (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef) propertyList, CFSTR(VM_PREFS_ENCRYPT_SWAP_KEY));
-               if (value == NULL) {
-                       /* no value: use the default value */
-               } else if (CFGetTypeID(value) != CFBooleanGetTypeID()) {
+               disable_encrypted_swap = (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef) propertyList, CFSTR(VM_PREFS_DISABLE_ENCRYPT_SWAP_KEY));
+               if (disable_encrypted_swap == NULL) {
+                       /* no value: use the default value i.e. encrypted swap ON */
+               } else if (CFGetTypeID(disable_encrypted_swap) != CFBooleanGetTypeID()) {
                        fprintf(stderr, "%s: wrong type for key \"%s\"\n",
-                               getprogname(), VM_PREFS_ENCRYPT_SWAP_KEY);
+                               getprogname(), VM_PREFS_DISABLE_ENCRYPT_SWAP_KEY);
                        /* bogus value, assume it's "true" for safety's sake */
-                       should_encrypt = true;
-                       explicit_value = true;
+                       should_encrypt = TRUE;
+                       explicit_value = TRUE;
                } else {
-                       should_encrypt = CFBooleanGetValue((CFBooleanRef)value);
-                       explicit_value = true;
+                       should_encrypt = CFBooleanGetValue((CFBooleanRef)disable_encrypted_swap) ? FALSE : TRUE;
+                       explicit_value = TRUE;
                }
        }
        else {
@@ -549,19 +576,43 @@ done:
        if (! explicit_value) {
 #if TARGET_OS_EMBEDDED
                should_encrypt = FALSE;
-#else
-               /* by default, encrypt swap on laptops only */
-               /*
-                * Look for battery power source.
-                */
-               should_encrypt = (kCFBooleanTrue == IOPSPowerSourceSupported(NULL, CFSTR(kIOPMBatteryPowerKey)));
-               /*fprintf(stderr, "dynamic_pager: battery power source: %d\n", should_encrypt);*/
 #endif
        }
 
        return should_encrypt;
 }
 
+#if TARGET_OS_EMBEDDED
+
+#define VM_PREFS_PAGING_MODE_PLIST     "com.apple.virtualMemoryMode.plist"
+#define VM_PREFS_PAGING_MODE_KEY       "Mode"
+
+static uint32_t
+get_paging_mode(void)
+{
+       SCPreferencesRef paging_prefs;
+       uint32_t paging_mode;
+       
+       paging_mode = VM_PAGING_MODE_FREEZE; /* default */
+       
+       paging_prefs = SCPreferencesCreate(NULL, CFSTR("dynamic_pager"), CFSTR(VM_PREFS_PAGING_MODE_PLIST));
+       if (paging_prefs) {
+               CFNumberRef value;
+
+               value = SCPreferencesGetValue(paging_prefs, CFSTR(VM_PREFS_PAGING_MODE_KEY));
+               
+               if (value && (CFGetTypeID( value ) == CFNumberGetTypeID() ) ) {
+                       CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &paging_mode);
+               } 
+
+               CFRelease(paging_prefs);
+       }
+       
+       return paging_mode;
+}
+
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -571,6 +622,14 @@ main(int argc, char **argv)
        int ch;
        int variable_sized = 1,flags=0;
        boolean_t       encrypted_swap;
+       static char tmp[1024];
+       struct statfs sfs;
+       char *q;
+#if TARGET_OS_EMBEDDED
+       int err;
+       uint32_t paging_mode;
+       size_t paging_mode_length;
+#endif
 
 /*
        setlinebuf(stdout);
@@ -630,10 +689,62 @@ retry:
                }
        }
 
+       /*
+        * get rid of the filename at the end of the swap file specification
+        * we only want the portion of the pathname that should already exist
+        */
+       strcpy(tmp, fileroot);
+       if ((q = strrchr(tmp, '/')))
+               *q = 0;
+
+       /*
+        * Remove all files in the swap directory.
+        */
+       clean_swap_directory(tmp);
+
+#if TARGET_OS_EMBEDDED
+       paging_mode = get_paging_mode();
+       paging_mode_length = sizeof(paging_mode);
+       
+       switch (paging_mode) {
+               case VM_PAGING_MODE_DISABLED:
+                       /* Paging disabled; nothing to do here so exit */
+                       exit(EXIT_SUCCESS);
+
+               case VM_PAGING_MODE_FREEZE:
+                       /* Freeze mode; one swap file of fixed size, so enable and override defaults if set */
+                       err = sysctlbyname(VM_FREEZE_SYSCTL, NULL, 0, &paging_mode, paging_mode_length);
+                       if (err < 0) {
+                               (void)fprintf(stderr, "dynamic_pager: cannot set %s\n", VM_FREEZE_SYSCTL);
+                               exit(EXIT_FAILURE);
+                       }
+                       variable_sized = 0;
+                       limits[0].size = FREEZE_FIXED_SWAP_SIZE;
+                       break;
+
+               case VM_PAGING_MODE_DYNAMIC:
+                       /* Dynamic paging selected; proceed normally */
+                       break;
+
+               default:
+                       /* Invalid option */
+                       (void)fprintf(stderr, "dynamic_pager: invalid paging_mode %d\n", paging_mode); 
+                       exit(EXIT_FAILURE);
+       }
+#endif
+
+       if (statfs(tmp, &sfs) == -1) {
+       /*
+        * Setup the swap directory.
+        */
+               if (mkdir(tmp, 0755) == -1) {
+               (void)fprintf(stderr, "dynamic_pager: cannot create swap directory %s\n", tmp); 
+               exit(EXIT_FAILURE);
+               }
+       }
+       chown(tmp, 0, 0);
+
        if (variable_sized) {
-               static char tmp[1024];
-               struct statfs sfs;
-               char *q;
                int  i;
                int  mib[4];
                size_t len;
@@ -663,37 +774,13 @@ retry:
                 * an additional swap file when it really isn't necessary
                 */
 
-               /*
-                * get rid of the filename at the end of the swap file specification
-                * we only want the portion of the pathname that should already exist
-                */
-               strcpy(tmp, fileroot);
-               if ((q = strrchr(tmp, '/')))
-                       *q = 0;
-
-               /*
-                * Remove all files in the swap directory.
-                */
-               clean_swap_directory(tmp);
-                       
-               if (statfs(tmp, &sfs) == -1) {
+               if (statfs(tmp, &sfs) == -1) {
                        /*
-                        * Setup the swap directory.
+                        * We really can't get filesystem status,
+                        * so let's not limit the swap files...
                         */
-                       if (mkdir(tmp, 0755) == -1) {
-                               (void)fprintf(stderr, "dynamic_pager: cannot create swap directory %s\n", tmp); 
-                               exit(EXIT_FAILURE);
-                       }
-                       chown(tmp, 0, 0);
-
-                       if (statfs(tmp, &sfs) == -1) {
-                               /*
-                                * We really can't get filesystem status,
-                                * so let's not limit the swap files...
-                                */
-                               fs_limit = (u_int64_t) -1;
-                       }
-               } 
+                       fs_limit = (u_int64_t) -1;
+               }
                
                if (fs_limit != (u_int64_t) -1) {
                        /*
index 0c3f35802ec5345bcb2d41167ad05d9715dcb460..8d51d0443cea1a55b9de389c48b52ddb4ead53ee 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = fs_usage.c
 MANPAGES = fs_usage.1
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip -lutil
 
 Extra_CC_Flags += -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders\
index 6c39c7c0149c64fca48dcf4c472334c441c9cce6..f6dae972804d87cb5c681c2c6fb897a4a73c6dc9 100644 (file)
@@ -57,10 +57,16 @@ By default no output filtering occurs.
 The supported modes are:
 .Pp
 .Pa  network   
-Only network related output is displayed.
+Only network related events are displayed.
 .Pp
 .Pa filesys    
-Only file system related output is displayed.
+Only file system related events are displayed.
+.Pp
+.Pa exec               
+Only exec and spawn events are displayed.
+.Pp
+.Pa pathname   
+Only pathname related events are displayed.
 .Pp
 .Pa cachehit   
 In addition, display CACHE_HIT output.
@@ -71,6 +77,25 @@ Specifying the
 option forces a wider, more detailed output,
 regardless of the window size.
 .\" ==========
+.It Fl R Ar raw_file
+Specifies a raw trace file to process.
+.\" ==========
+.It Fl S Ar start_time
+If 
+.Fl R
+is selected, specifies the start time in microseconds to
+begin processing entries from the raw trace file. Entries
+with timestamps before the specified start time will be
+skipped.
+.\" ==========
+.It Fl E Ar end_time
+If 
+.Fl R
+is selected, specifies the ending time in microseconds to
+stop processing entries from the raw trace file.  Entries
+with timestamps beyond the specified ending time will be
+skipped.
+.\" ==========
 .It  pid | cmd
 The sampled data can be limited to a list of process ids or commands.
 When a command name is given, all processes with that name will be sampled.
@@ -98,7 +123,7 @@ The data columns displayed are as follows:
 .Pp
 .It TIMESTAMP
 TOD when call occurred.
-Wide mode will have millisecond granularity.
+Wide mode will have microsecond granularity.
 .It CALL
 The name of the network or filesystem related call, page-in, page-out,
 or physical disk access.
@@ -133,7 +158,8 @@ after the elapsed time indicates the process was scheduled out
 during this file activity.
 In this case, the elapsed time includes the wait time.
 .It PROCESS NAME
-The process that made the system call.
+The process that made the system call.  Wide mode will append the
+thread id to the process name (i.e Mail.nnn).
 .El
 .Pp
 .Sh SAMPLE USAGE
index f9e02c1355404b215ac642bc337c9f96c1e94f54..7ed62cca524c937370e8efedb9161a82b7d29b8f 100644 (file)
  */
 
 /*
-cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c
+cc -I/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -DPRIVATE -D__APPLE_PRIVATE -arch x86_64 -arch i386 -O -o fs_usage fs_usage.c
 */
 
-#define        Default_DELAY   1       /* default delay interval */
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <signal.h>
@@ -37,16 +35,20 @@ cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c
 #include <aio.h>
 #include <string.h>
 #include <dirent.h>
+#include <libc.h>
+#include <termios.h>
+#include <errno.h>
+#include <err.h>
+#include <libutil.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/time.h>
-
-#include <libc.h>
-#include <termios.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/disk.h>
 
 #ifndef KERNEL_PRIVATE
 #define KERNEL_PRIVATE
@@ -56,19 +58,29 @@ cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o fs_usage fs_usage.c
 #include <sys/kdebug.h>
 #endif /*KERNEL_PRIVATE*/
 
-#include <sys/sysctl.h>
-#include <sys/disk.h>
-#include <errno.h>
 #import <mach/clock_types.h>
 #import <mach/mach_time.h>
-#include <err.h>
-#include <libutil.h>
+
+
 
 #define F_OPENFROM      56              /* SPI: open a file relative to fd (must be a dir) */
 #define F_UNLINKFROM    57              /* SPI: open a file relative to fd (must be a dir) */
 #define F_CHECK_OPENEVT 58              /* SPI: if a process is marked OPENEVT, or in O_EVTONLY on opens of this vnode */
 
 
+#ifndef        RAW_VERSION1
+typedef struct {
+        int             version_no;
+        int             thread_count;
+        uint64_t        TOD_secs;
+       uint32_t        TOD_usecs;
+} RAW_header;
+
+#define RAW_VERSION0    0x55aa0000
+#define RAW_VERSION1    0x55aa0101
+#endif
+
+
 #define MAXINDEX 2048
 
 typedef struct LibraryRange {
@@ -110,25 +122,29 @@ typedef struct LibraryInfo {
 LibraryInfo frameworkInfo[MAXINDEX];
 int numFrameworks = 0;
 
-void lookup_name(uint64_t user_addr, char **type, char **name);
-
 
 /* 
  MAXCOLS controls when extra data kicks in.
  MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
  If NUMPARMS changes to match the kernel, it will automatically
  get reflected in the -w mode output.
-*/
* MAXCOLS controls when extra data kicks in.
* MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
* If NUMPARMS changes to match the kernel, it will automatically
* get reflected in the -w mode output.
+ */
 #define NUMPARMS 23
 #define PATHLENGTH (NUMPARMS*sizeof(uintptr_t))
+
 #define MAXCOLS 132
 #define MAX_WIDE_MODE_COLS (PATHLENGTH + 80)
 #define MAXWIDTH MAX_WIDE_MODE_COLS + 64
 
+
+typedef struct th_info *th_info_t;
+
 struct th_info {
-        int  my_index;
-        int  in_filemgr;
+       th_info_t  next;
         uintptr_t  thread;
+        uintptr_t  child_thread;
+
+        int  in_filemgr;
         int  pid;
         int  type;
         int  arg1;
@@ -139,33 +155,46 @@ struct th_info {
         int  arg6;
         int  arg7;
         int  arg8;
-        uintptr_t  child_thread;
         int  waited;
         double stime;
         uintptr_t *pathptr;
-        uintptr_t pathname[NUMPARMS + 1];   /* add room for null terminator */
+        uintptr_t pathname[NUMPARMS + 1];      /* add room for null terminator */
+        uintptr_t pathname2[NUMPARMS + 1];     /* add room for null terminator */
+};
+
+
+typedef struct threadmap * threadmap_t;
+
+struct threadmap {
+       threadmap_t     tm_next;
+
+       uintptr_t       tm_thread;
+       unsigned int    tm_setsize;     /* this is a bit count */
+       unsigned long  *tm_setptr;      /* file descripter bitmap */
+       char            tm_command[MAXCOMLEN + 1];
 };
 
-#define MAX_THREADS 1024
-struct th_info th_state[MAX_THREADS];
 
-kd_threadmap *last_map = NULL;
-int    last_thread = 0;
-int    map_is_the_same = 0;
+#define HASH_SIZE       1024
+#define HASH_MASK       1023
+
+th_info_t      th_info_hash[HASH_SIZE];
+th_info_t      th_info_freelist;
+
+threadmap_t    threadmap_hash[HASH_SIZE];
+threadmap_t    threadmap_freelist;
+
 
 int  filemgr_in_progress = 0;
-int  execs_in_progress = 0;
-int  cur_start = 0;
-int  cur_max = 0;
 int  need_new_map = 1;
 int  bias_secs = 0;
 long last_time;
 int  wideflag = 0;
 int  columns = 0;
-int  select_pid_mode = 0;  /* Flag set indicates that output is restricted
-                             to selected pids or commands */
 
 int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
+int  select_pid_mode = 0;  /* Flag set indicates that output is restricted
+                             to selected pids or commands */
 
 char   *arguments = 0;
 int     argmax = 0;
@@ -190,6 +219,7 @@ int usleep_ms = USLEEP_MIN;
 int filter_mode = CACHEHIT_FILTER;
 
 #define NFS_DEV -1
+#define CS_DEV -2
 
 struct diskrec {
         struct diskrec *next;
@@ -218,30 +248,53 @@ struct diskio *free_diskios = NULL;
 struct diskio *busy_diskios = NULL;
 
 
-
 struct diskio *insert_diskio();
 struct diskio *complete_diskio();
 void           free_diskio();
 void           print_diskio();
+
+int            check_filter_mode(struct th_info *, int, int, int, char *);
 void            format_print(struct th_info *, char *, uintptr_t, int, int, int, int, int, int, double, double, int, char *, struct diskio *);
-void                   enter_syscall_now(uintptr_t, int, kd_buf *, char *, double);
-void                   enter_syscall(uintptr_t, int, kd_buf *, char *, double);
-void            exit_syscall(char *, uintptr_t, int, int, int, int, int, int, double);
-void                   extend_syscall(uintptr_t, int, kd_buf *);
-char           *find_disk_name();
+void           enter_event_now(uintptr_t, int, kd_buf *, char *, double);
+void           enter_event(uintptr_t, int, kd_buf *, char *, double);
+void            exit_event(char *, uintptr_t, int, int, int, int, int, int, double);
+void           extend_syscall(uintptr_t, int, kd_buf *);
+
+char           *generate_cs_disk_name(int, char *s);
+char           *find_disk_name(int);
 void           cache_disk_names();
 void           recache_disk_names();
+
+void           lookup_name(uint64_t user_addr, char **type, char **name);
 int            ReadSharedCacheMap(const char *, LibraryRange *, char *);
 void           SortFrameworkAddresses();
-void           mark_thread_waited(uintptr_t);
-int            check_filter_mode(struct th_info *, int, int, int, char *);
-void           fs_usage_fd_set(unsigned int, unsigned int);
-int            fs_usage_fd_isset(unsigned int, unsigned int);
-void           fs_usage_fd_clear(unsigned int, unsigned int);
+
+void           fs_usage_fd_set(uintptr_t, unsigned int);
+int            fs_usage_fd_isset(uintptr_t, unsigned int);
+void           fs_usage_fd_clear(uintptr_t, unsigned int);
+
 void           init_arguments_buffer();
 int            get_real_command_name(int, char *, int);
+
+void           delete_all_events();
+void           delete_event(th_info_t);
+th_info_t      add_event(uintptr_t, int);
+th_info_t      find_event(uintptr_t, int);
+void           mark_thread_waited(uintptr_t);
+
+void           read_command_map();
+void           delete_all_map_entries();
 void            create_map_entry(uintptr_t, int, char *);
-void           kill_thread_map(uintptr_t);
+void           delete_map_entry(uintptr_t);
+threadmap_t    find_map_entry(uintptr_t);
+
+void           getdivisor();
+void           argtopid();
+void           set_remove();
+void           set_pidcheck();
+void           set_pidexclude();
+int            quit();
+
 
 #define CLASS_MASK     0xff000000
 #define CSC_MASK       0xffff0000
@@ -259,39 +312,46 @@ void              kill_thread_map(uintptr_t);
 #define MACH_stkhandoff 0x01400008
 #define MACH_idle      0x01400024
 #define VFS_LOOKUP      0x03010090
-#define BSC_exit        0x040C0004
 
+#define BSC_thread_terminate    0x040c05a4
+
+#define Throttled      0x3010184
 #define SPEC_ioctl     0x3060000
+#define proc_exit      0x4010004
 
 #define P_DISKIO       0x03020000
 #define P_DISKIO_DONE  0x03020004
+#define P_DISKIO_TYPE  0x03020068
 #define P_DISKIO_MASK  (CSC_MASK | 0x4)
 
+#define P_DISKIO_READ    0x00000008
+#define P_DISKIO_ASYNC   0x00000010
+#define P_DISKIO_META    0x00000020
+#define P_DISKIO_PAGING   0x00000040
+#define P_DISKIO_THROTTLE 0x00000080
+#define P_DISKIO_PASSIVE  0x00000100
+
 #define P_WrData       0x03020000
 #define P_RdData       0x03020008
 #define P_WrMeta       0x03020020
 #define P_RdMeta       0x03020028
 #define P_PgOut                0x03020040
 #define P_PgIn         0x03020048
-#define P_WrDataAsync  0x03020010
-#define P_RdDataAsync  0x03020018
-#define P_WrMetaAsync  0x03020030
-#define P_RdMetaAsync  0x03020038
-#define P_PgOutAsync   0x03020050
-#define P_PgInAsync    0x03020058
-
-#define P_WrDataDone           0x03020004
-#define P_RdDataDone           0x0302000C
-#define P_WrMetaDone           0x03020024
-#define P_RdMetaDone           0x0302002C
-#define P_PgOutDone            0x03020044
-#define P_PgInDone             0x0302004C
-#define P_WrDataAsyncDone      0x03020014
-#define P_RdDataAsyncDone      0x0302001C
-#define P_WrMetaAsyncDone      0x03020034
-#define P_RdMetaAsyncDone      0x0302003C
-#define P_PgOutAsyncDone       0x03020054
-#define P_PgInAsyncDone                0x0302005C
+
+#define P_CS_ReadChunk         0x0a000200
+#define P_CS_ReadChunkDone     0x0a000280
+#define P_CS_WriteChunk                0x0a000210
+#define P_CS_WriteChunkDone    0x0a000290
+
+#define P_CS_Originated_Read   0x0a000500
+#define P_CS_Originated_ReadDone   0x0a000580
+#define P_CS_Originated_Write  0x0a000510
+#define P_CS_Originated_WriteDone  0x0a000590
+#define P_CS_MetaRead          0x0a000900
+#define P_CS_MetaReadDone      0x0a000980
+#define P_CS_MetaWrite         0x0a000910
+#define P_CS_MetaWriteDone     0x0a000990
+#define P_CS_SYNC_DISK         0x0a008000
 
 
 #define MSC_map_fd   0x010c00ac
@@ -312,6 +372,7 @@ void                kill_thread_map(uintptr_t);
 #define        BSC_sendto              0x040C0214
 #define BSC_socketpair         0x040C021C
 
+#define BSC_exit               0x040C0004
 #define BSC_read               0x040C000C
 #define BSC_write              0x040C0010
 #define BSC_open               0x040C0014
@@ -353,7 +414,9 @@ void                kill_thread_map(uintptr_t);
 #define BSC_pread              0x040C0264
 #define BSC_pwrite             0x040C0268
 #define BSC_statfs             0x040C0274      
-#define BSC_fstatfs            0x040C0278      
+#define BSC_fstatfs            0x040C0278
+#define BSC_unmount            0x040C027C
+#define BSC_mount              0x040C029C
 #define BSC_stat               0x040C02F0      
 #define BSC_fstat              0x040C02F4      
 #define BSC_lstat              0x040C02F8      
@@ -386,6 +449,7 @@ void                kill_thread_map(uintptr_t);
 #define BSC_listxattr          0x040C03C0
 #define BSC_flistxattr         0x040C03C4
 #define BSC_fsctl              0x040C03C8
+#define BSC_posix_spawn        0x040C03D0
 #define BSC_open_extended      0x040C0454
 #define BSC_stat_extended      0x040C045C
 #define BSC_lstat_extended     0x040C0460
@@ -553,6 +617,10 @@ void               kill_thread_map(uintptr_t);
 #define FMT_UMASK      32
 #define FMT_SENDFILE   33
 #define FMT_SPEC_IOCTL 34
+#define FMT_MOUNT      35
+#define FMT_UNMOUNT    36
+#define FMT_DISKIO_CS  37
+#define FMT_SYNC_DISK_CS       38
 
 #define MAX_BSD_SYSCALL        512
 
@@ -604,7 +672,9 @@ int bsd_syscall_types[] = {
        BSC_revoke,
        BSC_symlink,
        BSC_readlink,
+       BSC_exit,
        BSC_execve,
+       BSC_posix_spawn,
        BSC_umask,
        BSC_chroot,
        BSC_dup2,
@@ -631,6 +701,8 @@ int bsd_syscall_types[] = {
        BSC_stat,
        BSC_fstat,
        BSC_lstat,
+       BSC_mount,
+       BSC_unmount,
        BSC_pathconf,
        BSC_fpathconf,
        BSC_getdirentries,
@@ -794,8 +866,6 @@ int    exclude_default_pids = 1;
 struct kinfo_proc *kp_buffer = 0;
 int kp_nentries = 0;
 
-int num_cpus;
-
 #define EVENT_BASE 60000
 
 int num_events = EVENT_BASE;
@@ -812,8 +882,6 @@ char  *my_buffer;
 
 kbufinfo_t bufinfo = {0, 0, 0, 0, 0};
 
-int total_threads = 0;
-kd_threadmap *mapptr = 0;      /* pointer to list of threads */
 
 /* defines for tracking file descriptor state */
 #define FS_USAGE_FD_SETSIZE 256                /* Initial number of file descriptors per
@@ -822,24 +890,19 @@ kd_threadmap *mapptr = 0; /* pointer to list of threads */
 #define FS_USAGE_NFDBITS      (sizeof (unsigned long) * 8)
 #define FS_USAGE_NFDBYTES(n)  (((n) / FS_USAGE_NFDBITS) * sizeof (unsigned long))
 
-typedef struct {
-    unsigned int   fd_valid;       /* set if this is a valid entry */
-    uintptr_t      fd_thread;
-    unsigned int   fd_setsize;     /* this is a bit count */
-    unsigned long  *fd_setptr;     /* file descripter bitmap */
-} fd_threadmap;
-
-fd_threadmap *fdmapptr = 0;    /* pointer to list of threads for fd tracking */
-
 int trace_enabled = 0;
 int set_remove_flag = 1;
 
 char *RAW_file = (char *)0;
 int   RAW_flag = 0;
 int   RAW_fd = 0;
+
+uint64_t sample_TOD_secs;
+uint32_t sample_TOD_usecs;
+
 double bias_now = 0.0;
 double start_time = 0.0;
-double end_time = 99999999999.9;
+double end_time = 999999999999.9;
 
 
 void set_numbufs();
@@ -877,6 +940,28 @@ void leave()                       /* exit under normal conditions -- INT handler */
 }
 
 
+int
+quit(s)
+char *s;
+{
+        if (trace_enabled)
+              set_enable(0);
+
+       /* 
+        * This flag is turned off when calling
+        * quit() due to a set_remove() failure.
+        */
+       if (set_remove_flag)
+               set_remove();
+
+        fprintf(stderr, "fs_usage: ");
+       if (s)
+               fprintf(stderr, "%s", s);
+
+       exit(1);
+}
+
+
 void get_screenwidth()
 {
         struct winsize size;
@@ -900,10 +985,21 @@ void sigwinch()
                get_screenwidth();
 }
 
+
+void getdivisor()
+{
+       struct mach_timebase_info mti;
+
+       mach_timebase_info(&mti);
+
+       divisor = ((double)mti.denom / (double)mti.numer) * 1000;
+}
+
+
 int
 exit_usage(char *myname) {
 
-       fprintf(stderr, "Usage: %s [-e] [-w] [-f mode] [pid | cmd [pid | cmd]....]\n", myname);
+       fprintf(stderr, "Usage: %s [-e] [-w] [-f mode] [-R rawfile [-S start_time] [-E end_time]] [pid | cmd [pid | cmd]....]\n", myname);
        fprintf(stderr, "  -e    exclude the specified list of pids from the sample\n");
        fprintf(stderr, "        and exclude fs_usage by default\n");
        fprintf(stderr, "  -w    force wider, detailed, output\n");
@@ -913,6 +1009,9 @@ exit_usage(char *myname) {
        fprintf(stderr, "          mode = \"pathname\" Show only pathname related output\n");
        fprintf(stderr, "          mode = \"exec\"     Show only execs\n");
        fprintf(stderr, "          mode = \"cachehit\" In addition, show cachehits\n");
+       fprintf(stderr, "  -R    specifies a raw trace file to process\n");
+       fprintf(stderr, "  -S    if -R is specified, selects a start point in microseconds\n");
+       fprintf(stderr, "  -E    if -R is specified, selects an end point in microseconds\n");
        fprintf(stderr, "  pid   selects process(s) to sample\n");
        fprintf(stderr, "  cmd   selects process(s) matching command string to sample\n");
        fprintf(stderr, "\n%s will handle a maximum list of %d pids.\n\n", myname, MAX_PIDS);
@@ -937,8 +1036,6 @@ void init_tables(void)
         int type; 
         int code; 
 
-       for (i = 0; i < MAX_THREADS; i++)
-               th_state[i].my_index = i;
 
        for (i = 0; i < MAX_BSD_SYSCALL; i++) {
                bsd_syscalls[i].sc_name = NULL;
@@ -1061,11 +1158,29 @@ void init_tables(void)
                    case BSC_stat64_extended:
                      bsd_syscalls[code].sc_name = "stat_extended64";
                      break;
-                    
+
+                   case BSC_mount:
+                     bsd_syscalls[code].sc_name = "mount";
+                     bsd_syscalls[code].sc_format = FMT_MOUNT;
+                     break;
+
+                   case BSC_unmount:
+                     bsd_syscalls[code].sc_name = "unmount";
+                     bsd_syscalls[code].sc_format = FMT_UNMOUNT;
+                     break;
+
+                   case BSC_exit:
+                     bsd_syscalls[code].sc_name = "exit";
+                     break;
+
                    case BSC_execve:
                      bsd_syscalls[code].sc_name = "execve";
                      break;
                     
+                   case BSC_posix_spawn:
+                     bsd_syscalls[code].sc_name = "posix_spawn";
+                     break;
+                    
                    case BSC_load_shared_file:
                      bsd_syscalls[code].sc_name = "load_sf";
                      break;
@@ -1806,29 +1921,21 @@ main(argc, argv)
        char    *myname = "fs_usage";
        int     i;
        char    ch;
-       struct sigaction osa;
-       void getdivisor();
-       void argtopid();
-       void set_remove();
-       void set_pidcheck();
-       void set_pidexclude();
-       int quit();
 
        if (0 != reexec_to_match_kernel()) {
-         fprintf(stderr, "Could not re-execute: %d\n", errno);
-         exit(1);
+               fprintf(stderr, "Could not re-execute: %d\n", errno);
+               exit(1);
        }
        get_screenwidth();
 
-       /* get our name */
+       /*
+        * get our name
+        */
        if (argc > 0) {
-               if ((myname = rindex(argv[0], '/')) == 0) {
+               if ((myname = rindex(argv[0], '/')) == 0)
                        myname = argv[0];
-               }
-               else {
+               else
                        myname++;
-               }
        }
        
        while ((ch = getopt(argc, argv, "ewf:R:S:E:")) != EOF) {
@@ -1892,47 +1999,49 @@ main(argc, argv)
         * case below where exclude_pids is later set and the fs_usage PID
         * needs to make it into pids[] 
         */
-       if (exclude_pids || (!exclude_pids && argc == 0))
-         {
-           if (num_of_pids < (MAX_PIDS - 1))
-               pids[num_of_pids++] = getpid();
-         }
+       if (exclude_pids || (!exclude_pids && argc == 0)) {
+               if (num_of_pids < (MAX_PIDS - 1))
+                       pids[num_of_pids++] = getpid();
+       }
 
-       /* If we process any list of pids/cmds, then turn off the defaults */
+       /*
+        * If we process any list of pids/cmds, then turn off the defaults
+        */
        if (argc > 0)
-         exclude_default_pids = 0;
+               exclude_default_pids = 0;
 
        while (argc > 0 && num_of_pids < (MAX_PIDS - 1)) {
-         select_pid_mode++;
-         argtopid(argv[0]);
-         argc--;
-         argv++;
+               select_pid_mode++;
+               argtopid(argv[0]);
+               argc--;
+               argv++;
+       }
+       /*
+        * Exclude a set of default pids
+        */
+       if (exclude_default_pids) {
+               argtopid("Terminal");
+               argtopid("telnetd");
+               argtopid("telnet");
+               argtopid("sshd");
+               argtopid("rlogind");
+               argtopid("tcsh");
+               argtopid("csh");
+               argtopid("sh");
+               exclude_pids = 1;
        }
-
-       /* Exclude a set of default pids */
-       if (exclude_default_pids)
-         {
-           argtopid("Terminal");
-           argtopid("telnetd");
-           argtopid("telnet");
-           argtopid("sshd");
-           argtopid("rlogind");
-           argtopid("tcsh");
-           argtopid("csh");
-           argtopid("sh");
-           exclude_pids = 1;
-         }
-
 #if 0
-       for (i = 0; i < num_of_pids; i++)
-         {
-           if (exclude_pids)
-             fprintf(stderr, "exclude pid %d\n", pids[i]);
-           else
-             fprintf(stderr, "pid %d\n", pids[i]);
-         }
+       for (i = 0; i < num_of_pids; i++) {
+               if (exclude_pids)
+                       fprintf(stderr, "exclude pid %d\n", pids[i]);
+               else
+                       fprintf(stderr, "pid %d\n", pids[i]);
+       }
 #endif
        if (!RAW_flag) {
+               struct sigaction osa;
+               int     num_cpus;
+               size_t  len;
 
                /* set up signal handlers */
                signal(SIGINT, leave);
@@ -1943,13 +2052,14 @@ main(argc, argv)
                if (osa.sa_handler == SIG_DFL)
                        signal(SIGHUP, leave);
                signal(SIGTERM, leave);
-
-               /* grab the number of cpus */
-               size_t len;
+               /*
+                * grab the number of cpus
+                */
                mib[0] = CTL_HW;
                mib[1] = HW_NCPU;
                mib[2] = 0;
                len = sizeof(num_cpus);
+
                sysctl(mib, 2, &num_cpus, &len, NULL, 0);
                num_events = EVENT_BASE * num_cpus;
        }
@@ -1981,26 +2091,25 @@ main(argc, argv)
                        for (i = 0; i < num_of_pids; i++)
                                set_pidexclude(pids[i], 1);
                }
-
-               if (select_pid_mode && !one_good_pid)
-               {
+               if (select_pid_mode && !one_good_pid) {
                        /* 
-                          An attempt to restrict output to a given
-                          pid or command has failed. Exit gracefully
-                       */
+                        *  An attempt to restrict output to a given
+                        *  pid or command has failed. Exit gracefully
+                        */
                        set_remove();
                        exit_usage(myname);
                }
-
                set_enable(1);
+
                init_arguments_buffer();
        }
        getdivisor();
 
        init_tables();
 
-       /* main loop */
-
+       /*
+        * main loop
+        */
        while (1) {
                if (!RAW_flag)          
                        usleep(1000 * usleep_ms);
@@ -2011,12 +2120,12 @@ main(argc, argv)
        }
 }
 
+
 void
 find_proc_names()
 {
         size_t                 bufSize = 0;
-       struct kinfo_proc       *kp;
-       int quit();
+       struct kinfo_proc       *kp;
 
        mib[0] = CTL_KERN;
        mib[1] = KERN_PROC;
@@ -2026,8 +2135,8 @@ find_proc_names()
        if (sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0)
                quit("trace facility failure, KERN_PROC_ALL\n");
 
-       if((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
-           quit("can't allocate memory for proc buffer\n");
+       if ((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0)
+               quit("can't allocate memory for proc buffer\n");
        
        if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0)
                quit("trace facility failure, KERN_PROC_ALL\n");
@@ -2037,75 +2146,6 @@ find_proc_names()
 }
 
 
-void destroy_thread(struct th_info *ti) {
-
-       ti->child_thread = 0;
-       ti->thread = 0;
-       ti->pid = 0;
-
-       if (ti->my_index < cur_start)
-               cur_start = ti->my_index;
-
-        if (ti->my_index == cur_max) {
-               while (ti >= &th_state[0]) {
-                       if (ti->thread)
-                               break;
-                       ti--;
-               }
-               cur_max = ti->my_index;
-       }
-}
-
-
-struct th_info *find_empty(void) {
-       struct th_info *ti;
-
-       for (ti = &th_state[cur_start]; ti < &th_state[MAX_THREADS]; ti++, cur_start++) {
-               if (ti->thread == 0) {
-                       if (cur_start > cur_max)
-                               cur_max = cur_start;
-                       cur_start++;
-
-                       return (ti);
-               }
-       }
-       return ((struct th_info *)0);
-
-}
-
-
-struct th_info *find_thread(uintptr_t thread, int type) {
-        struct th_info *ti;
-
-       for (ti = &th_state[0]; ti <= &th_state[cur_max]; ti++) {
-               if (ti->thread == thread) {
-                       if (type == ti->type)
-                               return(ti);
-                       if (ti->in_filemgr) {
-                               if (type == -1)
-                                       return(ti);
-                               continue;
-                       }
-                       if (type == 0)
-                               return(ti);
-               }
-       }
-       return ((struct th_info *)0);
-}
-
-
-void
-mark_thread_waited(uintptr_t thread) {
-       struct th_info *ti;
-
-       for (ti = th_state; ti <= &th_state[cur_max]; ti++) {
-              if (ti->thread == thread) {
-                      ti->waited = 1;
-              }
-       }
-}
-
-
 void
 set_enable(int val) 
 {
@@ -2115,13 +2155,14 @@ set_enable(int val)
        mib[3] = val;
        mib[4] = 0;
        mib[5] = 0;                     /* no flags */
+
        if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
                quit("trace facility failure, KERN_KDENABLE\n");
 
        if (val)
-         trace_enabled = 1;
+               trace_enabled = 1;
        else
-         trace_enabled = 0;
+               trace_enabled = 0;
 }
 
 void
@@ -2133,6 +2174,7 @@ set_numbufs(int nbufs)
        mib[3] = nbufs;
        mib[4] = 0;
        mib[5] = 0;                     /* no flags */
+
        if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
                quit("trace facility failure, KERN_KDSETBUF\n");
 
@@ -2142,6 +2184,7 @@ set_numbufs(int nbufs)
        mib[3] = 0;
        mib[4] = 0;
        mib[5] = 0;                     /* no flags */
+
        if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
                quit("trace facility failure, KERN_KDSETUP\n");
 }
@@ -2165,16 +2208,14 @@ set_pidcheck(int pid, int on_off)
        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) {
                if (on_off == 1)
                        fprintf(stderr, "pid %d does not exist\n", pid);
-       }
-       else {
-         one_good_pid++;
-       }
+       } else
+               one_good_pid++;
 }
 
 /* 
  on_off == 0 turns off pid exclusion
  on_off == 1 turns on pid exclusion
-*/
* on_off == 0 turns off pid exclusion
* on_off == 1 turns on pid exclusion
+ */
 void
 set_pidexclude(int pid, int on_off) 
 {
@@ -2226,15 +2267,15 @@ set_remove()
        mib[3] = 0;
        mib[4] = 0;
        mib[5] = 0;             /* no flags */
-       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
-         {
-           set_remove_flag = 0;
-
-           if (errno == EBUSY)
-               quit("the trace facility is currently in use...\n          fs_usage, sc_usage, and latency use this feature.\n\n");
-           else
-               quit("trace facility failure, KERN_KDREMOVE\n");
-         }
+
+       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) {
+               set_remove_flag = 0;
+
+               if (errno == EBUSY)
+                       quit("the trace facility is currently in use...\n          fs_usage, sc_usage, and latency use this feature.\n\n");
+               else
+                       quit("trace facility failure, KERN_KDREMOVE\n");
+       }
 }
 
 void
@@ -2245,6 +2286,7 @@ set_init()
        kr.value1 = 0;
        kr.value2 = -1;
        needed = sizeof(kd_regtype);
+
        mib[0] = CTL_KERN;
        mib[1] = KERN_KDEBUG;
        mib[2] = KERN_KDSETREG;         
@@ -2273,21 +2315,19 @@ sample_sc()
        int i, count;
        size_t needed;
        uint32_t my_buffer_size = 0;
-       void read_command_map();
-       void create_map_entry();
 
-       if (!RAW_flag) {
-               /* Get kernel buffer information */
+       if (!RAW_flag)
                get_bufinfo(&bufinfo);
-       } else {
+       else
                my_buffer_size = num_events * sizeof(kd_buf);
-       }
+
        if (need_new_map) {
                read_command_map();
                need_new_map = 0;
        }
        if (!RAW_flag) {
                needed = bufinfo.nkdbufs * sizeof(kd_buf);
+
                mib[0] = CTL_KERN;
                mib[1] = KERN_KDEBUG;
                mib[2] = KERN_KDREADTR;         
@@ -2313,16 +2353,9 @@ sample_sc()
                if (bufinfo.flags & KDBG_WRAPPED) {
                        fprintf(stderr, "fs_usage: buffer overrun, events generated too quickly: %d\n", count);
 
-                       for (i = 0; i <= cur_max; i++) {
-                               th_state[i].thread = 0;
-                               th_state[i].pid = 0;
-                               th_state[i].pathptr = (uintptr_t *)NULL;
-                               th_state[i].pathname[0] = 0;
-                       }
-                       cur_max = 0;
-                       cur_start = 0;
+                       delete_all_events();
+
                        need_new_map = 1;
-                       map_is_the_same = 0;
                
                        set_enable(0);
                        set_enable(1);
@@ -2348,7 +2381,7 @@ sample_sc()
                long long l_usecs;
                int secs;
                long curr_time;
-               struct th_info *ti;
+               th_info_t       ti;
                 struct diskio  *dio;
 
 
@@ -2358,19 +2391,19 @@ sample_sc()
 
                now = kdbg_get_timestamp(&kd[i]);
 
-               if (i == 0 && !RAW_flag)
-               {
-                   curr_time = time((long *)0);
-                   /*
-                    * Compute bias seconds after each trace buffer read.
-                    * This helps resync timestamps with the system clock
-                    * in the event of a system sleep.
-                    */
-                   if (bias_secs == 0 || curr_time < last_time || curr_time > (last_time + 2)) {
-                           l_usecs = (long long)(now / divisor);
-                           secs = l_usecs / 1000000;
-                           bias_secs = curr_time - secs;
-                   }
+               if (i == 0 && !RAW_flag) {
+
+                       curr_time = time((long *)0);
+                       /*
+                        * Compute bias seconds after each trace buffer read.
+                        * This helps resync timestamps with the system clock
+                        * in the event of a system sleep.
+                        */
+                       if (bias_secs == 0 || curr_time < last_time || curr_time > (last_time + 2)) {
+                               l_usecs = (long long)(now / divisor);
+                               secs = l_usecs / 1000000;
+                               bias_secs = curr_time - secs;
+                       }
                }
                if (RAW_flag && bias_now == 0.0)
                        bias_now = now;
@@ -2386,60 +2419,89 @@ sample_sc()
                        }
                        continue;
                }
-
                switch (type) {
 
-               case TRACE_DATA_NEWTHREAD:
-                   
-                   if ((ti = find_empty()) == NULL)
-                           continue;
+               case P_CS_ReadChunk:
+               case P_CS_WriteChunk:
+               case P_CS_MetaRead:
+               case P_CS_MetaWrite:
+                   insert_diskio(type, kd[i].arg2, kd[i].arg1, kd[i].arg3, kd[i].arg4, thread, (double)now);
+                   continue;
+
+               case P_CS_Originated_Read:
+               case P_CS_Originated_Write:
+                   insert_diskio(type, kd[i].arg2, CS_DEV, kd[i].arg3, kd[i].arg4, thread, (double)now);
+                   continue;
+
+               case P_CS_ReadChunkDone:
+               case P_CS_WriteChunkDone:
+               case P_CS_Originated_ReadDone:
+               case P_CS_Originated_WriteDone:
+               case P_CS_MetaReadDone:
+               case P_CS_MetaWriteDone:
+                   if ((dio = complete_diskio(kd[i].arg2, kd[i].arg4, kd[i].arg3, thread, (double)now))) {
+                           print_diskio(dio);
+                           free_diskio(dio);
+                   }
+                   continue;
 
-                   ti->thread = thread;
-                   ti->child_thread = kd[i].arg1;
-                   ti->pid = kd[i].arg2;
+               case TRACE_DATA_NEWTHREAD:
+                   if (kd[i].arg1) {
+                           if ((ti = add_event(thread, TRACE_DATA_NEWTHREAD)) == NULL)
+                                   continue;
+                           ti->child_thread = kd[i].arg1;
+                           ti->pid = kd[i].arg2;
+                   }
                    continue;
 
                case TRACE_STRING_NEWTHREAD:
-                   if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
+                   if ((ti = find_event(thread, TRACE_DATA_NEWTHREAD)) == (struct th_info *)0)
                            continue;
-                   if (ti->child_thread == 0)
-                           continue;
-                   create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
 
-                   destroy_thread(ti);
+                   create_map_entry(ti->child_thread, ti->pid, (char *)&kd[i].arg1);
 
+                   delete_event(ti);
                    continue;
        
                case TRACE_DATA_EXEC:
-
-                   if ((ti = find_empty()) == NULL)
+                   if ((ti = add_event(thread, TRACE_DATA_EXEC)) == NULL)
                            continue;
 
-                   ti->thread = thread;
                    ti->pid = kd[i].arg1;
                    continue;       
 
                case TRACE_STRING_EXEC:
-                   if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
-                   {
-                       /* this is for backwards compatibility */
-                       create_map_entry(thread, 0, (char *)&kd[i].arg1);
-                   }
-                   else
-                   {
-                       create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
+                   if ((ti = find_event(thread, BSC_execve))) {
+                           if (ti->pathname[0])
+                                   exit_event("execve", thread, BSC_execve, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
 
-                       destroy_thread(ti);
+                   } else if ((ti = find_event(thread, BSC_posix_spawn))) {
+                           if (ti->pathname[0])
+                                   exit_event("posix_spawn", thread, BSC_posix_spawn, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
                    }
+                   if ((ti = find_event(thread, TRACE_DATA_EXEC)) == (struct th_info *)0)
+                           continue;
+
+                   create_map_entry(thread, ti->pid, (char *)&kd[i].arg1);
+
+                   delete_event(ti);
+                   continue;
+
+               case BSC_thread_terminate:
+                   delete_map_entry(thread);
                    continue;
 
                case BSC_exit:
-                   kill_thread_map(thread);
                    continue;
 
+               case proc_exit:
+                   kd[i].arg1 = kd[i].arg2 >> 8;
+                   type = BSC_exit;
+                   break;
+
                case BSC_mmap:
                    if (kd[i].arg4 & MAP_ANON)
-                       continue;
+                           continue;
                    break;
 
                case MACH_idle:
@@ -2449,11 +2511,16 @@ sample_sc()
                    continue;
 
                case VFS_LOOKUP:
-                   if ((ti = find_thread(thread, 0)) == (struct th_info *)0)
+                   if ((ti = find_event(thread, 0)) == (struct th_info *)0)
                            continue;
 
-                   if (ti->pathptr == NULL) {
-                           sargptr = ti->pathname;
+                   if (debugid & DBG_FUNC_START) {
+                           if (ti->pathname2[0])
+                                   continue;
+                           if (ti->pathname[0] == 0)
+                                   sargptr = ti->pathname;
+                           else
+                                   sargptr = ti->pathname2;
                            *sargptr++ = kd[i].arg2;
                            *sargptr++ = kd[i].arg3;
                            *sargptr++ = kd[i].arg4;
@@ -2461,6 +2528,7 @@ sample_sc()
                             * NULL terminate the 'string'
                             */
                            *sargptr = 0;
+
                            ti->pathptr = sargptr;
                    } else {
                            sargptr = ti->pathptr;
@@ -2468,21 +2536,17 @@ sample_sc()
                            /* 
                             * We don't want to overrun our pathname buffer if the
                             * kernel sends us more VFS_LOOKUP entries than we can
-                            *  handle.
-                            */
-                               if ((uintptr_t)sargptr >= (uintptr_t)&ti->pathname[NUMPARMS]) {
-                                       continue;
-                           }
-
-                            /*
-                            * We need to detect consecutive vfslookup entries.
-                            * So, if we get here and find a START entry,
-                            * fake the pathptr so we can bypass all further
-                            * vfslookup entries.
+                            * handle and we only handle 2 pathname lookups for
+                            * a given system call
                             */
-                           if (debugid & DBG_FUNC_START) {
-                               ti->pathptr = &ti->pathname[NUMPARMS];
-                               continue;
+                           if (sargptr == 0)
+                                   continue;
+                           if (ti->pathname2[0]) {
+                                   if ((uintptr_t)sargptr >= (uintptr_t)&ti->pathname2[NUMPARMS])
+                                           continue;
+                           } else {
+                                   if ((uintptr_t)sargptr >= (uintptr_t)&ti->pathname[NUMPARMS])
+                                           continue;
                            }
                            *sargptr++ = kd[i].arg1;
                            *sargptr++ = kd[i].arg2;
@@ -2492,7 +2556,14 @@ sample_sc()
                             * NULL terminate the 'string'
                             */
                            *sargptr = 0;
-                           ti->pathptr = sargptr;
+
+                           if (debugid & DBG_FUNC_END) {
+                                   if (ti->pathname2[0])
+                                           ti->pathptr = 0;
+                                   else
+                                           ti->pathptr = ti->pathname2;
+                           } else
+                                   ti->pathptr = sargptr;
                    }
                    continue;
                }
@@ -2512,237 +2583,210 @@ sample_sc()
                        } else
                                p = NULL;
 
-                       enter_syscall(thread, type, &kd[i], p, (double)now);
+                       enter_event(thread, type, &kd[i], p, (double)now);
                        continue;
                }
 
                switch (type) {
 
-                   case SPEC_ioctl:
-                     if (kd[i].arg2 == DKIOCSYNCHRONIZECACHE)
-                           exit_syscall("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_SPEC_IOCTL, (double)now);
-                     else {
-                             if ((ti = find_thread(thread, type))) {
-                                     destroy_thread(ti);
-                             }
-                     }
-                     continue;
-
-                   case MACH_pageout:
-                     if (kd[i].arg2) 
-                             exit_syscall("PAGE_OUT_ANON", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
-                     else
-                             exit_syscall("PAGE_OUT_FILE", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
-                     continue;
-
-                   case MACH_vmfault:
-                     if (kd[i].arg4 == DBG_PAGEIN_FAULT)
-                             exit_syscall("PAGE_IN", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
-                     else if (kd[i].arg4 == DBG_PAGEINV_FAULT)
-                             exit_syscall("PAGE_IN_FILE", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
-                     else if (kd[i].arg4 == DBG_PAGEIND_FAULT)
-                             exit_syscall("PAGE_IN_ANON", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
-                     else if (kd[i].arg4 == DBG_CACHE_HIT_FAULT)
-                             exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_CACHEHIT, (double)now);
-                     else {
-                             if ((ti = find_thread(thread, type))) {
-                                     destroy_thread(ti);
-                             }
-                     }
-                     continue;
-
-                   case MSC_map_fd:
-                     exit_syscall("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_FD, (double)now);
-                     continue;
+               case Throttled:
+                    exit_event("  THROTTLED", thread, type, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
+                    continue;
+
+               case P_CS_SYNC_DISK:
+                    exit_event("  SyncCacheCS", thread, type, kd[i].arg1, 0, 0, 0, FMT_SYNC_DISK_CS, (double)now);
+                    continue;
+
+               case SPEC_ioctl:
+                    if (kd[i].arg2 == DKIOCSYNCHRONIZECACHE)
+                            exit_event("IOCTL", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_SPEC_IOCTL, (double)now);
+                    else {
+                            if ((ti = find_event(thread, type)))
+                                    delete_event(ti);
+                    }
+                    continue;
+
+               case MACH_pageout:
+                    if (kd[i].arg2) 
+                            exit_event("PAGE_OUT_ANON", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
+                    else
+                            exit_event("PAGE_OUT_FILE", thread, type, 0, kd[i].arg1, 0, 0, FMT_PGOUT, (double)now);
+                    continue;
+
+               case MACH_vmfault:
+                    if (kd[i].arg4 == DBG_PAGEIN_FAULT)
+                            exit_event("PAGE_IN", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+                    else if (kd[i].arg4 == DBG_PAGEINV_FAULT)
+                            exit_event("PAGE_IN_FILE", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+                    else if (kd[i].arg4 == DBG_PAGEIND_FAULT)
+                            exit_event("PAGE_IN_ANON", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_PGIN, (double)now);
+                    else if (kd[i].arg4 == DBG_CACHE_HIT_FAULT)
+                            exit_event("CACHE_HIT", thread, type, 0, kd[i].arg1, kd[i].arg2, 0, FMT_CACHEHIT, (double)now);
+                    else {
+                            if ((ti = find_event(thread, type)))
+                                    delete_event(ti);
+                    }
+                    continue;
+
+               case MSC_map_fd:
+                    exit_event("map_fd", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, FMT_FD, (double)now);
+                    continue;
                      
-                   case BSC_mmap_extended:
-                   case BSC_mmap_extended2:
-                   case BSC_msync_extended:
-                   case BSC_pread_extended:
-                   case BSC_pwrite_extended:
-                     extend_syscall(thread, type, &kd[i]);
-                     continue;
+               case BSC_mmap_extended:
+               case BSC_mmap_extended2:
+               case BSC_msync_extended:
+               case BSC_pread_extended:
+               case BSC_pwrite_extended:
+                    extend_syscall(thread, type, &kd[i]);
+                    continue;
                }
 
                if ((type & CSC_MASK) == BSC_BASE) {
 
-                       index = BSC_INDEX(type);
-
-                       if (index >= MAX_BSD_SYSCALL)
-                               continue;
-
-                       if (bsd_syscalls[index].sc_name == NULL)
+                       if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
                                continue;
 
-                       if (type == BSC_execve)
-                               execs_in_progress--;
-
-                       exit_syscall(bsd_syscalls[index].sc_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
-                                    bsd_syscalls[index].sc_format, (double)now);
-
-                       continue;
-               }
+                       if (bsd_syscalls[index].sc_name) {
+                               exit_event(bsd_syscalls[index].sc_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
+                                          bsd_syscalls[index].sc_format, (double)now);
 
-               if ((type & CLASS_MASK) == FILEMGR_BASE) {
+                               if (type == BSC_exit)
+                                       delete_map_entry(thread);
+                       }
+               } else if ((type & CLASS_MASK) == FILEMGR_BASE) {
                
-                       index = filemgr_index(type);
-
-                       if (index >= MAX_FILEMGR)
-                               continue;
-
-                       if (filemgr_calls[index].fm_name == NULL)
+                       if ((index = filemgr_index(type)) >= MAX_FILEMGR)
                                continue;
 
-                       exit_syscall(filemgr_calls[index].fm_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
-                                    FMT_DEFAULT, (double)now);
+                       if (filemgr_calls[index].fm_name) {
+                               exit_event(filemgr_calls[index].fm_name, thread, type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4,
+                                          FMT_DEFAULT, (double)now);
+                       }
                }
        }
        fflush(0);
 }
 
 
-
-
 void
-enter_syscall_now(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
+enter_event_now(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
 {
-       struct th_info *ti;
-       int    secs;
-       int    usecs;
-       long long l_usecs;
-       long curr_time;
-       kd_threadmap *map;
-       kd_threadmap *find_thread_map();
-       int clen = 0;
-       int tsclen = 0;
-       int nmclen = 0;
-       int argsclen = 0;
-       char buf[MAXWIDTH];
-
-       if (execs_in_progress) {
-              if ((ti = find_thread(thread, BSC_execve))) {
-                      if (ti->pathptr) {
-                              exit_syscall("execve", thread, BSC_execve, 0, 0, 0, 0, FMT_DEFAULT, (double)now);
-                              execs_in_progress--;
-                      }
-              }
-       }
-       if ((ti = find_empty()) == NULL)
-              return;
-                   
-       if ((type & CLASS_MASK) == FILEMGR_BASE &&
-          (!RAW_flag || (now >= start_time && now <= end_time))) {
-
-              filemgr_in_progress++;
-              ti->in_filemgr = 1;
-
-              if (RAW_flag) {
-                      l_usecs = (long long)((now - bias_now) / divisor);
-                      l_usecs += ((long long)8 * (long long)3600 * (long long)1000000);
-              } else
-                      l_usecs = (long long)(now / divisor);
-              secs = l_usecs / 1000000;
-              curr_time = bias_secs + secs;
-                  
-              sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
-              tsclen = strlen(buf);
-
-              if (columns > MAXCOLS || wideflag) {
-                      usecs = l_usecs - (long long)((long long)secs * 1000000);
-                      sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000);
-                      tsclen = strlen(buf);
-              }
+       th_info_t       ti;
+       threadmap_t     tme;
+       int secs;
+       int usecs;
+       long long l_usecs;
+       long curr_time;
+       int clen = 0;
+       int tsclen = 0;
+       int nmclen = 0;
+       int argsclen = 0;
+       char buf[MAXWIDTH];
 
-              /*
-               * Print timestamp column
-               */
-              printf("%s", buf);
+       if ((ti = add_event(thread, type)) == NULL)
+               return;
 
-              map = find_thread_map(thread);
-              if (map) {
-                      sprintf(buf, "  %-25.25s ", name);
-                      nmclen = strlen(buf);
-                      printf("%s", buf);
+       ti->stime  = now;
+       ti->arg1   = kd->arg1;
+       ti->arg2   = kd->arg2;
+       ti->arg3   = kd->arg3;
+       ti->arg4   = kd->arg4;
 
-                      sprintf(buf, "(%d, 0x%lx, 0x%lx, 0x%lx)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
-                      argsclen = strlen(buf);
-                      
-                      /*
-                       * Calculate white space out to command
-                       */
-                      if (columns > MAXCOLS || wideflag) {
-                              clen = columns - (tsclen + nmclen + argsclen + 20);
-                      } else
-                              clen = columns - (tsclen + nmclen + argsclen + 12);
-
-                      if (clen > 0) {
-                              printf("%s", buf);   /* print the kdargs */
-                              memset(buf, ' ', clen);
-                              buf[clen] = '\0';
-                              printf("%s", buf);
-                      }
-                      else if ((argsclen + clen) > 0) {
-                              /*
-                               * no room so wipe out the kdargs
-                               */
-                              memset(buf, ' ', (argsclen + clen));
-                              buf[argsclen + clen] = '\0';
-                              printf("%s", buf);
-                      }
-                      if (columns > MAXCOLS || wideflag)
-                              printf("%-20.20s\n", map->command); 
-                      else
-                              printf("%-12.12s\n", map->command); 
-              } else
-                      printf("  %-24.24s (%5d, %#lx, 0x%lx, 0x%lx)\n",         name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
-       }
-       ti->thread = thread;
-       ti->waited = 0;
-       ti->type   = type;
-       ti->stime  = now;
-       ti->arg1   = kd->arg1;
-       ti->arg2   = kd->arg2;
-       ti->arg3   = kd->arg3;
-       ti->arg4   = kd->arg4;
-       ti->pathptr = (uintptr_t *)NULL;
-       ti->pathname[0] = 0;
-}
+       if ((type & CLASS_MASK) == FILEMGR_BASE &&
+           (!RAW_flag || (now >= start_time && now <= end_time))) {
 
+               filemgr_in_progress++;
+               ti->in_filemgr = 1;
 
-void
-enter_syscall(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
-{
-       int index;
+               if (RAW_flag) {
+                       l_usecs = (long long)((now - bias_now) / divisor);
+                       l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
+               } else
+                       l_usecs = (long long)(now / divisor);
+               secs = l_usecs / 1000000;
+               curr_time = bias_secs + secs;
+                  
+               sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
+               tsclen = strlen(buf);
 
-       if (type == MACH_pageout || type == MACH_vmfault || type == MSC_map_fd || type == SPEC_ioctl) {
-              enter_syscall_now(thread, type, kd, name, now);
-              return;
-       }
-       if ((type & CSC_MASK) == BSC_BASE) {
+               if (columns > MAXCOLS || wideflag) {
+                       usecs = l_usecs - (long long)((long long)secs * 1000000);
+                       sprintf(&buf[tsclen], ".%06ld", (long)usecs);
+                       tsclen = strlen(buf);
+               }
 
-              index = BSC_INDEX(type);
+               /*
+                * Print timestamp column
+                */
+               printf("%s", buf);
 
-              if (index >= MAX_BSD_SYSCALL)
-                      return;
+               tme = find_map_entry(thread);
+               if (tme) {
+                       sprintf(buf, "  %-25.25s ", name);
+                       nmclen = strlen(buf);
+                       printf("%s", buf);
 
-              if (type == BSC_execve)
-                      execs_in_progress++;
+                       sprintf(buf, "(%d, 0x%lx, 0x%lx, 0x%lx)", (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
+                       argsclen = strlen(buf);
+                      
+                       /*
+                        * Calculate white space out to command
+                        */
+                       if (columns > MAXCOLS || wideflag) {
+                               clen = columns - (tsclen + nmclen + argsclen + 20 + 11);
+                       } else
+                               clen = columns - (tsclen + nmclen + argsclen + 12);
 
-              if (bsd_syscalls[index].sc_name)
-                      enter_syscall_now(thread, type, kd, name, now);
+                       if (clen > 0) {
+                               printf("%s", buf);   /* print the kdargs */
+                               memset(buf, ' ', clen);
+                               buf[clen] = '\0';
+                               printf("%s", buf);
+                       }
+                       else if ((argsclen + clen) > 0) {
+                               /*
+                                * no room so wipe out the kdargs
+                                */
+                               memset(buf, ' ', (argsclen + clen));
+                               buf[argsclen + clen] = '\0';
+                               printf("%s", buf);
+                       }
+                       if (columns > MAXCOLS || wideflag)
+                               printf("%s.%d\n", tme->tm_command, (int)thread); 
+                       else
+                               printf("%-12.12s\n", tme->tm_command); 
+               } else
+                       printf("  %-24.24s (%5d, %#lx, 0x%lx, 0x%lx)\n",         name, (short)kd->arg1, kd->arg2, kd->arg3, kd->arg4);
+       }
+}
 
-              return;
-       }
-       if ((type & CLASS_MASK) == FILEMGR_BASE) {
 
-              index = filemgr_index(type);
+void
+enter_event(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
+{
+       int index;
+
+       if (type == MACH_pageout || type == MACH_vmfault || type == MSC_map_fd || type == SPEC_ioctl || type == Throttled || type == P_CS_SYNC_DISK) {
+               enter_event_now(thread, type, kd, name, now);
+               return;
+       }
+       if ((type & CSC_MASK) == BSC_BASE) {
 
-              if (index >= MAX_FILEMGR)
-                      return;
+               if ((index = BSC_INDEX(type)) >= MAX_BSD_SYSCALL)
+                       return;
+
+               if (bsd_syscalls[index].sc_name)
+                       enter_event_now(thread, type, kd, name, now);
+               return;
+       }
+       if ((type & CLASS_MASK) == FILEMGR_BASE) {
+
+               if ((index = filemgr_index(type)) >= MAX_FILEMGR)
+                       return;
               
-              if (filemgr_calls[index].fm_name)
-                      enter_syscall_now(thread, type, kd, name, now);
-       }
+               if (filemgr_calls[index].fm_name)
+                       enter_event_now(thread, type, kd, name, now);
+       }
 }
 
 /*
@@ -2756,66 +2800,66 @@ enter_syscall(uintptr_t thread, int type, kd_buf *kd, char *name, double now)
 void
 extend_syscall(uintptr_t thread, int type, kd_buf *kd)
 {
-       struct th_info *ti;
-
-       switch (type) {
-       case BSC_mmap_extended:
-          if ((ti = find_thread(thread, BSC_mmap)) == (struct th_info *)0)
-                  return;
-          ti->arg8   = ti->arg3;  /* save protection */
-          ti->arg1   = kd->arg1;  /* the fd */
-          ti->arg3   = kd->arg2;  /* bottom half address */
-          ti->arg5   = kd->arg3;  /* bottom half size */          
-          break;
-       case BSC_mmap_extended2:
-          if ((ti = find_thread(thread, BSC_mmap)) == (struct th_info *)0)
-                  return;
-          ti->arg2   = kd->arg1;  /* top half address */
-          ti->arg4   = kd->arg2;  /* top half size */
-          ti->arg6   = kd->arg3;  /* top half file offset */
-          ti->arg7   = kd->arg4;  /* bottom half file offset */
-          break;
-       case BSC_msync_extended:
-          if ((ti = find_thread(thread, BSC_msync)) == (struct th_info *)0) {
-              if ((ti = find_thread(thread, BSC_msync_nocancel)) == (struct th_info *)0)
-                  return;
-          }
-          ti->arg4   = kd->arg1;  /* top half address */
-          ti->arg5   = kd->arg2;  /* top half size */
-          break;
-       case BSC_pread_extended:
-          if ((ti = find_thread(thread, BSC_pread)) == (struct th_info *)0) {
-              if ((ti = find_thread(thread, BSC_pread_nocancel)) == (struct th_info *)0)
-                  return;
-          }
-          ti->arg1   = kd->arg1;  /* the fd */
-          ti->arg2   = kd->arg2;  /* nbytes */
-          ti->arg3   = kd->arg3;  /* top half offset */
-          ti->arg4   = kd->arg4;  /* bottom half offset */        
-          break;
-       case BSC_pwrite_extended:
-          if ((ti = find_thread(thread, BSC_pwrite)) == (struct th_info *)0) {
-              if ((ti = find_thread(thread, BSC_pwrite_nocancel)) == (struct th_info *)0)
-                  return;
-          }
-          ti->arg1   = kd->arg1;  /* the fd */
-          ti->arg2   = kd->arg2;  /* nbytes */
-          ti->arg3   = kd->arg3;  /* top half offset */
-          ti->arg4   = kd->arg4;  /* bottom half offset */
-          break;
-       default:
-          return;
+       th_info_t       ti;
+
+       switch (type) {
+       case BSC_mmap_extended:
+           if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
+                   return;
+           ti->arg8   = ti->arg3;  /* save protection */
+           ti->arg1   = kd->arg1;  /* the fd */
+           ti->arg3   = kd->arg2;  /* bottom half address */
+           ti->arg5   = kd->arg3;  /* bottom half size */         
+           break;
+       case BSC_mmap_extended2:
+           if ((ti = find_event(thread, BSC_mmap)) == (struct th_info *)0)
+                   return;
+           ti->arg2   = kd->arg1;  /* top half address */
+           ti->arg4   = kd->arg2;  /* top half size */
+           ti->arg6   = kd->arg3;  /* top half file offset */
+           ti->arg7   = kd->arg4;  /* bottom half file offset */
+           break;
+       case BSC_msync_extended:
+           if ((ti = find_event(thread, BSC_msync)) == (struct th_info *)0) {
+                   if ((ti = find_event(thread, BSC_msync_nocancel)) == (struct th_info *)0)
+                           return;
+           }
+           ti->arg4   = kd->arg1;  /* top half address */
+           ti->arg5   = kd->arg2;  /* top half size */
+           break;
+       case BSC_pread_extended:
+           if ((ti = find_event(thread, BSC_pread)) == (struct th_info *)0) {
+                   if ((ti = find_event(thread, BSC_pread_nocancel)) == (struct th_info *)0)
+                           return;
+           }
+           ti->arg1   = kd->arg1;  /* the fd */
+           ti->arg2   = kd->arg2;  /* nbytes */
+           ti->arg3   = kd->arg3;  /* top half offset */
+           ti->arg4   = kd->arg4;  /* bottom half offset */       
+           break;
+       case BSC_pwrite_extended:
+           if ((ti = find_event(thread, BSC_pwrite)) == (struct th_info *)0) {
+                   if ((ti = find_event(thread, BSC_pwrite_nocancel)) == (struct th_info *)0)
+                           return;
+           }
+           ti->arg1   = kd->arg1;  /* the fd */
+           ti->arg2   = kd->arg2;  /* nbytes */
+           ti->arg3   = kd->arg3;  /* top half offset */
+           ti->arg4   = kd->arg4;  /* bottom half offset */
+           break;
+       default:
+           return;
        }
 }
 
 
 void
-exit_syscall(char *sc_name, uintptr_t thread, int type, int arg1, int arg2, int arg3, int arg4,
-                           int format, double now)
+exit_event(char *sc_name, uintptr_t thread, int type, int arg1, int arg2, int arg3, int arg4,
+          int format, double now)
 {
-        struct th_info *ti;
+        th_info_t      ti;
       
-       if ((ti = find_thread(thread, type)) == (struct th_info *)0)
+       if ((ti = find_event(thread, type)) == (struct th_info *)0)
                return;
 
        if (check_filter_mode(ti, type, arg1, arg2, sc_name))
@@ -2827,7 +2871,7 @@ exit_syscall(char *sc_name, uintptr_t thread, int type, int arg1, int arg2, int
                if (filemgr_in_progress > 0)
                        filemgr_in_progress--;
        }
-       destroy_thread(ti);
+       delete_event(ti);
 }
 
 
@@ -2891,8 +2935,6 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
        long long l_usecs;
        long curr_time;
        char *command_name;
-       kd_threadmap *map;
-       kd_threadmap *find_thread_map();
        int in_filemgr = 0;
        int len = 0;
        int clen = 0;
@@ -2905,21 +2947,21 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
        char *p1;
        char *p2;
        char buf[MAXWIDTH];
+       char cs_diskname[32];
        command_name = "";
-       int     need_msec_update = 0;
        static char timestamp[32];
        static int  last_timestamp = -1;
        static int  timestamp_len = 0;
-       static int  last_msec = 0;
-
 
        if (RAW_flag) {
                l_usecs = (long long)((now - bias_now) / divisor);
 
                if ((double)l_usecs < start_time || (double)l_usecs > end_time)
                        return;
-               l_usecs += ((long long)8 * (long long)3600 * (long long)1000000);
-       } else
+
+               l_usecs += (sample_TOD_secs * 1000000) + sample_TOD_usecs;
+       }
+       else
                l_usecs = (long long)(now / divisor);
        secs = l_usecs / 1000000;
        curr_time = bias_secs + secs;
@@ -2929,43 +2971,31 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
        if (dio)
                command_name = dio->issuing_command;
        else {
-               if (map_is_the_same && thread == last_thread)
-                       map = last_map;
-               else {
-                       if ((map = find_thread_map(thread))) {
-                               last_map = map;
-                               last_thread = thread;
-                               map_is_the_same = 1;
-                       }
-               }
-               if (map)
-                       command_name = map->command;
+               threadmap_t     tme;
+
+               if ((tme = find_map_entry(thread)))
+                       command_name = tme->tm_command;
        }
        if (last_timestamp != curr_time) {
                timestamp_len = sprintf(timestamp, "%-8.8s", &(ctime(&curr_time)[11]));
                last_timestamp = curr_time;
-               need_msec_update = 1;
        }
        if (columns > MAXCOLS || wideflag) {
-               int msec;
+               int usec;
 
                tlen = timestamp_len;
                nopadding = 0;
-               msec = (l_usecs - (long long)((long long)secs * 1000000)) / 1000;
+               usec = (l_usecs - (long long)((long long)secs * 1000000));
 
-               if (msec != last_msec || need_msec_update) {
-                       sprintf(&timestamp[tlen], ".%03ld", (long)msec);
-                       last_msec = msec;
-               }
-               tlen += 4;
+               sprintf(&timestamp[tlen], ".%06ld", (long)usec);
+               tlen += 7;
 
                timestamp[tlen] = '\0';
 
                if (filemgr_in_progress) {
                        if (class != FILEMGR_CLASS) {
-                               if (find_thread(thread, -1)) {
+                               if (find_event(thread, -1))
                                        in_filemgr = 1;
-                               }
                        }
                }
        } else
@@ -3065,6 +3095,24 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
                                clen += printf(" D=0x%8.8x  B=0x%-6x   /dev/%s", dio->blkno, dio->iosize, find_disk_name(dio->dev));
                        break;
 
+                     case FMT_DISKIO_CS:
+                       /*
+                        * physical disk I/O
+                        */
+                       if (dio->io_errno)
+                               clen += printf(" D=0x%8.8x  [%3d]", dio->blkno, dio->io_errno);
+                       else
+                               clen += printf(" D=0x%8.8x  B=0x%-6x   /dev/%s", dio->blkno, dio->iosize, generate_cs_disk_name(dio->dev, &cs_diskname[0]));
+                       break;
+
+                     case FMT_SYNC_DISK_CS:
+                       /*
+                        * physical disk sync cache
+                        */
+                       clen += printf("                            /dev/%s", generate_cs_disk_name(arg1, &cs_diskname[0]));
+
+                       break;
+
                      case FMT_MSYNC:
                      {
                        /*
@@ -3408,9 +3456,9 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
                        buf[mlen++] = '>';
                        buf[mlen] = '\0';
 
-                       if (mlen < 21) {
-                               memset(&buf[mlen], ' ', 21 - mlen);
-                               mlen = 21;
+                       if (mlen < 19) {
+                               memset(&buf[mlen], ' ', 19 - mlen);
+                               mlen = 19;
                        }
                        clen += printf("%s", buf);
 
@@ -3484,6 +3532,35 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
                        break;
                      }
 
+                     case FMT_MOUNT:
+                     {
+                             if (arg1)
+                                     clen += printf("      [%3d] <FLGS=0x%x> ", arg1, ti->arg3);
+                             else
+                                     clen += printf("     <FLGS=0x%x> ", ti->arg3);
+
+                             nopadding = 1;
+                             break;
+                     }
+
+                     case FMT_UNMOUNT:
+                     {
+                             char *mountflag;
+                             
+                             if (ti->arg2 & MNT_FORCE)
+                                     mountflag = "<FORCE>";
+                             else
+                                     mountflag = "";
+
+                             if (arg1)
+                                     clen += printf("      [%3d] %s  ", arg1, mountflag);
+                             else
+                                     clen += printf("     %s         ", mountflag);
+
+                             nopadding = 1;
+                             break;
+                     }
+
                      case FMT_OPEN:
                      {
                        /*
@@ -3691,7 +3768,7 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
         * Calculate space available to print pathname
         */
        if (columns > MAXCOLS || wideflag)
-               clen =  columns - (clen + 14 + 20);
+               clen =  columns - (clen + 14 + 20 + 11);
        else
                clen =  columns - (clen + 14 + 12);
 
@@ -3700,9 +3777,18 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
 
        if (framework_name)
                len = sprintf(&buf[0], " %s %s ", framework_type, framework_name);
-       else if (*pathname != '\0')
+       else if (*pathname != '\0') {
                len = sprintf(&buf[0], " %s ", pathname);
-       else
+
+               if (format == FMT_MOUNT && ti->pathname2[0]) {
+                       int     len2;
+
+                       memset(&buf[len], ' ', 2);
+
+                       len2 = sprintf(&buf[len+2], " %s ", (char *)ti->pathname2);
+                       len = len + 2 + len2;
+               }
+       } else
                len = 0;
 
        if (clen > len) {
@@ -3751,349 +3837,412 @@ format_print(struct th_info *ti, char *sc_name, uintptr_t thread, int type, int
                p2 = "  ";
 
        if (columns > MAXCOLS || wideflag)
-               printf("%s%s %3ld.%06ld%s %-20.20s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name);
+               printf("%s%s %3ld.%06ld%s %s.%d\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name, (int)thread);
        else
                printf("%s%s %3ld.%06ld%s %-12.12s\n", p1, pathname, (unsigned long)secs, (unsigned long)usecs, p2, command_name);
 }
 
-int
-quit(s)
-char *s;
-{
-        if (trace_enabled)
-              set_enable(0);
 
-       /* 
-        * This flag is turned off when calling
-        * quit() due to a set_remove() failure.
-        */
-       if (set_remove_flag)
-               set_remove();
+void
+delete_event(th_info_t ti_to_delete) {
+       th_info_t       ti;
+       th_info_t       ti_prev;
+       int             hashid;
+
+       hashid = ti_to_delete->thread & HASH_MASK;
+
+       if ((ti = th_info_hash[hashid])) {
+               if (ti == ti_to_delete)
+                       th_info_hash[hashid] = ti->next;
+                else {
+                        ti_prev = ti;
+
+                       for (ti = ti->next; ti; ti = ti->next) {
+                                if (ti == ti_to_delete) {
+                                       ti_prev->next = ti->next;
+                                        break;
+                                }
+                                ti_prev = ti;
+                       }
+                }
+                if (ti) {
+                        ti->next = th_info_freelist;
+                        th_info_freelist = ti;
+                }
+        }
+}
 
-        fprintf(stderr, "fs_usage: ");
-       if (s)
-               fprintf(stderr, "%s", s);
+th_info_t
+add_event(uintptr_t thread, int type) {
+       th_info_t       ti;
+       int             hashid;
 
-       exit(1);
+       if ((ti = th_info_freelist))
+               th_info_freelist = ti->next;
+       else
+               ti = (th_info_t)malloc(sizeof(struct th_info));
+
+       hashid = thread & HASH_MASK;
+
+       ti->next = th_info_hash[hashid];
+       th_info_hash[hashid] = ti;
+
+       ti->thread = thread;
+       ti->type = type;
+
+       ti->waited = 0;
+       ti->in_filemgr = 0;
+       ti->pathptr = ti->pathname;
+       ti->pathname[0] = 0;
+       ti->pathname2[0] = 0;
+
+       return (ti);
 }
 
+th_info_t
+find_event(uintptr_t thread, int type) {
+        th_info_t      ti;
+       int             hashid;
 
-void getdivisor()
-{
-    struct mach_timebase_info mti;
+       hashid = thread & HASH_MASK;
 
-    mach_timebase_info(&mti);
+       for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
+               if (ti->thread == thread) {
+                       if (type == ti->type)
+                               return (ti);
+                       if (ti->in_filemgr) {
+                               if (type == -1)
+                                       return (ti);
+                               continue;
+                       }
+                       if (type == 0)
+                               return (ti);
+               }
+       }
+       return ((th_info_t) 0);
+}
 
-    divisor = ((double)mti.denom / (double)mti.numer) * 1000;
+void
+delete_all_events() {
+        th_info_t      ti = 0;
+        th_info_t      ti_next = 0;
+        int             i;
+
+        for (i = 0; i < HASH_SIZE; i++) {
+
+                for (ti = th_info_hash[i]; ti; ti = ti_next) {
+                        ti_next = ti->next;
+                        ti->next = th_info_freelist;
+                        th_info_freelist = ti;
+                }
+                th_info_hash[i] = 0;
+        }
+}
+
+
+void
+mark_thread_waited(uintptr_t thread) {
+        th_info_t      ti;
+       int             hashid;
+
+       hashid = thread & HASH_MASK;
+
+       for (ti = th_info_hash[hashid]; ti; ti = ti->next) {
+               if (ti->thread == thread)
+                       ti->waited = 1;
+       }
 }
 
 
 void read_command_map()
 {
-    size_t size;
-    int i;
-    int prev_total_threads;
-    int mib[6];
-  
-    if (mapptr) {
-       free(mapptr);
-       mapptr = 0;
-    }
-
-    prev_total_threads = total_threads;
-
-    if (!RAW_flag) {
-
-           total_threads = bufinfo.nkdthreads;
-           size = bufinfo.nkdthreads * sizeof(kd_threadmap);
-
-           if (size)
-           {
-                   if ((mapptr = (kd_threadmap *) malloc(size)))
-                   {
-                           bzero (mapptr, size);
-                           /* Now read the threadmap */
-                           mib[0] = CTL_KERN;
-                           mib[1] = KERN_KDEBUG;
-                           mib[2] = KERN_KDTHRMAP;
-                           mib[3] = 0;
-                           mib[4] = 0;
-                           mib[5] = 0;         /* no flags */
-                           if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
-                           {
-                                   /* This is not fatal -- just means I cant map command strings */
-                                   free(mapptr);
-                                   mapptr = 0;
-                           }
-                   }
-           }
-    } else {
-           uint32_t count_of_names;
+       size_t  size;
+       int     i;
+       int total_threads = 0;
+       kd_threadmap *mapptr = 0;
 
-           RAW_fd = open(RAW_file, O_RDONLY);
+       delete_all_map_entries();
 
-           if (RAW_fd < 0) {
-                   perror("Can't open RAW file");
-                   exit(1);
-           }
-           if (read(RAW_fd, &count_of_names, sizeof(uint32_t)) != sizeof(uint32_t)) {
-                   perror("read of RAW file failed");
-                   exit(2);
-           }
-           total_threads = count_of_names;
-           size = count_of_names * sizeof(kd_threadmap);
-           
-           if (size)
-           {
-                   if ((mapptr = (kd_threadmap *) malloc(size)))
-                   {
-                           bzero (mapptr, size);
+       if (!RAW_flag) {
 
-                           if (read(RAW_fd, mapptr, size) != size) {
+               total_threads = bufinfo.nkdthreads;
+               size = bufinfo.nkdthreads * sizeof(kd_threadmap);
+
+               if (size) {
+                       if ((mapptr = (kd_threadmap *) malloc(size))) {
+                               int mib[6];
+
+                               bzero (mapptr, size);
+                               /*
+                                * Now read the threadmap
+                                */
+                               mib[0] = CTL_KERN;
+                               mib[1] = KERN_KDEBUG;
+                               mib[2] = KERN_KDTHRMAP;
+                               mib[3] = 0;
+                               mib[4] = 0;
+                               mib[5] = 0;             /* no flags */
+
+                               if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0) {
+                                       /*
+                                        * This is not fatal -- just means I cant map command strings
+                                        */
+                                       free(mapptr);
+                                       return;
+                               }
+                       }
+               }
+       } else {
+               RAW_header      header;
+               off_t   offset;
 
-                                   free(mapptr);
-                                   mapptr = 0;
-                           }
-                   }
-           }
-    }
-    if (mapptr && (filter_mode & (NETWORK_FILTER | FILESYS_FILTER)))
-    {
-       if (fdmapptr)
-       {
-           /* We accept the fact that we lose file descriptor state if the
-              kd_buffer wraps */
-           for (i = 0; i < prev_total_threads; i++)
-           {
-               if (fdmapptr[i].fd_setptr)
-                   free (fdmapptr[i].fd_setptr);
-           }
-           free(fdmapptr);
-           fdmapptr = 0;
-       }
+               RAW_fd = open(RAW_file, O_RDONLY);
 
-       size = total_threads * sizeof(fd_threadmap);
-       if ((fdmapptr = (fd_threadmap *) malloc(size)))
-       {
-           bzero (fdmapptr, size);
-           /* reinitialize file descriptor state map */
-           for (i = 0; i < total_threads; i++)
-           {
-               fdmapptr[i].fd_thread = mapptr[i].thread;
-               fdmapptr[i].fd_valid = mapptr[i].valid;
-               fdmapptr[i].fd_setsize = 0;
-               fdmapptr[i].fd_setptr = 0;
-           }
+               if (RAW_fd < 0) {
+                       perror("Can't open RAW file");
+                       exit(1);
+               }
+               if (read(RAW_fd, &header, sizeof(RAW_header)) != sizeof(RAW_header)) {
+                       perror("read failed");
+                       exit(2);
+               }
+               if (header.version_no != RAW_VERSION1) {
+                       header.version_no = RAW_VERSION0;
+                       header.TOD_secs = time((long *)0);
+                       header.TOD_usecs = 0;
+
+                       lseek(RAW_fd, (off_t)0, SEEK_SET);
+
+                       if (read(RAW_fd, &header.thread_count, sizeof(int)) != sizeof(int)) {
+                               perror("read failed");
+                               exit(2);
+                       }
+               }
+               sample_TOD_secs = header.TOD_secs;
+               sample_TOD_usecs = header.TOD_usecs;
+
+               total_threads = header.thread_count;
+               size = total_threads * sizeof(kd_threadmap);
+
+               if (size) {
+                       if ((mapptr = (kd_threadmap *) malloc(size))) {
+                               bzero (mapptr, size);
+
+                               if (read(RAW_fd, mapptr, size) != size) {
+                                       free(mapptr);
+                                       return;
+                               }
+                       }
+               }
+               if (header.version_no != RAW_VERSION0) {
+                       offset = lseek(RAW_fd, (off_t)0, SEEK_CUR);
+                       offset = (offset + (4095)) & ~4095;
+
+                       lseek(RAW_fd, offset, SEEK_SET);
+               }
        }
-    }
+       for (i = 0; i < total_threads; i++)
+               create_map_entry(mapptr[i].thread, mapptr[i].valid, &mapptr[i].command[0]);
 
-    /* Resolve any LaunchCFMApp command names */
-    if (mapptr && arguments)
-    {
-       for (i=0; i < total_threads; i++)
-       {
-           int pid;
+        free(mapptr);
+}
 
-           pid = mapptr[i].valid;
-           
-           if (pid == 0 || pid == 1)
-               continue;
-           else if (!strncmp(mapptr[i].command,"LaunchCFMA", 10))
-           {
-               (void)get_real_command_name(pid, mapptr[i].command, sizeof(mapptr[i].command));
-           }
+
+void delete_all_map_entries()
+{
+       threadmap_t     tme = 0;
+        threadmap_t     tme_next = 0;
+       int             i;
+
+       for (i = 0; i < HASH_SIZE; i++) {
+
+               for (tme = threadmap_hash[i]; tme; tme = tme_next) {
+                        if (tme->tm_setptr)
+                               free(tme->tm_setptr);
+                       tme_next = tme->tm_next;
+                        tme->tm_next = threadmap_freelist;
+                       threadmap_freelist = tme;
+                }
+                threadmap_hash[i] = 0;
        }
-    }
 }
 
 
 void create_map_entry(uintptr_t thread, int pid, char *command)
 {
-    int i, n;
-    kd_threadmap *map;
-    fd_threadmap *fdmap = 0;
-
-    if (!mapptr)
-        return;
-
-    for (i = 0, map = 0; !map && i < total_threads; i++)
-    {
-        if (mapptr[i].thread == thread )
-       {
-           map = &mapptr[i];   /* Reuse this entry, the thread has been
-                                * reassigned */
-           if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr)
-           {
-               fdmap = &fdmapptr[i];
-               if (fdmap->fd_thread != thread)    /* This shouldn't happen */
-                   fdmap = (fd_threadmap *)0;
-           }
-       }
-    }
-
-    if (!map)   /* look for invalid entries that I can reuse*/
-    {
-        for (i = 0, map = 0; !map && i < total_threads; i++)
-       {
-           if (mapptr[i].valid == 0 )  
-               map = &mapptr[i];   /* Reuse this invalid entry */
-           if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr)
-           {
-               fdmap = &fdmapptr[i];
-           }
-       }
-    }
-  
-    if (!map)
-    {
-        /*
-        * If reach here, then this is a new thread and 
-        * there are no invalid entries to reuse
-        * Double the size of the thread map table.
-        */
-        n = total_threads * 2;
-       mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap));
-       bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap));
-       map = &mapptr[total_threads];
-
-       if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)) && fdmapptr)
-       {
-           fdmapptr = (fd_threadmap *)realloc(fdmapptr, n * sizeof(fd_threadmap));
-           bzero(&fdmapptr[total_threads], total_threads*sizeof(fd_threadmap));
-           fdmap = &fdmapptr[total_threads];       
-       }
-       
-       total_threads = n;
-    }
-
-    map->valid = 1;
-    map->thread = thread;
-    /*
-     * The trace entry that returns the command name will hold
-     * at most, MAXCOMLEN chars, and in that case, is not
-     * guaranteed to be null terminated.
-     */
-    (void)strncpy (map->command, command, MAXCOMLEN);
-    map->command[MAXCOMLEN] = '\0';
-
-    if (fdmap)
-    {
-       fdmap->fd_valid = 1;
-       fdmap->fd_thread = thread;
-       if (fdmap->fd_setptr)
-       {
-           free(fdmap->fd_setptr);
-           fdmap->fd_setptr = (unsigned long *)0;
+        threadmap_t     tme;
+        int             hashid;
+
+        if ((tme = threadmap_freelist))
+                threadmap_freelist = tme->tm_next;
+        else
+                tme = (threadmap_t)malloc(sizeof(struct threadmap));
+
+        tme->tm_thread  = thread;
+       tme->tm_setsize = 0;
+       tme->tm_setptr  = 0;
+
+        (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+        tme->tm_command[MAXCOMLEN] = '\0';
+
+        hashid = thread & HASH_MASK;
+
+        tme->tm_next = threadmap_hash[hashid];
+        threadmap_hash[hashid] = tme;
+
+       if (pid != 0 && pid != 1) {
+               if (!strncmp(command, "LaunchCFMA", 10))
+                       (void)get_real_command_name(pid, tme->tm_command, MAXCOMLEN);
        }
-       fdmap->fd_setsize = 0;
-    }
+}
+
+
+threadmap_t
+find_map_entry(uintptr_t thread)
+{
+        threadmap_t     tme;
+        int     hashid;
 
-    if (pid == 0 || pid == 1)
-       return;
-    else if (!strncmp(map->command, "LaunchCFMA", 10))
-       (void)get_real_command_name(pid, map->command, sizeof(map->command));
+       hashid = thread & HASH_MASK;
+
+        for (tme = threadmap_hash[hashid]; tme; tme = tme->tm_next) {
+               if (tme->tm_thread == thread)
+                       return (tme);
+       }
+        return (0);
 }
 
 
-kd_threadmap *find_thread_map(uintptr_t thread)
+void
+delete_map_entry(uintptr_t thread)
 {
-    int i;
-    kd_threadmap *map;
-
-    if (!mapptr)
-        return((kd_threadmap *)0);
-
-    for (i = 0; i < total_threads; i++)
-    {
-        map = &mapptr[i];
-       if (map->valid && (map->thread == thread))
-       {
-           return(map);
+        threadmap_t     tme = 0;
+        threadmap_t     tme_prev;
+        int             hashid;
+
+        hashid = thread & HASH_MASK;
+
+        if ((tme = threadmap_hash[hashid])) {
+                if (tme->tm_thread == thread)
+                       threadmap_hash[hashid] = tme->tm_next;
+                else {
+                        tme_prev = tme;
+
+                       for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+                                if (tme->tm_thread == thread) {
+                                        tme_prev->tm_next = tme->tm_next;
+                                        break;
+                               }
+                                tme_prev = tme;
+                       }
+               }
+                if (tme) {
+                       if (tme->tm_setptr)
+                               free(tme->tm_setptr);
+
+                        tme->tm_next = threadmap_freelist;
+                       threadmap_freelist = tme;
+               }
        }
-    }
-    return ((kd_threadmap *)0);
 }
 
-fd_threadmap *find_fd_thread_map(uintptr_t thread)
+
+void
+fs_usage_fd_set(uintptr_t thread, unsigned int fd)
 {
-    int i;
-    fd_threadmap *fdmap = 0;
-
-    if (!fdmapptr)
-        return((fd_threadmap *)0);
-
-    for (i = 0; i < total_threads; i++)
-    {
-        fdmap = &fdmapptr[i];
-       if (fdmap->fd_valid && (fdmap->fd_thread == thread))
-       {
-           return(fdmap);
+       threadmap_t     tme;
+
+       if ((tme = find_map_entry(thread)) == 0)
+               return;
+       /*
+        * If the map is not allocated, then now is the time
+        */
+       if (tme->tm_setptr == (unsigned long *)0) {
+               if ((tme->tm_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE))) == 0)
+                       return;
+
+               tme->tm_setsize = FS_USAGE_FD_SETSIZE;
+               bzero(tme->tm_setptr, (FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
        }
-    }
-    return ((fd_threadmap *)0);
+       /*
+        * If the map is not big enough, then reallocate it
+        */
+       while (tme->tm_setsize <= fd) {
+               int     n;
+
+               n = tme->tm_setsize * 2;
+               tme->tm_setptr = (unsigned long *)realloc(tme->tm_setptr, (FS_USAGE_NFDBYTES(n)));
+
+               bzero(&tme->tm_setptr[(tme->tm_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(tme->tm_setsize)));
+               tme->tm_setsize = n;
+       }
+       /*
+        * set the bit
+        */
+       tme->tm_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
 }
 
 
+/*
+ * Return values:
+ *  0 : File Descriptor bit is not set
+ *  1 : File Descriptor bit is set
+ */
+int
+fs_usage_fd_isset(uintptr_t thread, unsigned int fd)
+{
+       threadmap_t     tme;
+       int             ret = 0;
+
+       if ((tme = find_map_entry(thread))) {
+               if (tme->tm_setptr && fd < tme->tm_setsize)
+                       ret = tme->tm_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
+       }
+       return (ret);
+}
+    
+
 void
-kill_thread_map(uintptr_t thread)
+fs_usage_fd_clear(uintptr_t thread, unsigned int fd)
 {
-    kd_threadmap *map;
-    fd_threadmap *fdmap;
-
-    if (thread == last_thread)
-        map_is_the_same = 0;
-
-    if ((map = find_thread_map(thread))) {
-        map->valid = 0;
-       map->thread = 0;
-       map->command[0] = '\0';
-    }
-
-    if ((filter_mode & (NETWORK_FILTER | FILESYS_FILTER)))
-    {
-       if ((fdmap = find_fd_thread_map(thread)))
-       {
-           fdmap->fd_valid = 0;
-           fdmap->fd_thread = 0;
-           if (fdmap->fd_setptr)
-           {
-               free (fdmap->fd_setptr);
-               fdmap->fd_setptr = (unsigned long *)0;
-           }
-           fdmap->fd_setsize = 0;
-       }       
-    }
+       threadmap_t     tme;
+
+       if ((tme = find_map_entry(thread))) {
+               if (tme->tm_setptr && fd < tme->tm_setsize)
+                       tme->tm_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
+       }
 }
 
+
+
 void
-argtopid(str)
-        char *str;
+argtopid(char *str)
 {
         char *cp;
         int ret;
        int i;
 
         ret = (int)strtol(str, &cp, 10);
+
         if (cp == str || *cp) {
-         /* Assume this is a command string and find matching pids */
+               /*
+                * Assume this is a command string and find matching pids
+                */
                if (!kp_buffer)
                        find_proc_names();
 
-               for (i=0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
-                     if(kp_buffer[i].kp_proc.p_stat == 0)
-                         continue;
-                     else {
-                         if(!strncmp(str, kp_buffer[i].kp_proc.p_comm,
-                             sizeof(kp_buffer[i].kp_proc.p_comm) -1))
-                           pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
-                     }
+               for (i = 0; i < kp_nentries && num_of_pids < (MAX_PIDS - 1); i++) {
+                       if (kp_buffer[i].kp_proc.p_stat == 0)
+                               continue;
+                       else {
+                               if (!strncmp(str, kp_buffer[i].kp_proc.p_comm,
+                                            sizeof(kp_buffer[i].kp_proc.p_comm) -1))
+                                       pids[num_of_pids++] = kp_buffer[i].kp_proc.p_pid;
+                       }
                }
        }
        else if (num_of_pids < (MAX_PIDS - 1))
                pids[num_of_pids++] = ret;
-
-        return;
 }
 
 
@@ -4116,11 +4265,10 @@ lookup_name(uint64_t user_addr, char **type, char **name)
                        last  = numFrameworks;
 
                        for (i = numFrameworks / 2; start < last; i = start + ((last - start) / 2)) {
-                               if (user_addr > frameworkInfo[i].e_address) {
+                               if (user_addr > frameworkInfo[i].e_address)
                                        start = i+1;
-                               } else {
+                               else
                                        last = i;
-                               }
                        }
                        if (start < numFrameworks &&
                            user_addr >= frameworkInfo[start].b_address && user_addr < frameworkInfo[start].e_address) {
@@ -4137,28 +4285,30 @@ lookup_name(uint64_t user_addr, char **type, char **name)
  */
 static int compareFrameworkAddress(const void  *aa, const void *bb)
 {
-    LibraryInfo *a = (LibraryInfo *)aa;
-    LibraryInfo *b = (LibraryInfo *)bb;
+       LibraryInfo *a = (LibraryInfo *)aa;
+       LibraryInfo *b = (LibraryInfo *)bb;
 
-    if (a->b_address < b->b_address) return -1;
-    if (a->b_address == b->b_address) return 0;
-    return 1;
+       if (a->b_address < b->b_address) return -1;
+       if (a->b_address == b->b_address) return 0;
+       return 1;
 }
 
 
 int scanline(char *inputstring, char **argv, int maxtokens)
 {
-     int n = 0;
-     char **ap = argv, *p, *val;
-
-     for (p = inputstring; n < maxtokens && p != NULL; ) 
-     {
-        while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
-        *ap++ = val;
-        n++;
-     }
-     *ap = 0;
-     return n;
+       int n = 0;
+       char **ap = argv, *p, *val;
+
+       for (p = inputstring; n < maxtokens && p != NULL; ) {
+
+               while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
+
+               *ap++ = val;
+               n++;
+       }
+       *ap = 0;
+
+       return n;
 }
 
 
@@ -4182,9 +4332,8 @@ int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
        lr->e_address = 0;
 
        if ((fd = fopen(path, "r")) == 0)
-       {
                return 0;
-       }
+
        while (fgets(buf, 1023, fd)) {
                if (strncmp(buf, "mapping", 7))
                        break;
@@ -4202,10 +4351,10 @@ int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
                        /*
                         * There is a ".": name is whatever is between the "/" around the "." 
                         */
-                       while ( *substring != '/') {                /* find "/" before "." */
+                       while ( *substring != '/')                  /* find "/" before "." */
                                substring--;
-                       }
                        substring++;
+
                        strncpy(frameworkName, substring, 256);           /* copy path from "/" */
                        frameworkName[255] = 0;
                        substring = frameworkName;
@@ -4222,8 +4371,7 @@ int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
                        ptr = buf;
                        substring = ptr;
 
-                       while (*ptr) 
-                       {
+                       while (*ptr)  {
                                if (*ptr == '/')
                                        substring = ptr + 1;
                                ptr++;
@@ -4234,8 +4382,7 @@ int ReadSharedCacheMap(const char *path, LibraryRange *lr, char *linkedit_name)
                fnp = (char *)malloc(strlen(frameworkName) + 1);
                strcpy(fnp, frameworkName);
 
-               while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2))
-               {
+               while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2)) {
                        /*
                         * Get rid of EOL
                         */
@@ -4321,163 +4468,214 @@ SortFrameworkAddresses()
 
 struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, uintptr_t thread, double curtime)
 {
-    register struct diskio *dio;
-    register kd_threadmap  *map;
-    
-    if ((dio = free_diskios))
-        free_diskios = dio->next;
-    else {
-        if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
-            return (NULL);
-    }
-    dio->prev = NULL;
+       struct diskio   *dio;
+       threadmap_t     tme;
     
-    dio->type = type;
-    dio->bp = bp;
-    dio->dev = dev;
-    dio->blkno = blkno;
-    dio->iosize = io_size;
-    dio->issued_time = curtime;
-    dio->issuing_thread = thread;
+       if ((dio = free_diskios))
+               free_diskios = dio->next;
+       else {
+               if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
+                       return (NULL);
+       }
+       dio->prev = NULL;
     
-    if ((map = find_thread_map(thread)))
-    {
-        strncpy(dio->issuing_command, map->command, MAXCOMLEN);
-       dio->issuing_command[MAXCOMLEN-1] = '\0';
-    }
-    else
-        strcpy(dio->issuing_command, "");
+       dio->type = type;
+       dio->bp = bp;
+       dio->dev = dev;
+       dio->blkno = blkno;
+       dio->iosize = io_size;
+       dio->issued_time = curtime;
+       dio->issuing_thread = thread;
+       
+       if ((tme = find_map_entry(thread))) {
+               strncpy(dio->issuing_command, tme->tm_command, MAXCOMLEN);
+               dio->issuing_command[MAXCOMLEN-1] = '\0';
+       } else
+               strcpy(dio->issuing_command, "");
     
-    dio->next = busy_diskios;
-    if (dio->next)
-        dio->next->prev = dio;
-    busy_diskios = dio;
+       dio->next = busy_diskios;
+       if (dio->next)
+               dio->next->prev = dio;
+       busy_diskios = dio;
 
-    return (dio);
+       return (dio);
 }
 
 
 struct diskio *complete_diskio(int bp, int io_errno, int resid, uintptr_t thread, double curtime)
 {
-    register struct diskio *dio;
+       struct diskio *dio;
     
-    for (dio = busy_diskios; dio; dio = dio->next) {
-        if (dio->bp == bp) {
-        
-            if (dio == busy_diskios) {
-                if ((busy_diskios = dio->next))
-                    dio->next->prev = NULL;
-            } else {
-                if (dio->next)
-                    dio->next->prev = dio->prev;
-                dio->prev->next = dio->next;
-            }
-            dio->iosize -= resid;
-            dio->io_errno = io_errno;
-            dio->completed_time = curtime;
-            dio->completion_thread = thread;
+       for (dio = busy_diskios; dio; dio = dio->next) {
+
+               if (dio->bp == bp) {
+                       if (dio == busy_diskios) {
+                               if ((busy_diskios = dio->next))
+                                       dio->next->prev = NULL;
+                       } else {
+                               if (dio->next)
+                                       dio->next->prev = dio->prev;
+                               dio->prev->next = dio->next;
+                       }
+                       dio->iosize -= resid;
+                       dio->io_errno = io_errno;
+                       dio->completed_time = curtime;
+                       dio->completion_thread = thread;
             
-           return (dio);
-        }    
-    }
-    return ((struct diskio *)0);
+                       return (dio);
+               }    
+       }
+       return ((struct diskio *)0);
 }
 
 
 void free_diskio(struct diskio *dio)
 {
-    dio->next = free_diskios;
-    free_diskios = dio;
+       dio->next = free_diskios;
+       free_diskios = dio;
 }
 
 
 void print_diskio(struct diskio *dio)
 {
-    register char  *p;
-
-    switch (dio->type) {
-
-        case P_RdMeta:
-            p = "  RdMeta";
-            break;
-        case P_WrMeta:
-            p = "  WrMeta";
-            break;
-        case P_RdData:
-            p = "  RdData";
-            break;
-        case P_WrData:
-            p = "  WrData";
-            break;        
-        case P_PgIn:
-            p = "  PgIn";
-            break;
-        case P_PgOut:
-            p = "  PgOut";
-            break;
-        case P_RdMetaAsync:
-            p = "  RdMeta[async]";
-            break;
-        case P_WrMetaAsync:
-            p = "  WrMeta[async]";
-            break;
-        case P_RdDataAsync:
-            p = "  RdData[async]";
-            break;
-        case P_WrDataAsync:
-            p = "  WrData[async]";
-            break;        
-        case P_PgInAsync:
-            p = "  PgIn[async]";
-            break;
-        case P_PgOutAsync:
-            p = "  PgOut[async]";
-            break;
-        default:
-            p = "  ";
-           break;
-    }
-    if (check_filter_mode(NULL, dio->type, 0, 0, p))
-       format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 0, FMT_DISKIO, dio->completed_time, dio->issued_time, 1, "", dio);
+       char  *p = NULL;
+       int   len = 0;
+       int   type;
+       int   format = FMT_DISKIO;
+       char  buf[64];
+
+       type = dio->type;
+       
+
+       if (type == P_CS_ReadChunk || type == P_CS_WriteChunk || type == P_CS_Originated_Read ||
+           type == P_CS_Originated_Write || type == P_CS_MetaRead || type == P_CS_MetaWrite) {
+
+               switch (type) {
+
+               case P_CS_ReadChunk:
+                       p = "    RdChunkCS";
+                       len = 13;
+                       format = FMT_DISKIO_CS;
+                       break;
+               case P_CS_WriteChunk:
+                       p = "    WrChunkCS";
+                       len = 13;
+                       format = FMT_DISKIO_CS;
+                       break;
+               case P_CS_MetaRead:
+                       p = "  RdMetaCS";
+                       len = 10;
+                       format = FMT_DISKIO_CS;
+                       break;
+               case P_CS_MetaWrite:
+                       p = "  WrMetaCS";
+                       len = 10;
+                       format = FMT_DISKIO_CS;
+                       break;
+               case P_CS_Originated_Read:
+                       p = "  RdDataCS";
+                       len = 10;
+                       break;
+               case P_CS_Originated_Write:
+                       p = "  WrDataCS";
+                       len = 10;
+                       break;
+               }
+               strncpy(buf, p, len);
+       } else {
+
+               switch (type & P_DISKIO_TYPE) {
+
+               case P_RdMeta:
+                       p = "  RdMeta";
+                       len = 8;
+                       break;
+               case P_WrMeta:
+                       p = "  WrMeta";
+                       len = 8;
+                       break;
+               case P_RdData:
+                       p = "  RdData";
+                       len = 8;
+                       break;
+               case P_WrData:
+                       p = "  WrData";
+                       len = 8;
+                       break;        
+               case P_PgIn:
+                       p = "  PgIn";
+                       len = 6;
+                       break;
+               case P_PgOut:
+                       p = "  PgOut";
+                       len = 7;
+                       break;
+               default:
+                       p = "  ";
+                       len = 2;
+                       break;
+               }
+               strncpy(buf, p, len);
+
+               if (type & (P_DISKIO_ASYNC | P_DISKIO_THROTTLE | P_DISKIO_PASSIVE)) {
+                       buf[len++] = '[';
+               
+                       if (type & P_DISKIO_ASYNC) {
+                               memcpy(&buf[len], "async", 5);
+                               len += 5;
+                       }
+                       if (type & P_DISKIO_THROTTLE)
+                               buf[len++] = 'T';
+                       else if (type & P_DISKIO_PASSIVE)
+                               buf[len++] = 'P';
+
+                       buf[len++] = ']';
+               }
+       }
+       buf[len] = 0;
+
+       if (check_filter_mode(NULL, type, 0, 0, buf))
+               format_print(NULL, buf, dio->issuing_thread, type, 0, 0, 0, 0, format, dio->completed_time, dio->issued_time, 1, "", dio);
 }
 
 
 void cache_disk_names()
 {
-    struct stat    st;
-    DIR            *dirp = NULL;
-    struct dirent  *dir;
-    struct diskrec *dnp;
+       struct stat    st;
+       DIR            *dirp = NULL;
+       struct dirent  *dir;
+       struct diskrec *dnp;
 
 
-    if ((dirp = opendir("/dev")) == NULL)
-        return;
+       if ((dirp = opendir("/dev")) == NULL)
+               return;
         
-    while ((dir = readdir(dirp)) != NULL) {
-        char nbuf[MAXPATHLEN];
+       while ((dir = readdir(dirp)) != NULL) {
+               char nbuf[MAXPATHLEN];
         
-        if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
-            continue;
-        snprintf(nbuf, MAXPATHLEN, "%s/%s", "/dev", dir->d_name);
+               if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
+                       continue;
+
+               snprintf(nbuf, MAXPATHLEN, "%s/%s", "/dev", dir->d_name);
         
-       if (stat(nbuf, &st) < 0)
-            continue;
+               if (stat(nbuf, &st) < 0)
+                       continue;
 
-        if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
-            continue;
+               if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
+                       continue;
             
-        if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
-            free(dnp);
-            continue;
-        }
-        strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
-        dnp->diskname[dir->d_namlen] = 0;
-        dnp->dev = st.st_rdev;
+               if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
+                       free(dnp);
+                       continue;
+               }
+               strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
+               dnp->diskname[dir->d_namlen] = 0;
+               dnp->dev = st.st_rdev;
         
-        dnp->next = disk_list;
-        disk_list = dnp;
-    }
-    (void) closedir(dirp);
+               dnp->next = disk_list;
+               disk_list = dnp;
+       }
+       (void) closedir(dirp);
 }
 
 
@@ -4499,110 +4697,38 @@ void recache_disk_names()
 
 char *find_disk_name(int dev)
 {
-    struct diskrec *dnp;
-    int        i;
+       struct diskrec *dnp;
+       int     i;
     
-    if (dev == NFS_DEV)
-        return ("NFS");
+       if (dev == NFS_DEV)
+               return ("NFS");
         
-    for (i = 0; i < 2; i++) {
-           for (dnp = disk_list; dnp; dnp = dnp->next) {
-                   if (dnp->dev == dev)
-                           return (dnp->diskname);
-           }
-           recache_disk_names();
-    }
-    return ("NOTFOUND");
-}
-
-void
-fs_usage_fd_set(thread, fd)
-    unsigned int thread;
-    unsigned int fd;
-{
-    int n;
-    fd_threadmap *fdmap;
-
-    if(!(fdmap = find_fd_thread_map(thread)))
-       return;
-
-    /* If the map is not allocated, then now is the time */
-    if (fdmap->fd_setptr == (unsigned long *)0)
-    {
-       fdmap->fd_setptr = (unsigned long *)malloc(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE));
-       if (fdmap->fd_setptr)
-       {
-           fdmap->fd_setsize = FS_USAGE_FD_SETSIZE;
-           bzero(fdmap->fd_setptr,(FS_USAGE_NFDBYTES(FS_USAGE_FD_SETSIZE)));
+       if (dev == CS_DEV)
+               return ("CS");
+        
+       for (i = 0; i < 2; i++) {
+               for (dnp = disk_list; dnp; dnp = dnp->next) {
+                       if (dnp->dev == dev)
+                               return (dnp->diskname);
+               }
+               recache_disk_names();
        }
-       else
-           return;
-    }
-
-    /* If the map is not big enough, then reallocate it */
-    while (fdmap->fd_setsize <= fd)
-    {
-       fprintf(stderr, "reallocating bitmap for threadid %d, fd = %d, setsize = %d\n",
-         thread, fd, fdmap->fd_setsize);
-       n = fdmap->fd_setsize * 2;
-       fdmap->fd_setptr = (unsigned long *)realloc(fdmap->fd_setptr, (FS_USAGE_NFDBYTES(n)));
-       bzero(&fdmap->fd_setptr[(fdmap->fd_setsize/FS_USAGE_NFDBITS)], (FS_USAGE_NFDBYTES(fdmap->fd_setsize)));
-       fdmap->fd_setsize = n;
-    }
-
-    /* set the bit */
-    fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] |= (1 << ((fd) % FS_USAGE_NFDBITS));
-
-    return;
+       return ("NOTFOUND");
 }
 
-/*
-  Return values:
-  0 : File Descriptor bit is not set
-  1 : File Descriptor bit is set
-*/
-    
-int
-fs_usage_fd_isset(thread, fd)
-    unsigned int thread;
-    unsigned int fd;
-{
-    int ret = 0;
-    fd_threadmap *fdmap;
-
-    if(!(fdmap = find_fd_thread_map(thread)))
-       return(ret);
 
-    if (fdmap->fd_setptr == (unsigned long *)0)
-       return (ret);
-
-    if (fd < fdmap->fd_setsize)
-       ret = fdmap->fd_setptr[fd/FS_USAGE_NFDBITS] & (1 << (fd % FS_USAGE_NFDBITS));
-    
-    return (ret);
-}
-    
-void
-fs_usage_fd_clear(thread, fd)
-    unsigned int thread;
-    unsigned int fd;
+char *generate_cs_disk_name(int dev, char *s)
 {
-    fd_threadmap *map;
-
-    if (!(map = find_fd_thread_map(thread)))
-       return;
-
-    if (map->fd_setptr == (unsigned long *)0)
-       return;
+       if (dev == -1)
+               return ("UNKNOWN");
+       
+       sprintf(s, "disk%ds%d", (dev >> 16) & 0xffff, dev & 0xffff);
 
-    /* clear the bit */
-    if (fd < map->fd_setsize)
-       map->fd_setptr[fd/FS_USAGE_NFDBITS] &= ~(1 << (fd % FS_USAGE_NFDBITS));
-    
-    return;
+       return (s);
 }
 
 
+
 /*
  * ret = 1 means print the entry
  * ret = 0 means don't print the entry
@@ -4610,136 +4736,142 @@ fs_usage_fd_clear(thread, fd)
 int
 check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc_name)
 {
-    int ret = 0;
-    int network_fd_isset = 0;
-    unsigned int fd;
-
-    if (filter_mode == DEFAULT_DO_NOT_FILTER)
-            return(1);
-
-    if (sc_name[0] == 'C' && !strcmp (sc_name, "CACHE_HIT")) {
-            if (filter_mode & CACHEHIT_FILTER)
-                   /* Do not print if cachehit filter is set */
-                   return(0);
-           return(1);
-    }
+       int ret = 0;
+       int network_fd_isset = 0;
+       unsigned int fd;
+
+       if (filter_mode == DEFAULT_DO_NOT_FILTER)
+               return(1);
+
+       if (sc_name[0] == 'C' && !strcmp (sc_name, "CACHE_HIT")) {
+               if (filter_mode & CACHEHIT_FILTER)
+                       /* Do not print if cachehit filter is set */
+                       return(0);
+               return(1);
+       }
        
-    if (filter_mode & EXEC_FILTER)
-    {
-            if (type == BSC_execve)
-                   return(1);
-           return(0);
-    }
+       if (filter_mode & EXEC_FILTER) {
+               if (type == BSC_execve || type == BSC_posix_spawn)
+                       return(1);
+               return(0);
+       }
 
-    if (filter_mode & PATHNAME_FILTER)
-    {
+       if (filter_mode & PATHNAME_FILTER) {
             if (ti && ti->pathname[0])
                    return(1);
            if (type == BSC_close || type == BSC_close_nocancel)
                    return(1);
            return(0);
-    }
+       }
 
-    if ( !(filter_mode & (FILESYS_FILTER | NETWORK_FILTER)))
-       return(1);
+       if ( !(filter_mode & (FILESYS_FILTER | NETWORK_FILTER)))
+               return(1);
 
-       
-    if (ti == (struct th_info *)0)
-    {
-       if (filter_mode & FILESYS_FILTER)
-           ret = 1;
-       else
-           ret = 0;
-       return(ret);
-    }
-
-    switch (type) {
-    case BSC_close:
-    case BSC_close_nocancel:
-       fd = ti->arg1;
-       network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
-       if (error == 0)
-       {
-           fs_usage_fd_clear(ti->thread,fd);
+       if (ti == (struct th_info *)0) {
+               if (filter_mode & FILESYS_FILTER)
+                       return(1);
+               return(0);
        }
-       
-       if (network_fd_isset)
-       {
+
+       switch (type) {
+
+       case BSC_close:
+       case BSC_close_nocancel:
+           fd = ti->arg1;
+           network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+           if (error == 0)
+                   fs_usage_fd_clear(ti->thread,fd);
+           
+           if (network_fd_isset) {
+                   if (filter_mode & NETWORK_FILTER)
+                           ret = 1;
+           } else if (filter_mode & FILESYS_FILTER)
+                   ret = 1;
+           break;
+
+       case BSC_read:
+       case BSC_write:
+       case BSC_read_nocancel:
+       case BSC_write_nocancel:
+           /*
+            * we don't care about error in these cases
+            */
+           fd = ti->arg1;
+           network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+           if (network_fd_isset) {
+                   if (filter_mode & NETWORK_FILTER)
+                           ret = 1;
+           } else if (filter_mode & FILESYS_FILTER)
+                   ret = 1;    
+           break;
+
+       case BSC_accept:
+       case BSC_accept_nocancel:
+       case BSC_socket:
+           fd = retval;
+
+           if (error == 0)
+                   fs_usage_fd_set(ti->thread, fd);
            if (filter_mode & NETWORK_FILTER)
-               ret = 1;
-       }
-       else if (filter_mode & FILESYS_FILTER)
-           ret = 1;
-       break;
-    case BSC_read:
-    case BSC_write:
-    case BSC_read_nocancel:
-    case BSC_write_nocancel:
-       /* we don't care about error in this case */
-       fd = ti->arg1;
-       network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
-       if (network_fd_isset)
-       {
+                   ret = 1;
+           break;
+
+       case BSC_recvfrom:
+       case BSC_sendto:
+       case BSC_recvmsg:
+       case BSC_sendmsg:
+       case BSC_connect:
+       case BSC_bind:
+       case BSC_listen:            
+       case BSC_sendto_nocancel:
+       case BSC_recvfrom_nocancel:
+       case BSC_recvmsg_nocancel:
+       case BSC_sendmsg_nocancel:
+       case BSC_connect_nocancel:
+           fd = ti->arg1;
+
+           if (error == 0)
+                   fs_usage_fd_set(ti->thread, fd);
            if (filter_mode & NETWORK_FILTER)
-               ret = 1;
-       }
-       else if (filter_mode & FILESYS_FILTER)
-           ret = 1;    
-       break;
-    case BSC_accept:
-    case BSC_accept_nocancel:
-    case BSC_socket:
-       fd = retval;
-       if (error == 0)
-           fs_usage_fd_set(ti->thread, fd);
-       if (filter_mode & NETWORK_FILTER)
-           ret = 1;
-       break;
-    case BSC_recvfrom:
-    case BSC_sendto:
-    case BSC_recvmsg:
-    case BSC_sendmsg:
-    case BSC_connect:
-    case BSC_bind:
-    case BSC_listen:       
-    case BSC_sendto_nocancel:
-    case BSC_recvfrom_nocancel:
-    case BSC_recvmsg_nocancel:
-    case BSC_sendmsg_nocancel:
-    case BSC_connect_nocancel:
-       fd = ti->arg1;
-       if (error == 0)
-           fs_usage_fd_set(ti->thread, fd);
-       if (filter_mode & NETWORK_FILTER)
-           ret = 1;
-       break;
-    case BSC_select:
-    case BSC_select_nocancel:
-    case BSC_socketpair:
-       /* Cannot determine info about file descriptors */
-       if (filter_mode & NETWORK_FILTER)
-           ret = 1;
-       break;
-    case BSC_dup:
-    case BSC_dup2:
-       ret=0;   /* We track these cases for fd state only */
-       fd = ti->arg1;  /* oldd */
-       network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
-       if (error == 0 && network_fd_isset)
-       {
-           /* then we are duping a socket descriptor */
-           fd = retval;  /* the new fd */
-           fs_usage_fd_set(ti->thread, fd);
-       }
-       break;
+                   ret = 1;
+           break;
+
+       case BSC_select:
+       case BSC_select_nocancel:
+       case BSC_socketpair:
+           /*
+            * Cannot determine info about file descriptors
+            */
+           if (filter_mode & NETWORK_FILTER)
+                   ret = 1;
+           break;
+
+       case BSC_dup:
+       case BSC_dup2:
+           /*
+            * We track these cases for fd state only
+            */
+           fd = ti->arg1;
+           network_fd_isset = fs_usage_fd_isset(ti->thread, fd);
+
+           if (error == 0 && network_fd_isset) {
+                   /*
+                    * then we are duping a socket descriptor
+                    */
+                   fd = retval;  /* the new fd */
+                   fs_usage_fd_set(ti->thread, fd);
+           }
+           break;
 
-    default:
-       if (filter_mode & FILESYS_FILTER)
-           ret = 1;
-       break;
-    }
+       default:
+           if (filter_mode & FILESYS_FILTER)
+                   ret = 1;
+           break;
+       }
 
-    return(ret);
+       return(ret);
 }
 
 /*
@@ -4752,110 +4884,113 @@ check_filter_mode(struct th_info * ti, int type, int error, int retval, char *sc
 void
 init_arguments_buffer()
 {
+       int     mib[2];
+       size_t  size;
 
-    int     mib[2];
-    size_t  size;
-
-    mib[0] = CTL_KERN;
-    mib[1] = KERN_ARGMAX;
-    size = sizeof(argmax);
-    if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
-       return;
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_ARGMAX;
+       size = sizeof(argmax);
 
+       if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
+               return;
 #if 1
-    /* Hack to avoid kernel bug. */
-    if (argmax > 8192) {
-       argmax = 8192;
-    }
+       /* Hack to avoid kernel bug. */
+       if (argmax > 8192) {
+               argmax = 8192;
+       }
 #endif
-
-    arguments = (char *)malloc(argmax);
-    
-    return;
+       arguments = (char *)malloc(argmax);
 }
 
 
 int
 get_real_command_name(int pid, char *cbuf, int csize)
 {
-    /*
-     *      Get command and arguments.
-     */
-    char  *cp;
-    int             mib[4];
-    char    *command_beg, *command, *command_end;
-
-    if (cbuf == NULL) {
-       return(0);
-    }
-
-    if (arguments)
-       bzero(arguments, argmax);
-    else
-       return(0);
-
-    /*
-     * A sysctl() is made to find out the full path that the command
-     * was called with.
-     */
-    mib[0] = CTL_KERN;
-    mib[1] = KERN_PROCARGS2;
-    mib[2] = pid;
-    mib[3] = 0;
-
-    if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0) {
-       return(0);
-    }
-
-    /* Skip the saved exec_path. */
-    for (cp = arguments; cp < &arguments[argmax]; cp++) {
-       if (*cp == '\0') {
-           /* End of exec_path reached. */
-           break;
-       }
-    }
-    if (cp == &arguments[argmax]) {
-       return(0);
-    }
-
-    /* Skip trailing '\0' characters. */
-    for (; cp < &arguments[argmax]; cp++) {
-       if (*cp != '\0') {
-           /* Beginning of first argument reached. */
-           break;
+       /*
+        * Get command and arguments.
+        */
+       char    *cp;
+       int     mib[4];
+       char    *command_beg, *command, *command_end;
+
+       if (cbuf == NULL)
+               return(0);
+
+       if (arguments)
+               bzero(arguments, argmax);
+       else
+               return(0);
+
+       /*
+        * A sysctl() is made to find out the full path that the command
+        * was called with.
+        */
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_PROCARGS2;
+       mib[2] = pid;
+       mib[3] = 0;
+
+       if (sysctl(mib, 3, arguments, (size_t *)&argmax, NULL, 0) < 0)
+               return(0);
+
+       /*
+        * Skip the saved exec_path
+        */
+       for (cp = arguments; cp < &arguments[argmax]; cp++) {
+               if (*cp == '\0') {
+                       /*
+                        * End of exec_path reached
+                        */
+                       break;
+               }
        }
-    }
-    if (cp == &arguments[argmax]) {
-       return(0);
-    }
-    command_beg = cp;
-
-    /*
-     * Make sure that the command is '\0'-terminated.  This protects
-     * against malicious programs; under normal operation this never
-     * ends up being a problem..
-     */
-    for (; cp < &arguments[argmax]; cp++) {
-       if (*cp == '\0') {
-           /* End of first argument reached. */
-           break;
+       if (cp == &arguments[argmax])
+               return(0);
+
+       /*
+        * Skip trailing '\0' characters
+        */
+       for (; cp < &arguments[argmax]; cp++) {
+               if (*cp != '\0') {
+                       /*
+                        * Beginning of first argument reached
+                        */
+                       break;
+               }
        }
-    }
-    if (cp == &arguments[argmax]) {
-       return(0);
-    }
-    command_end = command = cp;
-
-    /* Get the basename of command. */
-    for (command--; command >= command_beg; command--) {
-       if (*command == '/') {
-           command++;
-           break;
+       if (cp == &arguments[argmax])
+               return(0);
+
+       command_beg = cp;
+       /*
+        * Make sure that the command is '\0'-terminated.  This protects
+        * against malicious programs; under normal operation this never
+        * ends up being a problem..
+        */
+       for (; cp < &arguments[argmax]; cp++) {
+               if (*cp == '\0') {
+                       /*
+                        * End of first argument reached
+                        */
+                       break;
+               }
        }
-    }
+       if (cp == &arguments[argmax])
+               return(0);
+
+       command_end = command = cp;
 
-    (void) strncpy(cbuf, (char *)command, csize);
-    cbuf[csize-1] = '\0';
+       /*
+        * Get the basename of command
+        */
+       for (command--; command >= command_beg; command--) {
+               if (*command == '/') {
+                       command++;
+                       break;
+               }
+       }
+       (void) strncpy(cbuf, (char *)command, csize);
+       cbuf[csize-1] = '\0';
 
-    return(1);
+       return(1);
 }
index aa855d93e4283f035c5ff65985d0f1244f7c4ca9..dee18c133cfc7d94963431ef2578406957db0cac 100644 (file)
@@ -9,7 +9,7 @@ CFILES = getconf.c \
        $(OBJROOT)/$(Project)/sysconf.c 
 MANPAGES = getconf.1
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -include _fbsd_compat.h -DAPPLE_GETCONF_UNDERSCORE \
                -DAPPLE_GETCONF_SPEC -I.
 Extra_LD_Flags = -dead_strip
index 95283a83baa96296560a7ef684d8c2fa98ebd947..9bc38661575ca6d5df32f3aca673da2d5ede8dee 100644 (file)
@@ -74,7 +74,7 @@ _POSIX2_FORT_DEV, _SC_2_FORT_DEV
 _POSIX2_FORT_RUN, _SC_2_FORT_RUN
 _POSIX2_LOCALEDEF, _SC_2_LOCALEDEF
 _POSIX2_PBS, _SC_PBS
-_POSIX2_PBS_ACCOUNTING, _SC_PBS_ACCOUNTING,
+_POSIX2_PBS_ACCOUNTING, _SC_PBS_ACCOUNTING
 _POSIX2_PBS_CHECKPOINT, _SC_PBS_CHECKPOINT
 _POSIX2_PBS_LOCATE, _SC_PBS_LOCATE
 _POSIX2_PBS_MESSAGE, _SC_PBS_MESSAGE
index fe7ba7769c0304d1a93d8bb2e15d12e73471d73e..e48d4aac9cfc5919f3701c37efcc01092359e53a 100644 (file)
@@ -10,7 +10,7 @@ ifeq ($(Embedded),YES)
 LAUNCHD_PLISTS = com.apple.getty.plist
 endif
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 147ef845e5ec75a63c3f8cd2f6d563b0ded9e7d4..90947229bbe959e4ec6813adde289708ad8a65ac 100644 (file)
@@ -390,7 +390,7 @@ chat_send(char const *str)
 {
        int r = 0;
 
-       if (chat_debug && CHATDEBUG_SEND)
+       if (chat_debug & CHATDEBUG_SEND)
                syslog(LOG_DEBUG, "chat_send '%s'", cleanstr(str, strlen(str)));
 
        if (*str) {
index 2b6dcc4432fdadcc008291dc4da84ba06600654e..376371d30fa0e6cc34d24e0b5d28fe90f8070960 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = hostinfo.c
 MANPAGES = hostinfo.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index b6a5ca76c335e61a218a06f36a383748d45797fa..7a696b6189ce0946b475055f6b4522f9e0d4be49 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = iostat.c
 MANPAGES = iostat.8
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip
 
 Extra_Frameworks = -framework CoreFoundation -framework IOKit
index 2713ef45102aead4dc44f10618de6a6dce42d657..643df3dfdf26b29e3cf51442dc6113dd3788da8e 100644 (file)
@@ -329,7 +329,7 @@ main(int argc, char **argv)
                if (isdigit(**argv))
                        break;
                if (record_one_device(*argv))
-                       errx(1, "can't record '%s' for monitoring");
+                       errx(1, "can't record '%s' for monitoring", *argv);
                num_devices_specified++;
        }
        if (nflag == 0 && maxshowdevs < num_devices_specified)
@@ -865,7 +865,7 @@ static void remove_drivelist(void* context, io_iterator_t drivelist)
                name = (CFStringRef)CFDictionaryGetValue(properties,
                        CFSTR(kIOBSDNameKey));
 
-               if (name && CFStringGetCString(name, bsdname, MAXDRIVENAME, CFStringGetSystemEncoding())) {
+               if (name && CFStringGetCString(name, bsdname, MAXDRIVENAME, kCFStringEncodingUTF8)) {
                        int i;
                        for (i = 0; i < num_devices; ++i) {
                                if (strcmp(bsdname,drivestat[i].name) == 0) {
@@ -958,7 +958,7 @@ record_device(io_registry_entry_t drive)
                        CFSTR(kIOBSDNameKey));
                if (name)
                        CFStringGetCString(name, drivestat[num_devices].name, 
-                                          MAXDRIVENAME, CFStringGetSystemEncoding());
+                                          MAXDRIVENAME, kCFStringEncodingUTF8);
                else {
                        errx(1, "device does not have a BSD name");
                }
index a8377fa99c90c6082ea0599601f6da6b9c4843da..2576afdaa43902ec2641b1510b8377d14d568b43 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = latency.c
 MANPAGES = latency.1
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip
 
 Extra_LD_Flags += -lcurses -lutil
index debed8b53d94d607afb9f0362bb3f4604ac229f2..564eb90407568cbd966597fabe1f338b51cb2355 100644 (file)
@@ -8,14 +8,14 @@
 .Nd monitors scheduling and interrupt latency
 .Sh SYNOPSIS
 .Nm latency
-.Op Fl rt
+.Op Fl p
 .Op Fl h
-.Op Fl c Ar code_file
-.Op Fl l Ar log_file
+.Op Fl m
 .Op Fl st Ar threshold
 .Op Fl it Ar threshold
-.Op Fl s Ar sleep_in_usecs
-.Op Fl d Ar decrementer_in_usecs
+.Op Fl c Ar code_file
+.Op Fl l Ar log_file
+.Op Fl R Ar raw_file
 .Op Fl n Ar kernel
 .Sh DESCRIPTION
 The
@@ -35,9 +35,11 @@ that contains the mappings for the system calls.
 This option overrides the default location of the system call code file,
 which is found in /usr/share/misc/trace.codes.
 .\" ==========
-.It Fl d Ar decrementer_in_usecs
-Sets the decrementer, using a value expressed in microseconds.
-On exit, the decrementer is set back to the system default value.
+.It Fl h
+Display high resolution interrupt latencies and write them to latencies.csv (truncate existing file) upon exit.
+.\" ==========
+.It Fl m
+Display per-CPU interrupt latency statistics.
 .\" ==========
 .It Fl it Ar threshold
 Set the interrupt latency threshold,
@@ -56,21 +58,16 @@ By default,
 acts on the default /mach_kernel.
 This option allows you to specify an alternate booted kernel.
 .\" ==========
-.It Fl rt
-Sets the real-time scheduling policy.
-Default policy is timeshare.
-.\" ==========
-.It Fl h
-Display high resolution interrupt latencies and write them to latencies.csv (truncate existing file) upon exit.
-.\" ==========
-.It Fl s Ar sleep_in_usecs
-Sets the timer, taking an argument expressed in microseconds.
-The default timer is set to 1000 microseconds.
+.It Fl p Ar priority
+Specifies the priority level to observe scheduler latencies for.
 .\" ==========
 .It Fl st Ar threshold
 Set the scheduler latency threshold in microseconds.
 If latency exceeds this, and a log file has been specified,
 a record of what occurred during this time is recorded.
+.\" ==========
+.It Fl R Ar raw_file
+Specifies a raw trace file to use as input.
 .El
 .Pp
 The data columns displayed are as follows:
@@ -87,11 +84,11 @@ utility is also SIGWINCH savvy, so adjusting your window geometry will change
 the list of delay values displayed.
 .Sh SAMPLE USAGE
 .Pp
-latency -rt -st 20000 -it 1000 -l /var/tmp/latency.log
+latency -p 97 -st 20000 -it 1000 -l /var/tmp/latency.log
 .Pp
 The
 .Nm latency
-utility will set the realtime scheduling policy.
+utility will watch threads with priority 97 for scheduling latencies.
 The threshold for the scheduler is set to 20000 microseconds.
 The threshold for interrupts is set to 1000 microseconds.
 Latencies that exceed these thresholds will be logged in /var/tmp/latency.log.
index 65b3c9ba65d71c6fc44d28a17c9a7f52616693b9..a731d4a6442845eea7f7f6e975137260c962ef98 100644 (file)
@@ -1,30 +1,28 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 
-
 /* 
-   cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o latency latency.c -lncurses
+   cc -I/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -DPRIVATE -D__APPLE_PRIVATE -arch x86_64 -arch i386 -O -o latency latency.c -lncurses -lutil
 */
 
 #include <mach/mach.h>
 #include <nlist.h>
 #include <fcntl.h>
 #include <string.h>
+#include <libc.h>
+#include <termios.h>
+#include <curses.h>
+#include <libutil.h>
+#include <errno.h>
+#include <err.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/time.h>
-
-#include <libc.h>
-#include <termios.h>
-#include <curses.h>
+#include <sys/sysctl.h>
 #include <sys/ioctl.h>
 
 #ifndef KERNEL_PRIVATE
 #include <sys/kdebug.h>
 #endif /*KERNEL_PRIVATE*/
 
-#include <libutil.h>
-
-#include <sys/sysctl.h>
-#include <errno.h>
-#include <err.h>
-
-#include <mach/host_info.h>
 #include <mach/mach_error.h>
 #include <mach/mach_types.h>
 #include <mach/message.h>
 
 #include <libkern/OSTypes.h>
 
-extern mach_port_t clock_port;
-
-#define KERN_KDPIDEX    14
-
 
 int      s_usec_10_bins[10];
 int      s_usec_100_bins[10];
@@ -83,122 +73,226 @@ int      s_too_slow;
 int      s_max_latency;
 int      s_min_latency = 0;
 long long s_total_latency = 0;
-int      s_total_samples;
+int      s_total_samples = 0;
 long     s_thresh_hold;
 int      s_exceeded_threshold = 0;
 
-int      i_usec_10_bins[10];
-int      i_usec_100_bins[10];
-int      i_msec_1_bins[10];
-int      i_msec_10_bins[5];
-int      i_too_slow;
-int      i_max_latency;
-int      i_min_latency = 0;
-long long i_total_latency = 0;
-int      i_total_samples;
+
+#define N_HIGH_RES_BINS 500
+int      use_high_res_bins = false;
+
+struct i_latencies {
+       int      i_usec_10_bins[10];
+       int      i_usec_100_bins[10];
+       int      i_msec_1_bins[10];
+       int      i_msec_10_bins[5];
+       int      i_too_slow;
+       int      i_max_latency;
+       int      i_min_latency;
+       int      i_total_samples;
+       int      i_total;
+       int      i_exceeded_threshold;
+       uint64_t i_total_latency;
+};
+
+struct i_latencies *i_lat;
+boolean_t i_latency_per_cpu = FALSE;
+
+int      i_high_res_bins[N_HIGH_RES_BINS];
+
 long     i_thresh_hold;
-int      i_exceeded_threshold = 0;
+
+int     watch_priority = 97;
 
 long     start_time;
 long     curr_time;
 long     refresh_time;
 
-char     *policy_name;
-int      my_policy;
-int      my_pri = -1;
-int      num_of_usecs_to_sleep = 1000;
-
-#define N_HIGH_RES_BINS 500
-int      use_high_res_bins = false;
-int      i_high_res_bins[N_HIGH_RES_BINS];
-int      i_highest_latency = 0;
 
-char *kernelpath = (char *)0;
-char *code_file = (char *)0;
+char *kernelpath = NULL;
 
 typedef struct {
-  u_long  k_sym_addr;       /* kernel symbol address from nm */
-  u_int   k_sym_len;        /* length of kernel symbol string */
-  char   *k_sym_name;       /* kernel symbol string from nm */
+       void     *k_sym_addr;   /* kernel symbol address from nm */
+       u_int     k_sym_len;    /* length of kernel symbol string */
+       char     *k_sym_name;   /* kernel symbol string from nm */
 } kern_sym_t;
 
-kern_sym_t *kern_sym_tbl;      /* pointer to the nm table       */
-int        kern_sym_count;    /* number of entries in nm table */
-char       pcstring[128];
+kern_sym_t *kern_sym_tbl;      /* pointer to the nm table       */
+int        kern_sym_count;     /* number of entries in nm table */
+
+
 
-#define UNKNOWN "Can't find symbol name"
+#define MAX_ENTRIES 4096
+struct ct {
+       int type;
+       char name[32];
+} codes_tab[MAX_ENTRIES];
 
+char *code_file = NULL;
+int    num_of_codes = 0;
 
-double   divisor;
-int      gotSIGWINCH = 0;
-int      trace_enabled = 0;
-struct host_basic_info  hi;
 
+double divisor;
+sig_atomic_t gotSIGWINCH = 0;
+int    trace_enabled = 0;
+int    need_new_map = 1;
+int    set_remove_flag = 1;    /* By default, remove trace buffer */
 
-#define SAMPLE_SIZE 300000
+int    RAW_flag = 0;
+int    RAW_fd   = 0;
 
-int mib[6];
-size_t needed;
-char  *my_buffer;
+uint64_t first_now = 0;
+uint64_t last_now = 0;
+int    first_read = 1;
+
+
+#define        SAMPLE_TIME_USECS 50000
+#define SAMPLE_SIZE 300000
+#define MAX_LOG_COUNT  30       /* limits the number of entries dumped in log_decrementer */
 
 kbufinfo_t bufinfo = {0, 0, 0};
 
-FILE *log_fp = (FILE *)0;
-int num_of_codes = 0;
-int need_new_map = 0;
-int total_threads = 0;
-kd_threadmap *mapptr = 0;
+FILE *log_fp = NULL;
 
-#define MAX_ENTRIES 4096
-struct ct {
-        int type;
-        char name[32];
-} codes_tab[MAX_ENTRIES];
+uint64_t sample_TOD_secs;
+uint32_t sample_TOD_usecs;
+
+int    sample_generation = 0;
+int    num_i_latency_cpus = 1;
+int    num_cpus;
+char *my_buffer;
+int    num_entries;
+
+kd_buf **last_decrementer_kd;   /* last DECR_TRAP per cpu */
 
 
 #define NUMPARMS 23
 
-struct th_info {
-        uintptr_t  thread;
-        int  type;
-        uintptr_t  child_thread;
-        int  arg1;
-        double stime;
-        long *pathptr;
-        long pathname[NUMPARMS + 1];
+typedef struct event *event_t;
+
+struct event {
+       event_t   ev_next;
+
+       uintptr_t ev_thread;
+       uint32_t  ev_type;
+       uint64_t  ev_timestamp;
+};
+
+
+typedef struct lookup *lookup_t;
+
+struct lookup {
+       lookup_t  lk_next;
+       
+       uintptr_t lk_thread;
+       uintptr_t lk_dvp;
+       long     *lk_pathptr;
+       long      lk_pathname[NUMPARMS + 1];
+};
+
+
+typedef struct threadmap *threadmap_t;
+
+struct threadmap {
+       threadmap_t     tm_next;
+       
+       uintptr_t       tm_thread;
+       uintptr_t       tm_pthread;
+       char            tm_command[MAXCOMLEN + 1];
+       char            tm_orig_command[MAXCOMLEN + 1];
+};
+
+
+typedef struct threadrun *threadrun_t;
+
+struct threadrun {
+       threadrun_t     tr_next;
+       
+       uintptr_t       tr_thread;
+       kd_buf          *tr_entry;
+       uint64_t        tr_timestamp;
+};
+
+
+typedef struct thread_entry *thread_entry_t;
+
+struct thread_entry {
+       thread_entry_t  te_next;
+
+       uintptr_t       te_thread;
 };
+       
+
+#define HASH_SIZE       1024
+#define HASH_MASK       1023
+
+event_t         event_hash[HASH_SIZE];
+lookup_t        lookup_hash[HASH_SIZE];
+threadmap_t     threadmap_hash[HASH_SIZE];
+threadrun_t    threadrun_hash[HASH_SIZE];
+
+event_t         event_freelist;
+lookup_t        lookup_freelist;
+threadrun_t    threadrun_freelist;
+threadmap_t     threadmap_freelist;
+threadmap_t     threadmap_temp;
+
+thread_entry_t thread_entry_freelist;
+thread_entry_t thread_delete_list;
+thread_entry_t thread_reset_list;
+thread_entry_t thread_event_list;
+thread_entry_t thread_lookup_list;
+thread_entry_t thread_run_list;
+
+
+#ifndef        RAW_VERSION1
+typedef struct {
+       int version_no;
+       int thread_count;
+       uint64_t TOD_secs;
+       uint32_t TOD_usecs;
+} RAW_header;
+
+#define RAW_VERSION0    0x55aa0000
+#define RAW_VERSION1    0x55aa0101
+#endif
+
 
-#define MAX_THREADS 512
-struct th_info th_state[MAX_THREADS];
+#define        USER_MODE       0
+#define KERNEL_MODE    1
 
-int  cur_max = 0;
 
-#define TRACE_DATA_NEWTHREAD   0x07000004
-#define TRACE_STRING_NEWTHREAD 0x07010004
-#define TRACE_STRING_EXEC      0x07010008
+#define TRACE_DATA_NEWTHREAD   0x07000004
+#define TRACE_STRING_NEWTHREAD 0x07010004
+#define TRACE_STRING_EXEC      0x07010008
 
-#define INTERRUPT         0x01050000
-#define DECR_TRAP         0x01090000
-#define DECR_SET          0x01090004
-#define MACH_vmfault      0x01300008
-#define MACH_sched        0x01400000
-#define MACH_stkhandoff   0x01400008
-#define VFS_LOOKUP        0x03010090
-#define BSC_exit          0x040C0004
-#define IES_action        0x050b0018
-#define IES_filter        0x050b001c
-#define TES_action        0x050c0010
-#define CQ_action         0x050d0018
+#define INTERRUPT              0x01050000
+#define DECR_TRAP              0x01090000
+#define DECR_SET               0x01090004
+#define MACH_vmfault           0x01300008
+#define MACH_sched             0x01400000
+#define MACH_stkhandoff        0x01400008
+#define MACH_makerunnable      0x01400018
+#define MACH_idle              0x01400024
+#define VFS_LOOKUP             0x03010090
+#define IES_action             0x050b0018
+#define IES_filter             0x050b001c
+#define TES_action             0x050c0010
+#define CQ_action              0x050d0018
+#define CPUPM_CPUSTER_RUNCOUNT 0x05310144
 
+#define BSC_exit               0x040C0004
+#define BSC_thread_terminate   0x040c05a4
 
-#define DBG_FUNC_ALL   (DBG_FUNC_START | DBG_FUNC_END)
-#define DBG_FUNC_MASK  0xfffffffc
+#define DBG_FUNC_MASK  ~(DBG_FUNC_START | DBG_FUNC_END)
 
 #define CPU_NUMBER(kp) kdbg_get_cpu(kp)
 
+#define EMPTYSTRING    ""
 
-char *fault_name[9] = {
-        "",
+
+const char *fault_name[] = {
+       "",
        "ZeroFill",
        "PageIn",
        "COW",
@@ -209,296 +303,256 @@ char *fault_name[9] = {
        "PageInAnon"
 };
 
-char *pc_to_string();
-static kern_return_t   set_time_constraint_policy(void);
-static kern_return_t   set_standard_policy(void);
-
-int decrementer_val = 0;     /* Value used to reset decrementer */
-int set_remove_flag = 1;     /* By default, remove trace buffer */
-
-kd_buf **last_decrementer_kd;   /* last DECR_TRAP per cpu */
-#define MAX_LOG_COUNT  30       /* limits the number of entries dumped in log_decrementer */
+const char *sched_reasons[] = {
+       "N",
+       "P",
+       "Q",
+       "?",
+       "u",
+       "U",
+       "?",
+       "?",
+       "H",
+       "?",
+       "?",
+       "?",
+       "?",
+       "?",
+       "?",
+       "?",
+       "Y"
+};
 
-int
-quit(s)
-char *s;
+#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(*x)))
+#define MAX_REASON ARRAYSIZE(sched_reasons)
+
+static double handle_decrementer(kd_buf *, int);
+static kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, double i_latency);
+static void read_command_map(void);
+static void enter_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, int print_info);
+static void exit_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, int print_info);
+static void print_entry(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, kd_buf *kd_note);
+static void log_info(uint64_t now, uint64_t idelta, uint64_t start_bias, kd_buf *kd, kd_buf *kd_note);
+static char *find_code(int);
+static void pc_to_string(char *pcstring, uintptr_t pc, int max_len, int mode);
+static void getdivisor(void);
+static int sample_sc(void);
+static void init_code_file(void);
+static void do_kernel_nm(void);
+static void open_logfile(const char*);
+static int binary_search(kern_sym_t *list, int low, int high, uintptr_t addr);
+
+static void create_map_entry(uintptr_t, char *);
+static void check_for_thread_update(uintptr_t thread, int debugid_base, kd_buf *kbufp, char **command);
+static void log_scheduler(kd_buf *kd_start, kd_buf *kd_stop, kd_buf *end_of_sample, double s_latency, uintptr_t thread);
+static int check_for_scheduler_latency(int type, uintptr_t *thread, uint64_t now, kd_buf *kd, kd_buf **kd_start, double *latency);
+static void open_rawfile(const char *path);
+
+static void screen_update(FILE *);
+
+static void set_enable(int);
+static void set_remove(void);
+
+static int
+quit(char *s)
 {
-        void set_enable();
-       void set_rtcdec();
-       void set_remove();
-
-        if (trace_enabled)
-               set_enable(0);
-
-       /* 
-          This flag is turned off when calling
-          quit() due to a set_remove() failure.
-       */
-       if (set_remove_flag)
-         set_remove();
-
-       if (decrementer_val)
-         set_rtcdec(0);
-
-        printf("latency: ");
-       if (s)
+       if (!RAW_flag) {
+               if (trace_enabled) {
+                       set_enable(0);
+               }
+               /* 
+                *  This flag is turned off when calling
+                * quit() due to a set_remove() failure.
+                */
+               if (set_remove_flag) {
+                       set_remove();
+               }
+       }
+       printf("latency: ");
+       if (s) {
                printf("%s", s);
-
+       }
        exit(1);
 }
 
 void
 set_enable(int val) 
 {
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDENABLE;         /* protocol */
-       mib[3] = val;
-       mib[4] = 0;
-       mib[5] = 0;                     /* no flags */
-
-       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDENABLE\n");
+       int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDENABLE, val };
+       size_t needed;
+
+       if (sysctl(mib, ARRAYSIZE(mib), NULL, &needed, NULL, 0) < 0) {
+               quit("trace facility failure, KERN_KDENABLE\n");
+       }
 }
 
 void
 set_numbufs(int nbufs) 
 {
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETBUF;
-       mib[3] = nbufs;
-       mib[4] = 0;
-       mib[5] = 0;                     /* no flags */
-       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETBUF\n");
-
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETUP;          
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;                     /* no flags */
-       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETUP\n");
+       int mib1[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSETBUF, nbufs };
+       int mib2[] = { CTL_KERN, KERN_KDEBUG, KERN_KDSETUP };
+       size_t needed;
 
+       if (sysctl(mib1, ARRAYSIZE(mib1), NULL, &needed, NULL, 0) < 0) {
+               quit("trace facility failure, KERN_KDSETBUF\n");
+       }
+       if (sysctl(mib2, ARRAYSIZE(mib2), NULL, &needed, NULL, 0) < 0) {
+               quit("trace facility failure, KERN_KDSETUP\n");
+       }
 }
 
 void
 set_pidexclude(int pid, int on_off) 
 {
-        kd_regtype kr;
-
-       kr.type = KDBG_TYPENONE;
-       kr.value1 = pid;
-       kr.value2 = on_off;
-       needed = sizeof(kd_regtype);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDPIDEX;
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;
-
-       sysctl(mib, 3, &kr, &needed, NULL, 0);
-}
+       int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDPIDEX };
+       size_t needed = sizeof(kd_regtype);
 
-void set_rtcdec(decval)
-int decval;
-{kd_regtype kr;
- int ret;
- extern int errno;
-
-       kr.type = KDBG_TYPENONE;
-       kr.value1 = decval;
-       needed = sizeof(kd_regtype);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETRTCDEC;              /* protocol */
-       mib[3] = 0;             /* wildcard address family */
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
+       kd_regtype kr = {
+               .type = KDBG_TYPENONE,
+               .value1 = pid,
+               .value2 = on_off
+       };
 
-       errno = 0;
-       if ((ret=sysctl(mib, 3, &kr, &needed, NULL, 0)) < 0)
-         {
-             decrementer_val = 0;
-             /* ignore this sysctl error if it's not supported */
-             if (errno == ENOENT) 
-                 return;
-             else
-                 quit("trace facility failure, KERN_KDSETRTCDEC\n");
-         }
+       sysctl(mib, ARRAYSIZE(mib), &kr, &needed, NULL, 0);
 }
 
-
 void
 get_bufinfo(kbufinfo_t *val)
 {
-        needed = sizeof (*val);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDGETBUF;         
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-
-       if (sysctl(mib, 3, val, &needed, 0, 0) < 0)
-               quit("trace facility failure, KERN_KDGETBUF\n");
-
+       int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDGETBUF };
+       size_t needed = sizeof (*val);
+       
+       if (sysctl(mib, ARRAYSIZE(mib), val, &needed, 0, 0) < 0) {
+               quit("trace facility failure, KERN_KDGETBUF\n");
+       }
 }
 
 void
-set_remove(
+set_remove(void)
 {
-  extern int errno;
-
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDREMOVE;         /* protocol */
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
+       int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDREMOVE };
+       size_t needed;
 
        errno = 0;
 
-       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
-         {
-             set_remove_flag = 0;
-             if(errno == EBUSY)
-                 quit("the trace facility is currently in use...\n         fs_usage, sc_usage, and latency use this feature.\n\n");
-             else
-                 quit("trace facility failure, KERN_KDREMOVE\n");
-         }
+       if (sysctl(mib, ARRAYSIZE(mib), NULL, &needed, NULL, 0) < 0) {
+               set_remove_flag = 0;
+               if (errno == EBUSY) {
+                       quit("the trace facility is currently in use...\n         fs_usage, sc_usage, and latency use this feature.\n\n");
+               } else {
+                       quit("trace facility failure, KERN_KDREMOVE\n");
+               }
+       }
 }
 
+
 void
-set_init_nologging()
+write_high_res_latencies(void)
 {
-        /* When we aren't logging, only collect the DECR_TRAP trace points */
-        kd_regtype kr;
-        kr.type = KDBG_VALCHECK;
-        kr.value1 = DECR_TRAP;
-       kr.value2 = 0;
-        kr.value3 = 0;
-        kr.value4 = 0;
-       needed = sizeof(kd_regtype);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETREG;
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-       if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETREG\n");
-
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETUP;          
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-
-       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETUP\n");
-}
+       int i;
+       FILE *f;
 
-void
-set_init_logging() 
-{       kd_regtype kr;
-
-       kr.type = KDBG_RANGETYPE;
-       kr.value1 = 0;  
-       kr.value2 = -1;
-       needed = sizeof(kd_regtype);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETREG;         
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-
-       if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETREG\n");
-
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDSETUP;          
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-
-       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDSETUP\n");
+       if (use_high_res_bins) {
+               if ((f = fopen("latencies.csv","w"))) {
+                       for (i = 0; i < N_HIGH_RES_BINS; i++) {
+                               fprintf(f, "%d,%d\n", i, i_high_res_bins[i]);
+                       }
+                       fclose(f);
+               }
+       }
 }
 
 void
-write_high_res_latencies()
+sigintr(int signo __attribute__((unused)))
 {
-    int i;
-    FILE *f;
-    if(use_high_res_bins)
-    {
-        f = fopen("latencies.csv","w");
-        for(i=0;i<N_HIGH_RES_BINS;i++)
-        {
-            fprintf(f,"%d,%d\n", i, i_high_res_bins[i]);
-        }
-        fclose(f);
-    }
-}
+       write_high_res_latencies();
 
-void sigwinch()
-{
-        gotSIGWINCH = 1;
+       set_enable(0);
+       set_pidexclude(getpid(), 0);
+       screen_update(log_fp);
+       endwin();
+       set_remove();
+
+       exit(1);
 }
 
-void sigintr()
+/* exit under normal conditions -- signal handler */
+void
+leave(int signo __attribute__((unused)))
 {
-        void screen_update();
+       write_high_res_latencies();
 
-        write_high_res_latencies();
-
-        set_enable(0);
+       set_enable(0);
        set_pidexclude(getpid(), 0);
-        screen_update(log_fp);
        endwin();
-       set_rtcdec(0);
        set_remove();
        
-        exit(1);
+       exit(1);
 }
 
-void leave()    /* exit under normal conditions -- signal handler */
+void
+sigwinch(int signo __attribute__((unused)))
 {
-        write_high_res_latencies();
+       gotSIGWINCH = 1;
+}
 
-        set_enable(0);
-       set_pidexclude(getpid(), 0);
-       endwin();
-       set_rtcdec(0);
-       set_remove();
-       
-        exit(1);
+void
+print_total(FILE *fp, char *s, int total)
+{
+       int  cpu;
+       int  clen;
+       int  itotal;
+       struct i_latencies *il;
+       char tbuf[512];
+
+       for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+               itotal += il->i_total;
+       }
+       clen = sprintf(tbuf, "%s  %10d      %9d", s, total, itotal);
+
+       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+
+               if (i_latency_per_cpu == TRUE) {
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_total);
+               }
+
+               il->i_total = 0;
+       }
+       sprintf(&tbuf[clen], "\n");
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
 }
 
+
+
 void
 screen_update(FILE *fp)
 {
-        int  i;
-       int  itotal, stotal;
-       int  elapsed_secs;
-       int  elapsed_mins;
-       int  elapsed_hours;
+       int i;
+       int cpu;
+       int clen;
+       int itotal, stotal;
+       int elapsed_secs;
+       int elapsed_mins;
+       int elapsed_hours;
+       int min_lat, max_lat;
+       uint64_t tot_lat;
        unsigned int average_s_latency;
        unsigned int average_i_latency;
-       char tbuf[256];
+       struct i_latencies *il;
+       char tbuf[1024];
 
-       if (fp == (FILE *)0) {
-               erase();
+       if (fp == NULL) {
+               erase();
                move(0, 0);
-       } else
-               fprintf(fp,"\n\n===================================================================================================\n");
+       } else {
+               fprintf(fp,"\n\n===================================================================================================\n");
+       }
        /*
         *  Display the current time.
         *  "ctime" always returns a string that looks like this:
@@ -509,7 +563,13 @@ screen_update(FILE *fp)
         *
         *  We want indices 11 thru 18 (length 8).
         */
-       elapsed_secs = curr_time - start_time;
+       if (RAW_flag) {
+               curr_time = sample_TOD_secs;
+               elapsed_secs = ((last_now - first_now) / divisor) / 1000000;
+       } else {
+               elapsed_secs = curr_time - start_time;
+       }
+
        elapsed_hours = elapsed_secs / 3600;
        elapsed_secs -= elapsed_hours * 3600;
        elapsed_mins = elapsed_secs / 60;
@@ -517,232 +577,331 @@ screen_update(FILE *fp)
 
        sprintf(tbuf, "%-19.19s                            %2ld:%02ld:%02ld\n", &(ctime(&curr_time)[0]),
                (long)elapsed_hours, (long)elapsed_mins, (long)elapsed_secs);
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
-
-       if (use_high_res_bins) {
-               sprintf(tbuf, "INTERRUPTS(HIGH RESOLUTION)\n");
-
-               if (fp)
-                       fprintf(fp, "%s", tbuf);
-               else
-                       printw(tbuf);
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
        }
-    if(use_high_res_bins)
-    {
-        for(i=0;i<N_HIGH_RES_BINS;i++) {
-            if(i && !(i%10)) {
-                sprintf(tbuf,"\n");
-                if (fp)
-                    fprintf(fp, "%s", tbuf);
-                else
-                    printw(tbuf);
-            }
-#define INDEX(i) ((i%10)*50 + (i/10))
-            if(INDEX(i) <= i_highest_latency)
-                sprintf(tbuf,"[%3d]: %6d ", INDEX(i), i_high_res_bins[INDEX(i)]);
-            else
-                tbuf[0] = '\0';
-
-            if (fp)
-                fprintf(fp, "%s", tbuf);
-            else
-                printw(tbuf);
-        }
-        sprintf(tbuf,"\n\n");
-        if (fp)
-            fprintf(fp, "%s", tbuf);
-        else
-            printw(tbuf);
-    }
 
        sprintf(tbuf, "                     SCHEDULER     INTERRUPTS\n");
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
-
-       sprintf(tbuf, "---------------------------------------------\n");
-
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       if (i_latency_per_cpu == TRUE) {
+               clen = sprintf(tbuf, "                                        Total");
 
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       if (cpu <= 9) {
+                               clen += sprintf(&tbuf[clen], "     CPU %d", cpu);
+                       } else {
+                               clen += sprintf(&tbuf[clen], "    CPU %d", cpu);
+                       }
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
 
+               clen = sprintf(tbuf, "\n-------------------------------------------------------");
 
-       sprintf(tbuf, "total_samples       %10d     %10d\n\n", s_total_samples, i_total_samples);
+               for (cpu = 1; cpu < num_i_latency_cpus; cpu++) {
+                       clen += sprintf(&tbuf[clen], "----------");
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
+       } else {
+               sprintf(tbuf, "---------------------------------------------");
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
+       }
+       for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+               itotal += il->i_total_samples;
+       }
+       clen = sprintf(tbuf, "\ntotal_samples       %10d      %9d", s_total_samples, itotal);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
 
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_total_samples);
+               }
+       }
+       sprintf(&tbuf[clen], "\n");
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
 
 
-       for (itotal = 0, stotal = 0, i = 0; i < 10; i++) {
-               sprintf(tbuf, "delays < %3d usecs  %10d     %10d\n", (i + 1) * 10, s_usec_10_bins[i], i_usec_10_bins[i]);
+       for (stotal = 0, i = 0; i < 10; i++) {
+               for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
 
-               if (fp)
-                       fprintf(fp, "%s", tbuf);
-               else
-                       printw(tbuf);
+                       itotal += il->i_usec_10_bins[i];
+                       il->i_total += il->i_usec_10_bins[i];
+               }
+               clen = sprintf(tbuf, "\ndelays < %3d usecs  %10d      %9d", (i + 1) * 10, s_usec_10_bins[i], itotal);
 
                stotal += s_usec_10_bins[i];
-               itotal += i_usec_10_bins[i];
-       }
-       sprintf(tbuf, "total  < 100 usecs  %10d     %10d\n\n", stotal, itotal);
-
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
-
 
+               if (i_latency_per_cpu == TRUE) {
+                       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                               il = &i_lat[cpu];
+                               
+                               clen += sprintf(&tbuf[clen], " %9d", il->i_usec_10_bins[i]);
+                       }
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
+       }
+       print_total(fp, "\ntotal  < 100 usecs", stotal);
 
-       for (itotal = 0, stotal = 0, i = 1; i < 10; i++) {
-               if (i < 9)
-                       sprintf(tbuf, "delays < %3d usecs  %10d     %10d\n", (i + 1) * 100, s_usec_100_bins[i], i_usec_100_bins[i]);
-               else
-                       sprintf(tbuf, "delays <   1 msec   %10d     %10d\n", s_usec_100_bins[i], i_usec_100_bins[i]);
+       for (stotal = 0, i = 1; i < 10; i++) {
+               for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
 
-               if (fp)
-                       fprintf(fp, "%s", tbuf);
-               else
-                       printw(tbuf);
+                       itotal += il->i_usec_100_bins[i];
+                       il->i_total += il->i_usec_100_bins[i];
+               }
+               if (i < 9) {
+                       clen = sprintf(tbuf, "\ndelays < %3d usecs  %10d      %9d", (i + 1) * 100, s_usec_100_bins[i], itotal);
+               } else {
+                       clen = sprintf(tbuf, "\ndelays <   1 msec   %10d      %9d", s_usec_100_bins[i], itotal);
+               }
 
                stotal += s_usec_100_bins[i];
-               itotal += i_usec_100_bins[i];
-       }
-       sprintf(tbuf, "total  <   1 msec   %10d     %10d\n\n", stotal, itotal);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+               if (i_latency_per_cpu == TRUE) {
+                       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                               il = &i_lat[cpu];
 
+                               clen += sprintf(&tbuf[clen], " %9d", il->i_usec_100_bins[i]);
+                       }
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
+       }
+       print_total(fp, "\ntotal  <   1 msec ", stotal);
 
 
-       for (itotal = 0, stotal = 0, i = 1; i < 10; i++) {
-               sprintf(tbuf, "delays < %3d msecs  %10d     %10d\n", (i + 1), s_msec_1_bins[i], i_msec_1_bins[i]);
+       for (stotal = 0, i = 1; i < 10; i++) {
+               for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
 
-               if (fp)
-                       fprintf(fp, "%s", tbuf);
-               else
-                       printw(tbuf);
+                       itotal += il->i_msec_1_bins[i];
+                       il->i_total += il->i_msec_1_bins[i];
+               }
+               clen = sprintf(tbuf, "\ndelays < %3d msecs  %10d      %9d", (i + 1), s_msec_1_bins[i], itotal);
 
                stotal += s_msec_1_bins[i];
-               itotal += i_msec_1_bins[i];
-       }
-       sprintf(tbuf, "total  <  10 msecs  %10d     %10d\n\n", stotal, itotal);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+               if (i_latency_per_cpu == TRUE) {
+                       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                               il = &i_lat[cpu];
 
+                               clen += sprintf(&tbuf[clen], " %9d", il->i_msec_1_bins[i]);
+                       }
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
+       }
+       print_total(fp, "\ntotal  <  10 msecs", stotal);
 
+       for (stotal = 0, i = 1; i < 5; i++) {
+               for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
 
+                       itotal += il->i_msec_10_bins[i];
+                       il->i_total += il->i_msec_10_bins[i];
+               }
+               clen = sprintf(tbuf, "\ndelays < %3d msecs  %10d      %9d", (i + 1)*10, s_msec_10_bins[i], itotal);
 
-       for (itotal = 0, stotal = 0, i = 1; i < 5; i++) {
-               sprintf(tbuf, "delays < %3d msecs  %10d     %10d\n", (i + 1)*10, s_msec_10_bins[i], i_msec_10_bins[i]);
+               stotal += s_msec_10_bins[i];
 
-               if (fp)
-                       fprintf(fp, "%s", tbuf);
-               else
-                       printw(tbuf);
+               if (i_latency_per_cpu == TRUE) {
+                       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                               il = &i_lat[cpu];
 
-               stotal += s_msec_10_bins[i];
-               itotal += i_msec_10_bins[i];
+                               clen += sprintf(&tbuf[clen], " %9d", il->i_msec_10_bins[i]);
+                       }
+               }
+               if (fp) {
+                       fprintf(fp, "%s", tbuf);
+               } else {
+                       printw(tbuf);
+               }
        }
-       sprintf(tbuf, "total  <  50 msecs  %10d     %10d\n\n", stotal, itotal);
-
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       print_total(fp, "\ntotal  <  50 msecs", stotal);
 
-       sprintf(tbuf, "delays >  50 msecs  %10d     %10d\n", s_too_slow, i_too_slow);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+               itotal += il->i_too_slow;
+       }
+       clen = sprintf(tbuf, "\ndelays >  50 msecs  %10d      %9d", s_too_slow, itotal);
 
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
+               
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_too_slow);
+               }
+       }
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
 
+       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
 
-       sprintf(tbuf, "\nminimum latency(usecs) %7d        %7d\n", s_min_latency, i_min_latency);
+               if (cpu == 0 || (il->i_min_latency < min_lat)) {
+                       min_lat = il->i_min_latency;
+               }
+       }
+       clen = sprintf(tbuf, "\n\nminimum latency(usecs) %7d      %9d", s_min_latency, min_lat);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
+               
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_min_latency);
+               }
+       }
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
 
-       sprintf(tbuf, "maximum latency(usecs) %7d        %7d\n", s_max_latency, i_max_latency);
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
 
-       if (s_total_samples)
-         average_s_latency = (unsigned int)(s_total_latency/s_total_samples);
-       else
-         average_s_latency = 0;
+               if (cpu == 0 || (il->i_max_latency > max_lat)) {
+                       max_lat = il->i_max_latency;
+               }
+       }
+       clen = sprintf(tbuf, "\nmaximum latency(usecs) %7d      %9d", s_max_latency, max_lat);
 
-       if (i_total_samples)
-         average_i_latency = (unsigned int)(i_total_latency/i_total_samples);
-       else
-         average_i_latency = 0;
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
+               
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_max_latency);
+               }
+       }
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
+       
+       if (s_total_samples) {
+               average_s_latency = (unsigned int)(s_total_latency/s_total_samples);
+       } else {
+               average_s_latency = 0;
+       }
 
-       sprintf(tbuf, "average latency(usecs) %7d        %7d\n", average_s_latency, average_i_latency);
+       for (itotal = 0, tot_lat = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+               
+               itotal += il->i_total_samples;
+               tot_lat += il->i_total_latency;
+       }
+       if (itotal) {
+               average_i_latency = (unsigned)(tot_lat/itotal);
+       } else {
+               average_i_latency = 0;
+       }
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+       clen = sprintf(tbuf, "\naverage latency(usecs) %7d      %9d", average_s_latency, average_i_latency);
 
-       sprintf(tbuf, "exceeded threshold     %7d        %7d\n", s_exceeded_threshold, i_exceeded_threshold);
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
+               
+                       if (il->i_total_samples) {
+                               average_i_latency = (unsigned int)(il->i_total_latency/il->i_total_samples);
+                       } else {
+                               average_i_latency = 0;
+                       }
 
-       if (fp)
-               fprintf(fp, "%s", tbuf);
-       else
-               printw(tbuf);
+                       clen += sprintf(&tbuf[clen], " %9d", average_i_latency);
+               }
+       }
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }
+       
+       for (itotal = 0, cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+               il = &i_lat[cpu];
+               
+               itotal += il->i_exceeded_threshold;
+       }
+       clen = sprintf(tbuf, "\nexceeded threshold     %7d      %9d", s_exceeded_threshold, itotal);
 
-       if (fp == (FILE *)0)
-               refresh();
-       else
-               fflush(fp);
+       if (i_latency_per_cpu == TRUE) {
+               for (cpu = 0; cpu < num_i_latency_cpus; cpu++) {
+                       il = &i_lat[cpu];
+               
+                       clen += sprintf(&tbuf[clen], " %9d", il->i_exceeded_threshold);
+               }
+       }
+       sprintf(&tbuf[clen], "\n");
+
+       if (fp) {
+               fprintf(fp, "%s", tbuf);
+       } else {
+               printw(tbuf);
+       }       
+
+       if (fp == NULL) {
+               refresh();
+       } else {
+               fflush(fp);
+       }
 }
 
 int
-exit_usage()
+exit_usage(void)
 {
-
-        fprintf(stderr, "Usage: latency [-rt] [-h] [-c codefile] [-l logfile] [-st threshold]\n");
-
-#if defined (__i386__)
-       fprintf(stderr, "               [-it threshold] [-s sleep_in_usecs] [-n kernel]\n\n");  
-#else
-       fprintf(stderr, "               [-it threshold] [-s sleep_in_usecs]\n");        
-       fprintf(stderr, "               [-d decrementer_in_usecs] [-n kernel]\n\n");
-#endif
-
-
-       fprintf(stderr, "  -rt   Set realtime scheduling policy.  Default is timeshare.\n");
+       fprintf(stderr, "Usage: latency [-p priority] [-h] [-m] [-st threshold] [-it threshold]\n");
+       fprintf(stderr, "               [-c codefile] [-l logfile] [-R rawfile] [-n kernel]\n\n");
+       fprintf(stderr, "  -p    specify scheduling priority to watch... default is realtime\n");
        fprintf(stderr, "  -h    Display high resolution interrupt latencies and write them to latencies.csv (truncate existing file) upon exit.\n");
-       fprintf(stderr, "  -c    specify name of codes file\n");
-       fprintf(stderr, "  -l    specify name of file to log trace entries to when threshold is exceeded\n");
        fprintf(stderr, "  -st   set scheduler latency threshold in microseconds... if latency exceeds this, then log trace\n");
+       fprintf(stderr, "  -m    specify per-CPU interrupt latency reporting\n");       
        fprintf(stderr, "  -it   set interrupt latency threshold in microseconds... if latency exceeds this, then log trace\n");
-       fprintf(stderr, "  -s    set sleep time in microseconds\n");
-#if !defined (__i386__)        
-       fprintf(stderr, "  -d    set decrementer in microseconds.\n");
-#endif
-       fprintf(stderr, "  -n    specify kernel, default is /mach_kernel\n");   
+       fprintf(stderr, "  -c    specify name of codes file... default is /usr/share/misc/trace.codes\n");
+       fprintf(stderr, "  -l    specify name of file to log trace entries to when the specified threshold is exceeded\n");
+       fprintf(stderr, "  -R    specify name of raw trace file to process\n");
+       fprintf(stderr, "  -n    specify kernel... default is /mach_kernel\n"); 
 
        fprintf(stderr, "\nlatency must be run as root\n\n");
 
@@ -753,1399 +912,1629 @@ exit_usage()
 int
 main(int argc, char *argv[])
 {
-       uint64_t start, stop;
-       uint64_t timestamp1;
-       uint64_t timestamp2;
-       uint64_t adeadline, adelay;
-       double fdelay;
-       int      elapsed_usecs;
-       double   nanosecs_to_sleep;
-       int      loop_cnt, sample_sc_now;
-       int      decrementer_usec = 0;
-        kern_return_t           ret;
-        unsigned int            size;
-        host_name_port_t        host;
-       void     getdivisor();
-       void     sample_sc();
-       void     init_code_file();
-       void     do_kernel_nm();
-       void     open_logfile();
-
        if (0 != reexec_to_match_kernel()) {
                fprintf(stderr, "Could not re-execute: %d\n", errno);
                exit(1);
        }
+       while (argc > 1) {
 
-       my_policy = THREAD_STANDARD_POLICY;
-       policy_name = "TIMESHARE";
+               if (strcmp(argv[1], "-R") == 0) {
+                       argc--;
+                       argv++;
 
-       while (argc > 1) {
-               if (strcmp(argv[1], "-rt") == 0) {
-                       my_policy = THREAD_TIME_CONSTRAINT_POLICY;   /* the real time band */
-                       policy_name = "REALTIME";
+                       if (argc > 1) {
+                               open_rawfile(argv[1]);
+                       } else {
+                               exit_usage();
+                       }
 
+                       RAW_flag = 1;
+
+               } else if (strcmp(argv[1], "-p") == 0) {
+                       argc--;
+                       argv++;
+
+                       if (argc > 1) {
+                               watch_priority = atoi(argv[1]);
+                       } else {
+                               exit_usage();
+                       }
                } else if (strcmp(argv[1], "-st") == 0) {
                        argc--;
                        argv++;
 
-                       if (argc > 1)
-                         s_thresh_hold = atoi(argv[1]);
-                       else
-                         exit_usage();
-                       
+                       if (argc > 1) {
+                               s_thresh_hold = atoi(argv[1]);
+                       } else {
+                               exit_usage();
+                       }
                } else if (strcmp(argv[1], "-it") == 0) {
                        argc--;
                        argv++;
                        
-                       if (argc > 1)
-                         i_thresh_hold = atoi(argv[1]);
-                       else
-                         exit_usage();
+                       if (argc > 1) {
+                               i_thresh_hold = atoi(argv[1]);
+                       } else {
+                               exit_usage();
+                       }
                } else if (strcmp(argv[1], "-c") == 0) {
                        argc--;
                        argv++;
                        
-                       if (argc > 1)
-                         code_file = argv[1];
-                       else
-                         exit_usage();
+                       if (argc > 1) {
+                               code_file = argv[1];
+                       } else {
+                               exit_usage();
+                       }
                } else if (strcmp(argv[1], "-l") == 0) {
                        argc--;
                        argv++;
                        
-                       if (argc > 1)
-                         open_logfile(argv[1]);
-                       else
-                         exit_usage();
-
-               } else if (strcmp(argv[1], "-s") == 0) {
+                       if (argc > 1) {
+                               open_logfile(argv[1]);
+                       } else {
+                               exit_usage();
+                       }
+               } else if (strcmp(argv[1], "-n") == 0) {
                        argc--;
                        argv++;
 
-                       if (argc > 1)
-                         num_of_usecs_to_sleep = atoi(argv[1]);
-                       else
-                         exit_usage();
-               }
-               else if (strcmp(argv[1], "-d") == 0) {
-                       argc--;
-                       argv++;
+                       if (argc > 1) {
+                               kernelpath = argv[1];
+                       } else {
+                               exit_usage();
+                       }
+               } else if (strcmp(argv[1], "-h") == 0) {
+                       use_high_res_bins = TRUE;
 
-                       if (argc > 1)
-                         decrementer_usec = atoi(argv[1]);
-                       else
-                         exit_usage();
-#if defined(__i386__)
-                       /* ignore this option - setting the decrementer has no effect */
-                       decrementer_usec = 0;
-#endif                 
-               }
-               else if (strcmp(argv[1], "-n") == 0) {
-                       argc--;
-                       argv++;
+               } else if (strcmp(argv[1], "-m") == 0) {
+                       i_latency_per_cpu = TRUE;
 
-                       if (argc > 1)
-                         kernelpath = argv[1];
-                       else
-                         exit_usage();
-               } else if (strcmp(argv[1], "-h") == 0) {
-            use_high_res_bins = true;
-               } else
+               } else {
                        exit_usage();
+               }
 
                argc--;
                argv++;
        }
+       if (!RAW_flag) {
+               if (geteuid() != 0) {
+                       printf("'latency' must be run as root...\n");
+                       exit(1);
+               }
+       }
+       if (kernelpath == NULL) {
+               kernelpath = "/mach_kernel";
+       }
 
-        if ( geteuid() != 0 ) {
-         printf("'latency' must be run as root...\n");
-         exit(1);
-        }
-
-       if (kernelpath == (char *) 0)
-         kernelpath = "/mach_kernel";
-
-       if (code_file == (char *) 0)
-          code_file = "/usr/share/misc/trace.codes";
+       if (code_file == NULL) {
+               code_file = "/usr/share/misc/trace.codes";
+       }
 
        do_kernel_nm();
 
-       sample_sc_now = 25000 / num_of_usecs_to_sleep;
-
        getdivisor();
-       decrementer_val = decrementer_usec * divisor;
-
-       /* get the cpu countfor the DECR_TRAP array */
-        host = mach_host_self();
-       size = sizeof(hi)/sizeof(int);
-        ret = host_info(host, HOST_BASIC_INFO, (host_info_t)&hi, &size);
-        if (ret != KERN_SUCCESS) {
-            mach_error(argv[0], ret);
-            exit(EXIT_FAILURE);
-       }
-
-       if ((last_decrementer_kd = (kd_buf **)malloc(hi.max_cpus * sizeof(kd_buf *))) == (kd_buf **)0)
-               quit("can't allocate memory for decrementer tracing info\n");
-
-       nanosecs_to_sleep = (double)(num_of_usecs_to_sleep * 1000);
-       fdelay = nanosecs_to_sleep * (divisor /1000);
-       adelay = (uint64_t)fdelay;
 
        init_code_file();
 
-       /* 
-          When the decrementer isn't set in the options,
-          decval will be zero and this call will reset
-          the system default ...
-       */
-       set_rtcdec(decrementer_val);
-
-       if (initscr() == (WINDOW *) 0)
-         {
-           printf("Unrecognized TERM type, try vt100\n");
-           exit(1);
-         }
-
-       clear();
-       refresh();
-       signal(SIGWINCH, sigwinch);
-       signal(SIGINT, sigintr);
-       signal(SIGQUIT, leave);
-       signal(SIGTERM, leave);
-       signal(SIGHUP, leave);
-
-
-       if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
-               quit("can't allocate memory for tracing info\n");
-       set_remove();
-       set_numbufs(SAMPLE_SIZE);
-       set_enable(0);
-       if(log_fp)
-         set_init_logging();
-       else
-         set_init_nologging();
-       set_pidexclude(getpid(), 1);
-       set_enable(1);
-       trace_enabled = 1;
-       need_new_map = 1;
-
-       loop_cnt = 0;
-       start_time = time((long *)0);
-       refresh_time = start_time;
-
-       if (my_policy == THREAD_TIME_CONSTRAINT_POLICY)
-         {
-           /* the realtime band */
-           if(set_time_constraint_policy() != KERN_SUCCESS)
-             quit("Failed to set realtime policy.\n");
-         }
-
-       for (;;) {
-               curr_time = time((long *)0);
-
-               if (curr_time >= refresh_time) {
-                      if (my_policy == THREAD_TIME_CONSTRAINT_POLICY)
-                      {
-                         /* set standard timeshare policy during screen update */
-                         if(set_standard_policy() != KERN_SUCCESS)
-                           quit("Failed to set standard policy.\n");
-                       }
-                       screen_update((FILE *)0);
-                       if (my_policy == THREAD_TIME_CONSTRAINT_POLICY)
-                       {
-                         /* set back to realtime band */
-                         if(set_time_constraint_policy() != KERN_SUCCESS)
-                           quit("Failed to set time_constraint policy.\n");
-                       }
-                       refresh_time = curr_time + 1;
-               }
-
-               timestamp1 = mach_absolute_time();
-               adeadline = timestamp1 + adelay;
-               mach_wait_until(adeadline);
-               timestamp2 = mach_absolute_time();
-
-               start = timestamp1;
-
-               stop = timestamp2;
-
-               elapsed_usecs = (int)(((double)(stop - start)) / divisor);
-
-               if ((elapsed_usecs -= num_of_usecs_to_sleep) <= 0)
-                       continue;
-
-               if (elapsed_usecs < 100)
-                       s_usec_10_bins[elapsed_usecs/10]++;
-               if (elapsed_usecs < 1000)
-                       s_usec_100_bins[elapsed_usecs/100]++;
-               else if (elapsed_usecs < 10000)
-                       s_msec_1_bins[elapsed_usecs/1000]++;
-               else if (elapsed_usecs < 50000)
-                       s_msec_10_bins[elapsed_usecs/10000]++;
-               else 
-                       s_too_slow++;
-
-               if (elapsed_usecs > s_max_latency)
-                       s_max_latency = elapsed_usecs;
-               if (elapsed_usecs < s_min_latency || s_total_samples == 0)
-                       s_min_latency = elapsed_usecs;
-               s_total_latency += elapsed_usecs;
-               s_total_samples++;
-
-               if (s_thresh_hold && elapsed_usecs > s_thresh_hold)
-                       s_exceeded_threshold++;
-               loop_cnt++;
-
-               if (log_fp && s_thresh_hold && elapsed_usecs > s_thresh_hold)
-                       sample_sc(start, stop);
-               else {
-                       if (loop_cnt >= sample_sc_now) {
-                               sample_sc((long long)0, (long long)0);
-                               loop_cnt = 0;
-                       }
+       if (!RAW_flag) {
+               if (initscr() == NULL) {
+                       printf("Unrecognized TERM type, try vt100\n");
+                       exit(1);
                }
-               if (gotSIGWINCH) {
-                       /*
-                         No need to check for initscr error return.
-                         We won't get here if it fails on the first call.
-                       */
-                       endwin();
-                       clear();
-                       refresh();
+               clear();
+               refresh();
 
-                       gotSIGWINCH = 0;
-               }
-       }
-}
+               signal(SIGWINCH, sigwinch);
+               signal(SIGINT, sigintr);
+               signal(SIGQUIT, leave);
+               signal(SIGTERM, leave);
+               signal(SIGHUP, leave);
 
+               /*
+                * grab the number of cpus and scale the buffer size
+                */
+               int mib[] = { CTL_HW, HW_NCPU };
+               size_t len = sizeof(num_cpus);
 
-void getdivisor()
-{
-  mach_timebase_info_data_t info;
+               sysctl(mib, ARRAYSIZE(mib), &num_cpus, &len, NULL, 0);
 
-  (void) mach_timebase_info (&info);
+               set_remove();
+               set_numbufs(SAMPLE_SIZE * num_cpus);
 
-  divisor = ( (double)info.denom / (double)info.numer) * 1000;
+               get_bufinfo(&bufinfo);
 
-}
+               set_enable(0);
 
-/* This is the realtime band */
-static kern_return_t
-set_time_constraint_policy()
-{
-       kern_return_t                           result;
-       thread_time_constraint_policy_data_t    info;
-       mach_msg_type_number_t                  count;  
-       boolean_t                               get_default;
-
-       get_default = TRUE;
-       count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;
-       result = thread_policy_get(mach_thread_self(), THREAD_TIME_CONSTRAINT_POLICY,
-                                  (thread_policy_t)&info, &count, &get_default);
-       if (result != KERN_SUCCESS)
-               return (result);
-
-       result = thread_policy_set(mach_thread_self(),  THREAD_TIME_CONSTRAINT_POLICY,
-                                  (thread_policy_t)&info, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
-
-       return (result);
-}
+               set_pidexclude(getpid(), 1);
+               set_enable(1);
 
-/* This is the timeshare mode */
-static kern_return_t
-set_standard_policy()
-{
-       kern_return_t                   result;
-       thread_standard_policy_data_t   info;
-       mach_msg_type_number_t          count;  
-       boolean_t                       get_default;
-
-       get_default = TRUE;
-       count = THREAD_STANDARD_POLICY_COUNT;
-       result = thread_policy_get(mach_thread_self(), THREAD_STANDARD_POLICY,
-                                  (thread_policy_t)&info, &count, &get_default);
-       if (result != KERN_SUCCESS)
-               return (result);
-
-       result = thread_policy_set(mach_thread_self(),  THREAD_STANDARD_POLICY,
-                                  (thread_policy_t)&info, THREAD_STANDARD_POLICY_COUNT);
-
-       return (result);
-}
+               num_entries = bufinfo.nkdbufs;
+       } else {
+               num_entries = 50000;
+               num_cpus    = 128;
+       }
 
-                                                                                                 
-void read_command_map()
-{
-    size_t size;
-    int mib[6];
-  
-    if (mapptr) {
-       free(mapptr);
-       mapptr = 0;
-    }
-    total_threads = bufinfo.nkdthreads;
-    size = bufinfo.nkdthreads * sizeof(kd_threadmap);
-    if (size)
-    {
-        if ((mapptr = (kd_threadmap *) malloc(size)))
-            bzero (mapptr, size);
-       else
-       {
-           printf("Thread map is not initialized -- this is not fatal\n");
-           return;
-       }
-    }
-    /* Now read the threadmap */
-    mib[0] = CTL_KERN;
-    mib[1] = KERN_KDEBUG;
-    mib[2] = KERN_KDTHRMAP;
-    mib[3] = 0;
-    mib[4] = 0;
-    mib[5] = 0;                /* no flags */
-    if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
-    {
-        /* This is not fatal -- just means I cant map command strings */
-
-        printf("Can't read the thread map -- this is not fatal\n");
-       free(mapptr);
-       mapptr = 0;
-       return;
-    }
-    return;
-}
+       if ((my_buffer = malloc(num_entries * sizeof(kd_buf))) == NULL) {
+               quit("can't allocate memory for tracing info\n");
+       }
 
+       if ((last_decrementer_kd = (kd_buf **)malloc(num_cpus * sizeof(kd_buf *))) == NULL) {
+               quit("can't allocate memory for decrementer tracing info\n");
+       }
 
-void create_map_entry(uintptr_t thread, char *command)
-{
-    int i, n;
-    kd_threadmap *map;
-
-    if (!mapptr)
-        return;
-
-    for (i = 0, map = 0; !map && i < total_threads; i++)
-    {
-        if (mapptr[i].thread == thread )       
-           map = &mapptr[i];   /* Reuse this entry, the thread has been reassigned */
-    }
-
-    if (!map)   /* look for invalid entries that I can reuse*/
-    {
-        for (i = 0, map = 0; !map && i < total_threads; i++)
-       {
-           if (mapptr[i].valid == 0 )  
-               map = &mapptr[i];   /* Reuse this invalid entry */
-       }
-    }
-  
-    if (!map)
-    {
-        /* If reach here, then this is a new thread and 
-        * there are no invalid entries to reuse
-        * Double the size of the thread map table.
-        */
+       if (i_latency_per_cpu == FALSE) {
+               num_i_latency_cpus = 1;
+       } else {
+               num_i_latency_cpus = num_cpus;
+       }
 
-        n = total_threads * 2;
-       mapptr = (kd_threadmap *) realloc(mapptr, n * sizeof(kd_threadmap));
-       bzero(&mapptr[total_threads], total_threads*sizeof(kd_threadmap));
-       map = &mapptr[total_threads];
-       total_threads = n;
-#if 0
-       if (log_fp)
-         fprintf(log_fp, "MAP: increasing thread map to %d entries\n", total_threads);
-#endif
-    }
-#if 0
-    if (log_fp)
-      fprintf(log_fp, "MAP: adding thread %x with name %s\n", thread, command);
-#endif
-    map->valid = 1;
-    map->thread = thread;
-    /*
-      The trace entry that returns the command name will hold
-      at most, MAXCOMLEN chars, and in that case, is not
-      guaranteed to be null terminated.
-    */
-    (void)strncpy (map->command, command, MAXCOMLEN);
-    map->command[MAXCOMLEN] = '\0';
-}
+       if ((i_lat = (struct i_latencies *)malloc(num_i_latency_cpus * sizeof(struct i_latencies))) == NULL) {
+               quit("can't allocate memory for interrupt latency info\n");
+       }
 
+       bzero((char *)i_lat, num_i_latency_cpus * sizeof(struct i_latencies));
 
-kd_threadmap *find_thread_map(uintptr_t thread)
-{
-    int i;
-    kd_threadmap *map;
+       if (RAW_flag) {
+               while (sample_sc()) {
+                       continue;
+               }
 
-    if (!mapptr)
-        return((kd_threadmap *)0);
+               if (log_fp) {
+                       screen_update(log_fp);
+               }
 
-    for (i = 0; i < total_threads; i++)
-    {
-        map = &mapptr[i];
-       if (map->valid && (map->thread == thread))
-       {
-           return(map);
-       }
-    }
-    return ((kd_threadmap *)0);
-}
+               screen_update(stdout);
 
-void
-kill_thread_map(uintptr_t thread)
-{
-    kd_threadmap *map;
+       } else {
+               uint64_t adelay;
+               double  fdelay;
+               double  nanosecs_to_sleep;
 
-    if ((map = find_thread_map(thread))) {
+               nanosecs_to_sleep = (double)(SAMPLE_TIME_USECS * 1000);
+               fdelay = nanosecs_to_sleep * (divisor /1000);
+               adelay = (uint64_t)fdelay;
 
-#if 0
-      if (log_fp)
-        fprintf(log_fp, "MAP: deleting thread %x with name %s\n", thread, map->command);
-#endif
-        map->valid = 0;
-       map->thread = 0;
-       map->command[0] = '\0';
-    }
-}
+               trace_enabled = 1;
 
+               start_time = time(NULL);
+               refresh_time = start_time;
 
-struct th_info *find_thread(uintptr_t thread, int type1, int type2) {
-       struct th_info *ti;
+               for (;;) {
+                       curr_time = time(NULL);
 
-       for (ti = th_state; ti < &th_state[cur_max]; ti++) {
-              if (ti->thread == thread) {
-                      if (type1 == 0)
-                              return(ti);
-                      if (type1 == ti->type)
-                              return(ti);
-                      if (type2 == ti->type)
-                              return(ti);
-              }
-       }
-       return ((struct th_info *)0);
-}
+                       if (curr_time >= refresh_time) {
+                               screen_update(NULL);
+                               refresh_time = curr_time + 1;
+                       }
+                       mach_wait_until(mach_absolute_time() + adelay);
 
+                       sample_sc();
 
-char *find_code(type)
-{
-        int i;
+                       if (gotSIGWINCH) {
+                               /*
+                                * No need to check for initscr error return.
+                                * We won't get here if it fails on the first call.
+                                */
+                               endwin();
+                               clear();
+                               refresh();
 
-       for (i = 0; i < num_of_codes; i++) {
-               if (codes_tab[i].type == type)
-                       return(codes_tab[i].name);
+                               gotSIGWINCH = 0;
+                       }
+               }
        }
-       return ((char *)0);
 }
 
 
-void sample_sc(uint64_t start, uint64_t stop)
+                                                                                                 
+void
+read_command_map(void)
 {
-       kd_buf   *kd, *last_mach_sched, *start_kd, *end_of_sample;
-       uint64_t now;
-       int count, i;
-       int first_entry = 1;
-       double timestamp = 0.0;
-       double last_timestamp = 0.0;
-       double delta = 0.0;
-       double start_bias = 0.0;        
-       char   command[32];
-       void read_command_map();
-
-       if (log_fp && (my_policy == THREAD_TIME_CONSTRAINT_POLICY))
-         {
-           /* set standard timeshare policy when logging */
-           if(set_standard_policy() != KERN_SUCCESS)
-             quit("Failed to set standard policy.\n");
-         }
-
-        /* Get kernel buffer information */
-       get_bufinfo(&bufinfo);
-
-       if (need_new_map) {
-               read_command_map();
-               need_new_map = 0;
-       }
-       needed = bufinfo.nkdbufs * sizeof(kd_buf);
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_KDEBUG;
-       mib[2] = KERN_KDREADTR;         
-       mib[3] = 0;
-       mib[4] = 0;
-       mib[5] = 0;             /* no flags */
-
-       if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0)
-               quit("trace facility failure, KERN_KDREADTR\n");
-
-       count = needed;
-
-       if (bufinfo.flags & KDBG_WRAPPED) {
-               for (i = 0; i < cur_max; i++) {
-                       th_state[i].thread = 0;
-                       th_state[i].type = -1;
-                       th_state[i].pathptr = (long *)NULL;
-                       th_state[i].pathname[0] = 0;
+       kd_threadmap *mapptr = 0;
+       int     total_threads = 0;
+       size_t  size;
+       off_t   offset;
+       int     i;
+       RAW_header header = {0};
+
+       if (RAW_flag) {
+                if (read(RAW_fd, &header, sizeof(RAW_header)) != sizeof(RAW_header)) {
+                        perror("read failed");
+                       exit(2);
+                }
+               if (header.version_no != RAW_VERSION1) {
+                       header.version_no = RAW_VERSION0;
+                       header.TOD_secs = time(NULL);
+                       header.TOD_usecs = 0;
+
+                       lseek(RAW_fd, (off_t)0, SEEK_SET);
+
+                       if (read(RAW_fd, &header.thread_count, sizeof(int)) != sizeof(int)) {
+                               perror("read failed");
+                               exit(2);
+                       }
                }
-               cur_max = 0;
-               need_new_map = 1;
+                total_threads = header.thread_count;
                
-               set_enable(0);
-               set_enable(1);
-
-               if (log_fp) {
-                       double latency;
+               sample_TOD_secs = header.TOD_secs;
+               sample_TOD_usecs = header.TOD_usecs;
 
-                       latency = (double)(stop - start) / divisor;
-                       latency -= (double)num_of_usecs_to_sleep;
+               if (total_threads == 0 && header.version_no != RAW_VERSION0) {
+                       offset = lseek(RAW_fd, (off_t)0, SEEK_CUR);
+                       offset = (offset + (4095)) & ~4095;
 
-                       fprintf(log_fp, "\n\n%-19.19s   scheduling latency = %.1fus  num_of_traces = %d <<<<<<< trace buffer wrapped >>>>>>>\n\n",
-                               &(ctime(&curr_time)[0]), latency, count);
+                       lseek(RAW_fd, offset, SEEK_SET);
                }
+       } else {
+               total_threads = bufinfo.nkdthreads;
        }
-       end_of_sample = &((kd_buf *)my_buffer)[count];
-
-       /* Always reinitialize the DECR_TRAP array */
-       for (i=0; i < hi.max_cpus; i++)
-             last_decrementer_kd[i] = (kd_buf *)my_buffer;
-
-       last_mach_sched = (kd_buf *)0;
-
-       for (kd = (kd_buf *)my_buffer; kd < end_of_sample; kd++) {
-               int debugid, thread, cpunum;
-               int type, clen, mode;
-               int len;
-               char *p;
-               long *sargptr;
-               kd_buf *cur_kd;
-               double i_latency = 0.0;
-               struct th_info *ti;
-               char   command1[32];
-               char   sched_info[64];
-               kd_threadmap *map;
-               kd_threadmap *find_thread_map();
-               double handle_decrementer();
-               kd_buf *log_decrementer();
-               int check_for_thread_update();
-               void enter_syscall();
-               void exit_syscall();
-               void print_entry();
-
-               thread  = kd->arg5;
-               cpunum  = CPU_NUMBER(kd);
-               debugid = kd->debugid;
-               type    = kd->debugid & DBG_FUNC_MASK;
-
-               if (check_for_thread_update(thread, type, kd))
-                       continue;
-
-               if (type == DECR_TRAP)
-                       i_latency = handle_decrementer(kd);
-
-               now = kd->timestamp & KDBG_TIMESTAMP_MASK;
+               
+       size = total_threads * sizeof(kd_threadmap);
 
-               timestamp = ((double)now) / divisor;
-
-               if (now < start || now > stop) {
-                       if (debugid & DBG_FUNC_START)
-                               enter_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 0);
-                       else if (debugid & DBG_FUNC_END)
-                               exit_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 0);
-                       else if (type == DECR_TRAP) {
-                               cur_kd = kd;
-                               if (log_fp && i_thresh_hold && (int)i_latency > i_thresh_hold) {
-                                       start_kd = last_decrementer_kd[cpunum];
-                                       kd = log_decrementer(start_kd, kd, end_of_sample, i_latency);
-                                       if (kd >= end_of_sample)
-                                               break;
-                               }
-                               if ((kd->debugid & DBG_FUNC_MASK) == DECR_TRAP)
-                                 {
-                                   cpunum = CPU_NUMBER(kd);
-                                   last_decrementer_kd[cpunum] = kd;
-                                 }
-                               else
-                                 last_decrementer_kd[cpunum] = cur_kd;
-                       }
-                       continue;
+       if (size == 0 || ((mapptr = (kd_threadmap *) malloc(size)) == 0)) {
+               return;
+       }
+       bzero (mapptr, size);
+       /*
+        * Now read the threadmap
+        */
+       if (RAW_flag) {
+               if (read(RAW_fd, mapptr, size) != size) {
+                       printf("Can't read the thread map -- this is not fatal\n");
                }
-               if (first_entry) {
-                       double latency;
-                       char buf1[132];
-                       char buf2[132];
-
-                       latency = (double)(stop - start) / divisor;
-                       latency -= (double)num_of_usecs_to_sleep;
-
-                       if (my_pri == -1)
-                               sprintf(buf2, "default");
-                       else
-                               sprintf(buf2, "%d", my_pri);
-                       sprintf(buf1, "%-19.19s     scheduling latency = %.1fus    sleep_request = %dus     policy = %s     priority = %s",
-                               &(ctime(&curr_time)[0]), latency, num_of_usecs_to_sleep, policy_name, buf2);
-                       clen = strlen(buf1);
-                       memset(buf2, '-', clen);
-                       buf2[clen] = 0;
-                       
-                       if (log_fp) {
-                         fprintf(log_fp, "\n\n%s\n", buf2);
-                         fprintf(log_fp, "%s\n\n", buf1);
-                         fprintf(log_fp, "RelTime(Us)  Delta              debugid                      arg1       arg2       arg3      arg4       thread   cpu  command\n\n");
-                       }
-                       start_bias = ((double)start) / divisor;
-                       last_timestamp = timestamp;
-                       first_entry = 0;
+               if (header.version_no != RAW_VERSION0) {
+                       offset = lseek(RAW_fd, (off_t)0, SEEK_CUR);
+                       offset = (offset + (4095)) & ~4095;
+
+                       lseek(RAW_fd, offset, SEEK_SET);
                }
-               delta = timestamp - last_timestamp;
+       } else {
+               int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDTHRMAP};
+               if (sysctl(mib, ARRAYSIZE(mib), mapptr, &size, NULL, 0) < 0) {
+                       /*
+                        * This is not fatal -- just means I cant map command strings
+                        */
+                       printf("Can't read the thread map -- this is not fatal\n");
 
-               if ((map = find_thread_map(thread)))
-                       strcpy(command, map->command);
-               else
-                       command[0] = 0;
+                       total_threads = 0;
+               }
+       }
+       for (i = 0; i < total_threads; i++) {
+               create_map_entry(mapptr[i].thread, &mapptr[i].command[0]);
+       }
+       free(mapptr);
+}
 
-               switch (type) {
+void
+create_map_entry(uintptr_t thread, char *command)
+{
+       threadmap_t tme;
 
-               case CQ_action:
-                   if (log_fp) {
-                       fprintf(log_fp, "%9.1f %8.1f\t\tCQ_action @ %-59.59s %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, pc_to_string(kd->arg1, 59, 1) , thread, cpunum, command);
-                   }
-                   last_timestamp = timestamp;
-                   break;
+       if ((tme = threadmap_freelist)) {
+               threadmap_freelist = tme->tm_next;
+       } else {
+               tme = (threadmap_t)malloc(sizeof(struct threadmap));
+       }
 
-               case TES_action:
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f\t\tTES_action @ %-58.58s %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, pc_to_string(kd->arg1, 58, 1) , thread, cpunum, command);
-                   }
+       tme->tm_thread = thread;
 
-                   last_timestamp = timestamp;
-                   break;
+       (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+       tme->tm_command[MAXCOMLEN] = '\0';
+       tme->tm_orig_command[0] = '\0';
 
-               case IES_action:
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f\t\tIES_action @ %-58.58s %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, pc_to_string(kd->arg1, 58, 1) , thread, cpunum, command);
-                   }
+       int hashid = thread & HASH_MASK;
 
-                   last_timestamp = timestamp;
-                   break;
+       tme->tm_next = threadmap_hash[hashid];
+       threadmap_hash[hashid] = tme;
+}
 
-               case IES_filter:
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f\t\tIES_filter @ %-58.58s %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, pc_to_string(kd->arg1, 58, 1) , thread, cpunum, command);
-                   }
+void
+delete_thread_entry(uintptr_t thread)
+{
+       threadmap_t tme;
 
-                   last_timestamp = timestamp;
-                   break;
+       int hashid = thread & HASH_MASK;
 
-               case DECR_TRAP:
-                   last_decrementer_kd[cpunum] = kd;
+       if ((tme = threadmap_hash[hashid])) {
+               if (tme->tm_thread == thread) {
+                       threadmap_hash[hashid] = tme->tm_next;
+               } else {
+                       threadmap_t tme_prev = tme;
 
-                   if (i_thresh_hold && (int)i_latency > i_thresh_hold)
-                           p = "*";
-                   else
-                           p = " ";
+                       for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+                               if (tme->tm_thread == thread) {
+                                       tme_prev->tm_next = tme->tm_next;
+                                       break;
+                               }
+                               tme_prev = tme;
+                       }
+               }
+               if (tme) {
+                       tme->tm_next = threadmap_freelist;
+                       threadmap_freelist = tme;
+               }
+       }
+}
 
-                   mode = 1;
+void
+find_and_insert_tmp_map_entry(uintptr_t pthread, char *command)
+{
+       threadmap_t tme;
+
+       if ((tme = threadmap_temp)) {
+               if (tme->tm_pthread == pthread) {
+                       threadmap_temp = tme->tm_next;
+               } else {
+                       threadmap_t tme_prev = tme;
+
+                       for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+                               if (tme->tm_pthread == pthread) {
+                                       tme_prev->tm_next = tme->tm_next;
+                                       break;
+                               }
+                               tme_prev = tme;
+                       }
+               }
+               if (tme) {
+                       (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+                       tme->tm_command[MAXCOMLEN] = '\0';
+                       tme->tm_orig_command[0] = '\0';
+
+                       int hashid = tme->tm_thread & HASH_MASK;
+                       tme->tm_next = threadmap_hash[hashid];
+                       threadmap_hash[hashid] = tme;
+               }
+       }
+}
 
-                   if ((ti = find_thread(kd->arg5, 0, 0))) {
-                           if (ti->type == -1 && strcmp(command, "kernel_task"))
-                                   mode = 0;
-                   }
+void
+create_tmp_map_entry(uintptr_t thread, uintptr_t pthread)
+{
+       threadmap_t tme;
 
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f[%.1f]%s\tDECR_TRAP @ %-59.59s %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, i_latency, p, pc_to_string(kd->arg2, 59, mode) , thread, cpunum, command);
-                   }
+       if ((tme = threadmap_freelist)) {
+               threadmap_freelist = tme->tm_next;
+       } else {
+               tme = malloc(sizeof(struct threadmap));
+       }
 
-                   last_timestamp = timestamp;
-                   break;
+       tme->tm_thread = thread;
+       tme->tm_pthread = pthread;
+       tme->tm_command[0] = '\0';
+       tme->tm_orig_command[0] = '\0';
 
-               case DECR_SET:
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f[%.1f]  \t%-28.28s                                            %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, (double)kd->arg1/divisor, "DECR_SET", thread, cpunum, command);
-                   }
+       tme->tm_next = threadmap_temp;
+       threadmap_temp = tme;
+}
 
-                   last_timestamp = timestamp;
-                   break;
+threadmap_t
+find_thread_entry(uintptr_t thread)
+{
+       threadmap_t tme;
 
-               case MACH_sched:
-               case MACH_stkhandoff:
-                   last_mach_sched = kd;
+       int hashid = thread & HASH_MASK;
 
-                   if ((map = find_thread_map(kd->arg2)))
-                           strcpy(command1, map->command);
-                   else
-                           sprintf(command1, "%-8x", kd->arg2);
+       for (tme = threadmap_hash[hashid]; tme; tme = tme->tm_next) {
+               if (tme->tm_thread == thread) {
+                       return tme;
+               }
+       }
+       return 0;
+}
 
-                   if ((ti = find_thread(kd->arg2, 0, 0))) {
-                           if (ti->type == -1 && strcmp(command1, "kernel_task"))
-                                   p = "U";
-                           else
-                                   p = "K";
-                   } else
-                           p = "*";
-                   memset(sched_info, ' ', sizeof(sched_info));
+void
+find_thread_name(uintptr_t thread, char **command)
+{
+       threadmap_t     tme;
 
-                   sprintf(sched_info, "%14.14s", command);
-                   clen = strlen(sched_info);
-                   sched_info[clen] = ' ';
+       if ((tme = find_thread_entry(thread))) {
+               *command = tme->tm_command;
+       } else {
+               *command = EMPTYSTRING;
+       }
+}
 
-                   sprintf(&sched_info[14],  " @ pri %3d  -->  %14.14s", kd->arg3, command1);
-                   clen = strlen(sched_info);
-                   sched_info[clen] = ' ';
+void
+add_thread_entry_to_list(thread_entry_t *list, uintptr_t thread)
+{
+       thread_entry_t  te;
 
-                   sprintf(&sched_info[45], " @ pri %3d%s", kd->arg4, p);
+       if ((te = thread_entry_freelist)) {
+               thread_entry_freelist = te->te_next;
+       } else {
+               te = (thread_entry_t)malloc(sizeof(struct thread_entry));
+       }
 
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f\t\t%-10.10s  %s    %-8x  %d\n",
-                                   timestamp - start_bias, delta, "MACH_SCHED", sched_info, thread, cpunum);
-                   }
+       te->te_thread = thread;
+       te->te_next = *list;
+       *list = te;
+}
 
-                   last_timestamp = timestamp;
-                   break;
+void
+exec_thread_entry(uintptr_t thread, char *command)
+{
+       threadmap_t     tme;
 
-               case VFS_LOOKUP:
-                   if ((ti = find_thread(thread, 0, 0)) == (struct th_info *)0) {
-                           if (cur_max >= MAX_THREADS)
-                                   continue;
-                           ti = &th_state[cur_max++];
-
-                           ti->thread = thread;
-                           ti->type   = -1;
-                           ti->pathptr = (long *)0;
-                           ti->child_thread = 0;
-                   }
-                   while ( (kd < end_of_sample) && ((kd->debugid & DBG_FUNC_MASK) == VFS_LOOKUP))
-                     {
-                       if (ti->pathptr == NULL) {
-                           ti->arg1 = kd->arg1;
-                           sargptr = ti->pathname;
-                               
-                           *sargptr++ = kd->arg2;
-                           *sargptr++ = kd->arg3;
-                           *sargptr++ = kd->arg4;
-                           /*
-                            * NULL terminate the 'string'
-                            */
-                           *sargptr = 0;
-                           ti->pathptr = sargptr;
+       if ((tme = find_thread_entry(thread))) {
+               if (tme->tm_orig_command[0] == '\0') {
+                       (void)strncpy (tme->tm_orig_command, tme->tm_command, MAXCOMLEN);
+                       tme->tm_orig_command[MAXCOMLEN] = '\0';
+               }
+               (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+               tme->tm_command[MAXCOMLEN] = '\0';
 
-                       } else {
-                           sargptr = ti->pathptr;
+               add_thread_entry_to_list(&thread_reset_list, thread);
+       } else {
+               create_map_entry(thread, command);
+       }
+}
 
-                           /*
-                               We don't want to overrun our pathname buffer if the
-                               kernel sends us more VFS_LOOKUP entries than we can
-                               handle.
-                           */
+void
+record_thread_entry_for_gc(uintptr_t thread)
+{
+       add_thread_entry_to_list(&thread_delete_list, thread);
+}
 
-                            if (sargptr >= &ti->pathname[NUMPARMS])
-                             {
-                               kd++;
-                               continue;
-                             }
-
-                            /*
-                              We need to detect consecutive vfslookup entries.
-                              So, if we get here and find a START entry,
-                              fake the pathptr so we can bypass all further
-                              vfslookup entries.
-                           */
-
-                            if (kd->debugid & DBG_FUNC_START)
-                              {
-                                ti->pathptr = &ti->pathname[NUMPARMS];
-                              }
-                           else
-                             {
-                               *sargptr++ = kd->arg1;
-                               *sargptr++ = kd->arg2;
-                               *sargptr++ = kd->arg3;
-                               *sargptr++ = kd->arg4;
-                               /*
-                                * NULL terminate the 'string'
-                                */
-                               *sargptr = 0;
+void
+gc_thread_entries(void)
+{
+       thread_entry_t te;
+       thread_entry_t te_next;
+       int count = 0;
 
-                               ti->pathptr = sargptr;
-                             }
-                       }
-                       kd++;
-                   }
-                   p = (char *)ti->pathname;
-
-                   kd--;
-
-                   /* print the tail end of the pathname */
-                   len = strlen(p);
-                   if (len > 42)
-                     len -= 42;
-                   else
-                     len = 0;
-                           
-                   if (log_fp) {
-                     fprintf(log_fp, "%9.1f %8.1f\t\t%-14.14s %-42s    %-8x   %-8x  %d  %s\n",
-                             timestamp - start_bias, delta, "VFS_LOOKUP", 
-                             &p[len], ti->arg1, thread, cpunum, command);
-                   }
-
-                   last_timestamp = timestamp;
-                   break;
+       for (te = thread_delete_list; te; te = te_next) {
+               delete_thread_entry(te->te_thread);
 
-               default:
-                   if (debugid & DBG_FUNC_START)
-                           enter_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 1);
-                   else if (debugid & DBG_FUNC_END)
-                           exit_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 1);
-                   else
-                           print_entry(log_fp, kd, thread, type, command, timestamp, delta, start_bias);
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
 
-                   last_timestamp = timestamp;
-                   break;
-               }
+               count++;
        }
-       if (last_mach_sched && log_fp)
-               fprintf(log_fp, "\nblocked by %s @ priority %d\n", command, last_mach_sched->arg3);
-#if 0
-       if (first_entry == 0 && log_fp)
-               fprintf(log_fp, "\n   start = %qd   stop = %qd    count = %d    now = %qd\n", start, stop, count, now);
-#endif
-       if (log_fp)
-               fflush(log_fp);
-
-       if (log_fp && (my_policy == THREAD_TIME_CONSTRAINT_POLICY))
-         {
-           /* set back to realtime band */
-           if(set_time_constraint_policy() != KERN_SUCCESS)
-             quit("Failed to set time_constraint policy.\n");
-         }
+       thread_delete_list = 0;
 }
 
 void
-enter_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, double timestamp, double delta, double bias, int print_info)
+gc_reset_entries(void)
 {
-       struct th_info *ti;
-       int    i;
-       int    cpunum;
-       char  *p;
-
-       cpunum = CPU_NUMBER(kd);
-
-       if (print_info && fp) {
-              if ((p = find_code(type))) {
-                      if (type == INTERRUPT) {
-                              int mode = 1;
-
-                              if ((ti = find_thread(kd->arg5, 0, 0))) {
-                                      if (ti->type == -1 && strcmp(command, "kernel_task"))
-                                              mode = 0;
-                              }
-
-                              fprintf(fp, "%9.1f %8.1f\t\tINTERRUPT @ %-59.59s %-8x  %d  %s\n",
-                                      timestamp - bias, delta, pc_to_string(kd->arg2, 59, mode), thread, cpunum, command);
-                      } else if (type == MACH_vmfault) {
-                              fprintf(fp, "%9.1f %8.1f\t\t%-28.28s                                            %-8x  %d  %s\n",
-                                      timestamp - bias, delta, p, thread, cpunum, command);
-                      } else {
-                              fprintf(fp, "%9.1f %8.1f\t\t%-28.28s %-8x   %-8x   %-8x  %-8x   %-8x  %d  %s\n",
-                                      timestamp - bias, delta, p, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
-                                      thread, cpunum, command);
-                      }
-              } else {
-                      fprintf(fp, "%9.1f %8.1f\t\t%-8x                     %-8x   %-8x   %-8x  %-8x   %-8x  %d  %s\n",
-                              timestamp - bias, delta, type, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
-                              thread, cpunum, command);
-              }
-       }
-       if ((ti = find_thread(thread, -1, type)) == (struct th_info *)0) {
-              if (cur_max >= MAX_THREADS) {
-                      static int do_this_once = 1;
-
-                      if (do_this_once) {
-                              for (i = 0; i < cur_max; i++) {
-                                      if (!fp)
-                                            break;
-                                      fprintf(fp, "thread = %x, type = %x\n", 
-                                              th_state[i].thread, th_state[i].type);
-                              }
-                              do_this_once = 0;
-                      }
-                      return;
+       thread_entry_t te;
+       thread_entry_t te_next;
+       int count = 0;
 
-              }
-              ti = &th_state[cur_max++];
-
-              ti->thread = thread;
-              ti->child_thread = 0;
-       }
-       if (type != BSC_exit)
-              ti->type = type;
-       else
-              ti->type = -1;
-       ti->stime  = timestamp;
-       ti->pathptr = (long *)NULL;
+       for (te = thread_reset_list; te; te = te_next) {
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
 
-#if 0
-       if (print_info && fp)
-              fprintf(fp, "cur_max = %d,  ti = %x,  type = %x,  thread = %x\n", cur_max, ti, ti->type, ti->thread);
-#endif
+               count++;
+       }
+       thread_reset_list = 0;
 }
 
-
 void
-exit_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, double timestamp, double delta, double bias, int print_info)
+reset_thread_names(void)
 {
-       struct th_info *ti;
-       int    cpunum;
-       char   *p;
-       uint64_t user_addr;
-
-       cpunum = CPU_NUMBER(kd);
+       thread_entry_t te;
+       thread_entry_t te_next;
+       int count = 0;
+
+       for (te = thread_reset_list; te; te = te_next) {
+               threadmap_t     tme;
+
+               if ((tme = find_thread_entry(te->te_thread))) {
+                       if (tme->tm_orig_command[0]) {
+                               (void)strncpy (tme->tm_command, tme->tm_orig_command, MAXCOMLEN);
+                               tme->tm_command[MAXCOMLEN] = '\0';
+                               tme->tm_orig_command[0] = '\0';
+                       }
+               }
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
 
-       ti = find_thread(thread, type, type);
-#if 0
-       if (print_info && fp)
-              fprintf(fp, "cur_max = %d,  ti = %x,  type = %x,  thread = %x\n", cur_max, ti, type, thread);
-#endif
-       if (print_info && fp) {
-              if (ti)
-                      fprintf(fp, "%9.1f %8.1f(%.1f) \t", timestamp - bias, delta, timestamp - ti->stime);
-              else
-                      fprintf(fp, "%9.1f %8.1f()      \t", timestamp - bias, delta);
-
-              if ((p = find_code(type))) {
-                      if (type == INTERRUPT) {
-                              fprintf(fp, "INTERRUPT                                                               %-8x  %d  %s\n", thread, cpunum, command);
-                      } else if (type == MACH_vmfault && kd->arg4 <= DBG_PAGEIND_FAULT) {
-                              user_addr = ((uint64_t)kd->arg1 << 32) | (uint32_t)kd->arg2;
-
-                              fprintf(fp, "%-28.28s %-10.10s   %-16qx              %-8x  %d  %s\n",
-                                      p, fault_name[kd->arg4], user_addr,
-                                      thread, cpunum, command);
-                      } else {
-                              fprintf(fp, "%-28.28s %-8x   %-8x                        %-8x  %d  %s\n",
-                                      p, kd->arg1, kd->arg2,
-                                      thread, cpunum, command);
-                      }
-              } else {
-                      fprintf(fp, "%-8x                     %-8x   %-8x                        %-8x  %d  %s\n",
-                              type, kd->arg1, kd->arg2,
-                              thread, cpunum, command);
-              }
-       }
-       if (ti == (struct th_info *)0) {
-              if ((ti = find_thread(thread, -1, -1)) == (struct th_info *)0) {
-                      if (cur_max >= MAX_THREADS)
-                              return;
-                      ti = &th_state[cur_max++];
-
-                      ti->thread = thread;
-                      ti->child_thread = 0;
-                      ti->pathptr = (long *)NULL;
-              }
-       }
-       ti->type = -1;
+               count++;
+       }
+       thread_reset_list = 0;
 }
 
 void
-print_entry(FILE *fp, kd_buf *kd, int thread, int type, char *command, double timestamp, double delta, double bias)
+delete_all_thread_entries(void)
 {
-       char  *p;
-       int cpunum;
+       threadmap_t tme = 0;
+       threadmap_t tme_next = 0;
+       int i;
+
+       for (i = 0; i < HASH_SIZE; i++) {
+               for (tme = threadmap_hash[i]; tme; tme = tme_next) {
+                       tme_next = tme->tm_next;
+                        tme->tm_next = threadmap_freelist;
+                       threadmap_freelist = tme;
+               }
+               threadmap_hash[i] = 0;
+       }
+}
 
-       if (!fp)
-        return;
 
-       cpunum = CPU_NUMBER(kd);
-#if 0
-       fprintf(fp, "cur_max = %d, type = %x,  thread = %x, cpunum = %d\n", cur_max, type, thread, cpunum);
-#endif
-       if ((p = find_code(type))) {
-              fprintf(fp, "%9.1f %8.1f\t\t%-28.28s %-8x   %-8x   %-8x  %-8x   %-8x  %d  %s\n",
-                      timestamp - bias, delta, p, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
-                      thread, cpunum, command);
-       } else {
-              fprintf(fp, "%9.1f %8.1f\t\t%-8x                     %-8x   %-8x   %-8x  %-8x   %-8x  %d  %s\n",
-                      timestamp - bias, delta, type, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
-                      thread, cpunum, command);
-       }
-}
 
-int
-check_for_thread_update(int thread, int type, kd_buf *kd)
+
+static void
+insert_run_event(uintptr_t thread, kd_buf *kd, uint64_t now)
 {
-        struct th_info *ti;
-       void create_map_entry();
+       threadrun_t     trp;
 
-        switch (type) {
+       int hashid = thread & HASH_MASK;
 
-       case TRACE_DATA_NEWTHREAD:
-           if ((ti = find_thread(thread, 0, 0)) == (struct th_info *)0) {
-                   if (cur_max >= MAX_THREADS)
-                           return (1);
-                   ti = &th_state[cur_max++];
+       for (trp = threadrun_hash[hashid]; trp; trp = trp->tr_next) {
+               if (trp->tr_thread == thread) {
+                       break;
+               }
+       }
+       if (trp == NULL) {
+               if ((trp = threadrun_freelist)) {
+                       threadrun_freelist = trp->tr_next;
+               } else {
+                       trp = (threadrun_t)malloc(sizeof(struct threadrun));
+               }
 
-                   ti->thread = thread;
-                   ti->type   = -1;
-                   ti->pathptr = (long *)NULL;
-           }
-           ti->child_thread = kd->arg1;
-           return (1);
+               trp->tr_thread = thread;
 
-       case TRACE_STRING_NEWTHREAD:
-           if ((ti = find_thread(thread, 0, 0)) == (struct th_info *)0)
-                   return (1);
-           if (ti->child_thread == 0)
-                   return (1);
-           create_map_entry(ti->child_thread, (char *)&kd->arg1);
+               trp->tr_next = threadrun_hash[hashid];
+               threadrun_hash[hashid] = trp;
 
-           ti->child_thread = 0;
-           return (1);
+               add_thread_entry_to_list(&thread_run_list, thread);
+       }
+       trp->tr_entry = kd;
+       trp->tr_timestamp = now;
+}
 
-       case TRACE_STRING_EXEC:
-           create_map_entry(thread, (char *)&kd->arg1);
-           return (1);
+static threadrun_t
+find_run_event(uintptr_t thread)
+{
+       threadrun_t trp;
+       int hashid = thread & HASH_MASK;
 
+       for (trp = threadrun_hash[hashid]; trp; trp = trp->tr_next) {
+               if (trp->tr_thread == thread) {
+                       return trp;
+               }
        }
-       return (0);
+       return 0;
 }
 
-
-kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, double i_latency)
+static void
+delete_run_event(uintptr_t thread)
 {
-        kd_buf *kd, *kd_start, *kd_stop;
-       int kd_count;     /* Limit the boundary of kd_start */
-       double timestamp = 0.0;
-       double last_timestamp = 0.0;
-       double delta = 0.0;
-       double start_bias = 0.0;
-       int thread, cpunum;
-       int debugid, type, clen;
-       int len;
-       uint64_t now;
-       struct th_info *ti;
-       long  *sargptr;
-       char  *p;
-       char   command[32];
-       char   command1[32];
-       char   sched_info[64];
-       char   buf1[128];
-       char   buf2[128];
-       kd_threadmap *map;
-       kd_threadmap *find_thread_map();
-
-       sprintf(buf1, "%-19.19s     interrupt latency = %.1fus", &(ctime(&curr_time)[0]), i_latency);
-       clen = strlen(buf1);
-       memset(buf2, '-', clen);
-       buf2[clen] = 0;
-       fprintf(log_fp, "\n\n%s\n", buf2);
-       fprintf(log_fp, "%s\n\n", buf1);
+       threadrun_t     trp = 0;
+       threadrun_t trp_prev;
 
-       fprintf(log_fp, "RelTime(Us)  Delta              debugid                      arg1       arg2       arg3      arg4       thread   cpu   command\n\n");
+       int hashid = thread & HASH_MASK;
 
-       thread = kd_beg->arg5;
-       cpunum = CPU_NUMBER(kd_end);
+       if ((trp = threadrun_hash[hashid])) {
+               if (trp->tr_thread == thread) {
+                       threadrun_hash[hashid] = trp->tr_next;
+               } else {
+                       trp_prev = trp;
 
-       for (kd_count = 0, kd_start = kd_beg - 1; (kd_start >= (kd_buf *)my_buffer); kd_start--, kd_count++) {
-               if (kd_count == MAX_LOG_COUNT)
-                       break;
+                       for (trp = trp->tr_next; trp; trp = trp->tr_next) {
+                               if (trp->tr_thread == thread) {
+                                       trp_prev->tr_next = trp->tr_next;
+                                       break;
+                               }
+                               trp_prev = trp;
+                       }
+               }
+               if (trp) {
+                       trp->tr_next = threadrun_freelist;
+                       threadrun_freelist = trp;
+               }
+       }
+}
 
-               if (CPU_NUMBER(kd_start) != cpunum)
-                       continue;
-                                                                                    
-               if ((kd_start->debugid & DBG_FUNC_MASK) == DECR_TRAP)
-                       break;
+static void
+gc_run_events(void) {
+       thread_entry_t te;
+       thread_entry_t te_next;
+       threadrun_t     trp;
+       threadrun_t     trp_next;
+       int count = 0;
+
+       for (te = thread_run_list; te; te = te_next) {
+               int hashid = te->te_thread & HASH_MASK;
+
+               for (trp = threadrun_hash[hashid]; trp; trp = trp_next) {
+                       trp_next = trp->tr_next;
+                       trp->tr_next = threadrun_freelist;
+                       threadrun_freelist = trp;
+                       count++;
+               }
+               threadrun_hash[hashid] = 0;
 
-               if (kd_start->arg5 != thread)
-                       break;
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
        }
+       thread_run_list = 0;
+}
 
-       if (kd_start < (kd_buf *)my_buffer)
-               kd_start = (kd_buf *)my_buffer;
 
-       thread = kd_end->arg5;
 
-       for (kd_stop = kd_end + 1; kd_stop < end_of_sample; kd_stop++) {
-                                                                                    
-               if ((kd_stop->debugid & DBG_FUNC_MASK) == DECR_TRAP)
-                       break;
+static void
+insert_start_event(uintptr_t thread, int type, uint64_t now)
+{
+       event_t evp;
 
-               if (CPU_NUMBER(kd_stop) != cpunum)
-                       continue;
+       int hashid = thread & HASH_MASK;
 
-               if (kd_stop->arg5 != thread)
-                       break;
+       for (evp = event_hash[hashid]; evp; evp = evp->ev_next) {
+               if (evp->ev_thread == thread && evp->ev_type == type) {
+                       break;
+               }
        }
+       if (evp == NULL) {
+               if ((evp = event_freelist)) {
+                       event_freelist = evp->ev_next;
+               } else {
+                       evp = (event_t)malloc(sizeof(struct event));
+               }
 
-       if (kd_stop >= end_of_sample)
-               kd_stop = end_of_sample - 1;
+               evp->ev_thread = thread;
+               evp->ev_type = type;
+
+               evp->ev_next = event_hash[hashid];
+               event_hash[hashid] = evp;
+
+               add_thread_entry_to_list(&thread_event_list, thread);
+       }
+       evp->ev_timestamp = now;
+}
 
-       now = kd_start->timestamp & KDBG_TIMESTAMP_MASK;
-       timestamp = ((double)now) / divisor;
 
-       for (kd = kd_start; kd <= kd_stop; kd++) {
-               type = kd->debugid & DBG_FUNC_MASK;
+static uint64_t
+consume_start_event(uintptr_t thread, int type, uint64_t now)
+{
+       event_t evp;
+       event_t evp_prev;
+       uint64_t elapsed = 0;
+
+       int hashid = thread & HASH_MASK;
+
+       if ((evp = event_hash[hashid])) {
+               if (evp->ev_thread == thread && evp->ev_type == type) {
+                       event_hash[hashid] = evp->ev_next;
+               } else {
+                       evp_prev = evp;
+
+                       for (evp = evp->ev_next; evp; evp = evp->ev_next) {
+                               if (evp->ev_thread == thread && evp->ev_type == type) {
+                                       evp_prev->ev_next = evp->ev_next;
+                                       break;
+                               }
+                               evp_prev = evp;
+                       }
+               }
+               if (evp) {
+                       elapsed = now - evp->ev_timestamp;
 
-               if ((ti = find_thread(kd->arg5, type, type))) {
-                       if (ti->stime >= timestamp)
-                               ti->type = -1;
+                       if (now < evp->ev_timestamp) {
+                               printf("consume: now = %qd,  timestamp = %qd\n", now, evp->ev_timestamp);
+                               elapsed = 0;
+                       }
+                       evp->ev_next = event_freelist;
+                       event_freelist = evp;
                }
        }
-       for (kd = kd_start; kd <= kd_stop; kd++) {
-               int    mode;
+       return elapsed;
+}
 
-               thread  = kd->arg5;
-               cpunum  = CPU_NUMBER(kd);
-               debugid = kd->debugid;
-               type    = kd->debugid & DBG_FUNC_MASK;
+static void
+gc_start_events(void)
+{
+       thread_entry_t  te;
+       thread_entry_t  te_next;
+       event_t         evp;
+       event_t         evp_next;
+       int             count = 0;
+        int            hashid;
+
+       for (te = thread_event_list; te; te = te_next) {
+
+               hashid = te->te_thread & HASH_MASK;
+
+               for (evp = event_hash[hashid]; evp; evp = evp_next) {
+                       evp_next = evp->ev_next;
+                        evp->ev_next = event_freelist;
+                        event_freelist = evp;
+                       count++;
+               }
+               event_hash[hashid] = 0;
 
-               now = kd->timestamp & KDBG_TIMESTAMP_MASK;
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
+       }
+       thread_event_list = 0;
+}
+
+int
+thread_in_user_mode(uintptr_t thread, char *command)
+{
+       event_t evp;
+
+       if (strcmp(command, "kernel_task") == 0) {
+               return 0;
+       }
+
+       int hashid = thread & HASH_MASK;
+
+       for (evp = event_hash[hashid]; evp; evp = evp->ev_next) {
+               if (evp->ev_thread == thread) {
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+
+
+static lookup_t
+handle_lookup_event(uintptr_t thread, int debugid, kd_buf *kdp)
+{
+       lookup_t lkp;
+       boolean_t first_record = FALSE;
+
+       int hashid = thread & HASH_MASK;
+
+       if (debugid & DBG_FUNC_START) {
+               first_record = TRUE;
+       }
+
+       for (lkp = lookup_hash[hashid]; lkp; lkp = lkp->lk_next) {
+               if (lkp->lk_thread == thread) {
+                       break;
+               }
+       }
+       if (lkp == NULL) {
+               if (first_record == FALSE) {
+                       return 0;
+               }
+
+               if ((lkp = lookup_freelist)) {
+                       lookup_freelist = lkp->lk_next;
+               } else {
+                       lkp = (lookup_t)malloc(sizeof(struct lookup));
+               }
+
+               lkp->lk_thread = thread;
+
+               lkp->lk_next = lookup_hash[hashid];
+               lookup_hash[hashid] = lkp;
+
+               add_thread_entry_to_list(&thread_lookup_list, thread);
+       }
+
+       if (first_record == TRUE) {
+               lkp->lk_pathptr = lkp->lk_pathname;
+               lkp->lk_dvp = kdp->arg1;
+       } else {
+               if (lkp->lk_pathptr > &lkp->lk_pathname[NUMPARMS-4]) {
+                       return lkp;
+               }
+               *lkp->lk_pathptr++ = kdp->arg1;
+       }
+       *lkp->lk_pathptr++ = kdp->arg2;
+       *lkp->lk_pathptr++ = kdp->arg3;
+       *lkp->lk_pathptr++ = kdp->arg4;
+       *lkp->lk_pathptr = 0;
+
+       if (debugid & DBG_FUNC_END) {
+               return lkp;
+       }
+
+       return 0;
+}
+
+static void
+delete_lookup_event(uintptr_t thread, lookup_t lkp_to_delete)
+{
+       lookup_t        lkp;
+       lookup_t        lkp_prev;
+       int             hashid;
+
+       hashid = thread & HASH_MASK;
+
+       if ((lkp = lookup_hash[hashid])) {
+               if (lkp == lkp_to_delete) {
+                       lookup_hash[hashid] = lkp->lk_next;
+               } else {
+                       lkp_prev = lkp;
+
+                       for (lkp = lkp->lk_next; lkp; lkp = lkp->lk_next) {
+                               if (lkp == lkp_to_delete) {
+                                       lkp_prev->lk_next = lkp->lk_next;
+                                       break;
+                               }
+                               lkp_prev = lkp;
+                       }
+               }
+               if (lkp) {
+                       lkp->lk_next = lookup_freelist;
+                       lookup_freelist = lkp;
+               }
+       }
+}
+
+static void
+gc_lookup_events(void) {
+       thread_entry_t  te;
+       thread_entry_t  te_next;
+       lookup_t        lkp;
+       lookup_t        lkp_next;
+       int             count = 0;
+        int            hashid;
+
+       for (te = thread_lookup_list; te; te = te_next) {
+               hashid = te->te_thread & HASH_MASK;
+
+               for (lkp = lookup_hash[hashid]; lkp; lkp = lkp_next) {
+                       lkp_next = lkp->lk_next;
+                        lkp->lk_next = lookup_freelist;
+                        lookup_freelist = lkp;
+                       count++;
+               }
+               lookup_hash[hashid] = 0;
+
+               te_next = te->te_next;
+               te->te_next = thread_entry_freelist;
+               thread_entry_freelist = te;
+       }
+       thread_lookup_list = 0;
+}
+
+int
+sample_sc(void)
+{
+       kd_buf  *kd, *end_of_sample;
+       int     keep_going = 1;
+       int     count, i;
+
+       if (!RAW_flag) {
+               /*
+                * Get kernel buffer information
+                */
+               get_bufinfo(&bufinfo);
+       }
+       if (need_new_map) {
+               delete_all_thread_entries();
+               read_command_map();
+               need_new_map = 0;
+       }
+       if (RAW_flag) {
+               uint32_t bytes_read;
+
+               bytes_read = read(RAW_fd, my_buffer, num_entries * sizeof(kd_buf));
+
+               if (bytes_read == -1) {
+                       perror("read failed");
+                       exit(2);
+               }
+               count = bytes_read / sizeof(kd_buf);
+
+               if (count != num_entries) {
+                       keep_going = 0;
+               }
+
+               if (first_read) {
+                       kd = (kd_buf *)my_buffer;
+                       first_now = kd->timestamp & KDBG_TIMESTAMP_MASK;
+                       first_read = 0;
+               }
+               
+       } else {
+               int mib[] = { CTL_KERN, KERN_KDEBUG, KERN_KDREADTR };
+               size_t needed = bufinfo.nkdbufs * sizeof(kd_buf);
+
+               if (sysctl(mib, ARRAYSIZE(mib), my_buffer, &needed, NULL, 0) < 0) {
+                       quit("trace facility failure, KERN_KDREADTR\n");
+               }
+
+               count = needed;
+               sample_generation++;
+
+               if (bufinfo.flags & KDBG_WRAPPED) {
+                       need_new_map = 1;
+                       
+                       if (log_fp) {
+                               fprintf(log_fp, "\n\n%-19.19s   sample = %d   <<<<<<< trace buffer wrapped >>>>>>>\n\n",
+                                       &(ctime(&curr_time)[0]), sample_generation);
+                       }
+                       set_enable(0);
+                       set_enable(1);
+               }
+       }
+       end_of_sample = &((kd_buf *)my_buffer)[count];
+
+       /*
+        * Always reinitialize the DECR_TRAP array
+        */
+       for (i = 0; i < num_cpus; i++) {
+             last_decrementer_kd[i] = (kd_buf *)my_buffer;
+       }
+
+       for (kd = (kd_buf *)my_buffer; kd < end_of_sample; kd++) {
+               kd_buf *kd_start;
+               uintptr_t thread = kd->arg5;
+               int     type = kd->debugid & DBG_FUNC_MASK;
+
+               (void)check_for_thread_update(thread, type, kd, NULL);
+
+               uint64_t now = kd->timestamp & KDBG_TIMESTAMP_MASK;
+               last_now = now;
+
+               if (type == DECR_TRAP) {
+                       int cpunum = CPU_NUMBER(kd);
+                       double i_latency = handle_decrementer(kd, cpunum);
+
+                       if (log_fp) {
+                               if (i_thresh_hold && (int)i_latency > i_thresh_hold) {
+                                       kd_start = last_decrementer_kd[cpunum];
+
+                                       log_decrementer(kd_start, kd, end_of_sample, i_latency);
+                               }
+                               last_decrementer_kd[cpunum] = kd;
+                       }
+               } else {
+                       double s_latency;
+                       if (check_for_scheduler_latency(type, &thread, now, kd, &kd_start, &s_latency)) {
+                               log_scheduler(kd_start, kd, end_of_sample, s_latency, thread);
+                       }
+               }
+       }
+       if (log_fp) {
+               fflush(log_fp);
+       }
+
+       gc_thread_entries();
+       gc_reset_entries();
+       gc_run_events();
+
+       return keep_going;
+}
+
+
+
+void
+enter_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, int print_info)
+{
+       char    *p;
+       double  timestamp;
+       double  delta;
+       char    pcstring[128];
+
+       int cpunum = CPU_NUMBER(kd);
+
+       if (print_info && fp) {
+               timestamp = (double)(now - start_bias) / divisor;
+               delta = (double)idelta / divisor;
+
+               if ((p = find_code(type))) {
+                       if (type == INTERRUPT) {
+                               int mode;
+
+                               if (kd->arg3) {
+                                       mode = USER_MODE;
+                               } else {
+                                       mode = KERNEL_MODE;
+                               }
+
+                               pc_to_string(&pcstring[0], kd->arg2, 58, mode);
+
+                               fprintf(fp, "%9.1f %8.1f\t\tINTERRUPT[%2lx] @ %-58.58s %-8x  %d  %s\n",
+                                       timestamp, delta, kd->arg1, &pcstring[0], thread, cpunum, command);
+                       } else if (type == MACH_vmfault) {
+                               fprintf(fp, "%9.1f %8.1f\t\t%-28.28s                                               %-8x  %d  %s\n",
+                                       timestamp, delta, p, thread, cpunum, command);
+                       } else {
+                               fprintf(fp, "%9.1f %8.1f\t\t%-28.28s %-8lx   %-8lx   %-8lx  %-8lx      %-8x  %d  %s\n",
+                                       timestamp, delta, p, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
+                                       thread, cpunum, command);
+                       }
+               } else {
+                       fprintf(fp, "%9.1f %8.1f\t\t%-8x                     %-8lx   %-8lx   %-8lx  %-8lx      %-8x  %d  %s\n",
+                               timestamp, delta, type, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
+                               thread, cpunum, command);
+              }
+       }
+       if (type != BSC_thread_terminate && type != BSC_exit) {
+               insert_start_event(thread, type, now);
+       }
+}
+
+
+void
+exit_syscall(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, int print_info)
+{
+       char   *p;
+       uint64_t user_addr;
+       double  timestamp;
+       double  delta;
+       double  elapsed_timestamp;
+
+       elapsed_timestamp = (double)consume_start_event(thread, type, now) / divisor;
+
+       if (print_info && fp) {
+               int cpunum = CPU_NUMBER(kd);
+
+               timestamp = (double)(now - start_bias) / divisor;
+               delta = (double)idelta / divisor;
+
+               fprintf(fp, "%9.1f %8.1f(%.1f) \t", timestamp, delta, elapsed_timestamp);
+
+               if ((p = find_code(type))) {
+                       if (type == INTERRUPT) {
+                               fprintf(fp, "INTERRUPT                                                                  %-8x  %d  %s\n", thread, cpunum, command);
+                       } else if (type == MACH_vmfault && kd->arg4 <= DBG_PAGEIND_FAULT) {
+                               user_addr = ((uint64_t)kd->arg1 << 32) | (uint32_t)kd->arg2;
+
+                               fprintf(fp, "%-28.28s %-10.10s   %-16qx                 %-8x  %d  %s\n",
+                                       p, fault_name[kd->arg4], user_addr,
+                                       thread, cpunum, command);
+                      } else {
+                               fprintf(fp, "%-28.28s %-8lx   %-8lx                           %-8x  %d  %s\n",
+                                       p, kd->arg1, kd->arg2,
+                                       thread, cpunum, command);
+                      }
+               } else {
+                       fprintf(fp, "%-8x                     %-8lx   %-8lx                           %-8x  %d  %s\n",
+                               type, kd->arg1, kd->arg2,
+                               thread, cpunum, command);
+               }
+       }
+}
+
+
+void
+print_entry(FILE *fp, kd_buf *kd, int thread, int type, char *command, uint64_t now, uint64_t idelta, uint64_t start_bias, kd_buf *kd_note)
+{
+       char    *p;
+
+       if (!fp) {
+               return;
+       }
 
-               timestamp = ((double)now) / divisor;
+       int cpunum = CPU_NUMBER(kd);
 
-               if (kd == kd_start) {
-                       start_bias = timestamp;
-                       last_timestamp = timestamp;
+       double timestamp = (double)(now - start_bias) / divisor;
+       double delta = (double)idelta / divisor;
+
+       if ((p = find_code(type))) {
+               if (kd == kd_note) {
+                       fprintf(fp, "%9.1f %8.1f\t**\t", timestamp, delta);
+               } else {
+                       fprintf(fp, "%9.1f %8.1f\t\t", timestamp, delta);
                }
-               delta = timestamp - last_timestamp;
+               fprintf(fp, "%-28.28s %-8lx   %-8lx   %-8lx  %-8lx      %-8x  %d  %s\n",
+                       p, kd->arg1, kd->arg2, kd->arg3, kd->arg4, thread, cpunum, command);
+       } else {
+               fprintf(fp, "%9.1f %8.1f\t\t%-8x                     %-8lx   %-8lx   %-8lx  %-8lx   %-8x  %d  %s\n",
+                       timestamp, delta, type, kd->arg1, kd->arg2, kd->arg3, kd->arg4, 
+                       thread, cpunum, command);
+       }
+}
 
-               if ((map = find_thread_map(thread)))
-                       strcpy(command, map->command);
-               else
-                       command[0] = 0;
 
+void
+check_for_thread_update(uintptr_t thread, int debugid_base, kd_buf *kbufp, char **command)
+{
+       if (debugid_base == TRACE_DATA_NEWTHREAD) {
+               /*
+                * Save the create thread data
+                */
+               create_tmp_map_entry(kbufp->arg1, thread);
+       } else if (debugid_base == TRACE_STRING_NEWTHREAD) {
+               /*
+                * process new map entry
+                */
+               find_and_insert_tmp_map_entry(thread, (char *)&kbufp->arg1);
+       } else if (debugid_base == TRACE_STRING_EXEC) {
+               exec_thread_entry(thread, (char *)&kbufp->arg1);
+       } else {
+               if (debugid_base == BSC_exit || debugid_base == BSC_thread_terminate) {
+                       record_thread_entry_for_gc(thread);
+               }
+               if (command) {
+                       find_thread_name(thread, command);
+               }
+       }
+}
 
-               switch (type) {
+
+void
+log_info(uint64_t now, uint64_t idelta, uint64_t start_bias, kd_buf *kd, kd_buf *kd_note)
+{
+       lookup_t        lkp;
+       int             mode;
+       int             reason;
+       char            *p;
+       char            *command;
+       char            *command1;
+       char            command_buf[32];
+       char            sched_info[64];
+       char            pcstring[128];
+       const char *sched_reason;
+       double          i_latency;
+       double          timestamp;
+       double          delta;
+       char joe[32];
+
+       int thread  = kd->arg5;
+       int cpunum      = CPU_NUMBER(kd);
+       int debugid = kd->debugid;
+       int type    = kd->debugid & DBG_FUNC_MASK;
+
+       (void)check_for_thread_update(thread, type, kd, &command);
+
+       if ((type >> 24) == DBG_TRACE) {
+               if (((type >> 16) & 0xff) != DBG_TRACE_INFO) {
+                       return;
+               }
+       }
+       timestamp = (double)(now - start_bias) / divisor;
+       delta = (double)idelta / divisor;
+
+       switch (type) {
 
                case CQ_action:
-                   fprintf(log_fp, "%9.1f %8.1f\t\tCQ_action @ %-59.59s %-8x  %d  %s\n",
-                           timestamp - start_bias, delta, pc_to_string(kd->arg1, 59, 1) , thread, cpunum, command);
+                       pc_to_string(&pcstring[0], kd->arg1, 62, KERNEL_MODE);
 
-                   last_timestamp = timestamp;
-                   break;
+                       fprintf(log_fp, "%9.1f %8.1f\t\tCQ_action @ %-62.62s %-8x  %d  %s\n",
+                               timestamp, delta, &pcstring[0], thread, cpunum, command);
+                       break;
 
-               case DECR_TRAP:
-                   if ((int)(kd->arg1) >= 0)
-                           i_latency = 0;
-                   else
-                           i_latency = (((double)(-1 - kd->arg1)) / divisor);
+               case TES_action:
+                       pc_to_string(&pcstring[0], kd->arg1, 61, KERNEL_MODE);
+
+                       fprintf(log_fp, "%9.1f %8.1f\t\tTES_action @ %-61.61s %-8x  %d  %s\n",
+                               timestamp, delta, &pcstring[0], thread, cpunum, command);
+                       break;
+
+               case IES_action:
+                       pc_to_string(&pcstring[0], kd->arg1, 61, KERNEL_MODE);
+
+                       fprintf(log_fp, "%9.1f %8.1f\t\tIES_action @ %-61.61s %-8x  %d  %s\n",
+                               timestamp, delta, &pcstring[0], thread, cpunum, command);
+                       break;
+
+               case IES_filter:
+                       pc_to_string(&pcstring[0], kd->arg1, 61, KERNEL_MODE);
 
-                   if (i_thresh_hold && (int)i_latency > i_thresh_hold)
-                           p = "*";
-                   else
-                           p = " ";
+                       fprintf(log_fp, "%9.1f %8.1f\t\tIES_filter @ %-61.61s %-8x  %d  %s\n",
+                               timestamp, delta, &pcstring[0], thread, cpunum, command);
+                       break;
 
-                   mode = 1;
+               case DECR_TRAP:
+                       if ((int)kd->arg1 >= 0) {
+                               i_latency = 0;
+                       } else {
+                               i_latency = (((double)(-1 - kd->arg1)) / divisor);
+                       }
 
-                   if ((ti = find_thread(kd->arg5, 0, 0))) {
-                           if (ti->type == -1 && strcmp(command, "kernel_task"))
-                                   mode = 0;
-                   }
-                   fprintf(log_fp, "%9.1f %8.1f[%.1f]%s\tDECR_TRAP @ %-59.59s %-8x  %d  %s\n",
-                           timestamp - start_bias, delta, i_latency, p, pc_to_string(kd->arg2, 59, mode) , thread, cpunum, command);
+                       if (i_thresh_hold && (int)i_latency > i_thresh_hold) {
+                               p = "*";
+                       } else {
+                               p = " ";
+                       }
 
-                   last_timestamp = timestamp;
-                   break;
+                       if (kd->arg3) {
+                               mode = USER_MODE;
+                       } else {
+                               mode = KERNEL_MODE;
+                       }
 
-               case DECR_SET:
-                   fprintf(log_fp, "%9.1f %8.1f[%.1f]  \t%-28.28s                                            %-8x  %d  %s\n",
-                           timestamp - start_bias, delta, (double)kd->arg1/divisor,
-                           "DECR_SET", thread, cpunum, command);
+                       pc_to_string(&pcstring[0], kd->arg2, 62, mode);
 
-                   last_timestamp = timestamp;
-                   break;
+                       fprintf(log_fp, "%9.1f %8.1f[%.1f]%s\tDECR_TRAP @ %-62.62s %-8x  %d  %s\n",
+                                       timestamp, delta, i_latency, p, &pcstring[0], thread, cpunum, command);
+                       break;
+
+               case DECR_SET:
+                       fprintf(log_fp, "%9.1f %8.1f[%.1f]  \t%-28.28s                                               %-8x  %d  %s\n",
+                                       timestamp, delta, (double)kd->arg1/divisor, "DECR_SET", thread, cpunum, command);
+                       break;
 
                case MACH_sched:
                case MACH_stkhandoff:
-                   if ((map = find_thread_map(kd->arg2)))
-                           strcpy(command1, map->command);
-                   else
-                           sprintf(command1, "%-8x", kd->arg2);
 
-                   if ((ti = find_thread(kd->arg2, 0, 0))) {
-                           if (ti->type == -1 && strcmp(command1, "kernel_task"))
-                                   p = "U";
-                           else
-                                   p = "K";
-                   } else
-                           p = "*";
-                   memset(sched_info, ' ', sizeof(sched_info));
-
-                   sprintf(sched_info, "%14.14s", command);
-                   clen = strlen(sched_info);
-                   sched_info[clen] = ' ';
+                       find_thread_name(kd->arg2, &command1);
+                       
+                       if (command1 == EMPTYSTRING) {
+                               command1 = command_buf;
+                               sprintf(command1, "%-8lx", kd->arg2);
+                       }
+                       if (thread_in_user_mode(kd->arg2, command1)) {
+                               p = "U";
+                       } else {
+                               p = "K";
+                       }
 
-                   sprintf(&sched_info[14],  " @ pri %3d  -->  %14.14s", kd->arg3, command1);
-                   clen = strlen(sched_info);
-                   sched_info[clen] = ' ';
+                       reason = kd->arg1;
 
-                   sprintf(&sched_info[45], " @ pri %3d%s", kd->arg4, p);
+                       if (reason > MAX_REASON) {
+                               sched_reason = "?";
+                       } else {
+                               sched_reason = sched_reasons[reason];
+                       }
 
-                   fprintf(log_fp, "%9.1f %8.1f\t\t%-10.10s  %s    %-8x  %d\n",
-                                   timestamp - start_bias, delta, "MACH_SCHED", sched_info, thread, cpunum);
+                       if (sched_reason[0] == '?') {
+                               sprintf(joe, "%x", reason);
+                               sched_reason = joe;
+                       }
+                       sprintf(sched_info, "%14.14s @ pri %3lu  -->  %14.14s @ pri %3lu%s", command, kd->arg3, command1, kd->arg4, p);
 
-                   last_timestamp = timestamp;
-                   break;
+                       fprintf(log_fp, "%9.1f %8.1f\t\t%-10.10s[%s]  %s    %-8x  %d\n",
+                               timestamp, delta, "MACH_SCHED", sched_reason, sched_info, thread, cpunum);
+                       break;
 
                case VFS_LOOKUP:
-                   if ((ti = find_thread(thread, 0, 0)) == (struct th_info *)0) {
-                           if (cur_max >= MAX_THREADS)
-                                   continue;
-                           ti = &th_state[cur_max++];
-
-                           ti->thread = thread;
-                           ti->type   = -1;
-                           ti->pathptr = (long *)NULL;
-                           ti->child_thread = 0;
-                   }
-
-                   while ( (kd <= kd_stop) && (kd->debugid & DBG_FUNC_MASK) == VFS_LOOKUP)
-                     {
-                       if (ti->pathptr == NULL) {
-                           ti->arg1 = kd->arg1;
-                           sargptr = ti->pathname;
+                       if ((lkp = handle_lookup_event(thread, debugid, kd))) {
+                               /*
+                                * print the tail end of the pathname
+                                */
+                               p = (char *)lkp->lk_pathname;
+                               int clen = strlen(p);
+
+                               if (clen > 45) {
+                                       clen -= 45;
+                               } else {
+                                       clen = 0;
+                               }
                                
-                           *sargptr++ = kd->arg2;
-                           *sargptr++ = kd->arg3;
-                           *sargptr++ = kd->arg4;
-                           /*
-                            * NULL terminate the 'string'
-                            */
-                           *sargptr = 0;
+                               fprintf(log_fp, "%9.1f %8.1f\t\t%-14.14s %-45s    %-8lx   %-8x  %d  %s\n",
+                                       timestamp, delta, "VFS_LOOKUP", 
+                                       &p[clen], lkp->lk_dvp, thread, cpunum, command);
 
-                           ti->pathptr = sargptr;
+                               delete_lookup_event(thread, lkp);
+                       }
+                       break;
 
+               default:
+                       if (debugid & DBG_FUNC_START) {
+                               enter_syscall(log_fp, kd, thread, type, command, now, idelta, start_bias, 1);
+                       } else if (debugid & DBG_FUNC_END) {
+                               exit_syscall(log_fp, kd, thread, type, command, now, idelta, start_bias, 1);
                        } else {
-                           sargptr = ti->pathptr;
+                               print_entry(log_fp, kd, thread, type, command, now, idelta, start_bias, kd_note);
+                       }
+                       break;
+       }
+}
+
 
-                           /*
-                               We don't want to overrun our pathname buffer if the
-                               kernel sends us more VFS_LOOKUP entries than we can
-                               handle.
-                           */
 
-                            if (sargptr >= &ti->pathname[NUMPARMS])
-                             {
-                               kd++;
+void
+log_range(kd_buf *kd_buffer, kd_buf *kd_start, kd_buf *kd_stop, kd_buf *kd_note, char *buf1)
+{
+       uint64_t last_timestamp = 0;
+       uint64_t delta = 0;
+       uint64_t start_bias = 0;
+       uint64_t now;
+       kd_buf  *kd;
+       int     clen;
+       char buf2[128];
+
+       clen = strlen(buf1);
+       memset(buf2, '-', clen);
+       buf2[clen] = 0;
+       fprintf(log_fp, "\n\n%s\n", buf2);
+       fprintf(log_fp, "%s\n\n", buf1);
+
+       fprintf(log_fp, "RelTime(Us)  Delta              debugid                      arg1       arg2       arg3      arg4       thread   cpu   command\n\n");
+
+       reset_thread_names();
+
+       last_timestamp = kd_start->timestamp & KDBG_TIMESTAMP_MASK;
+       start_bias = last_timestamp;
+
+       for (kd = kd_buffer; kd <= kd_stop; kd++) {
+               now = kd->timestamp & KDBG_TIMESTAMP_MASK;
+
+               if (kd >= kd_start) {
+                       delta = now - last_timestamp;
+
+                       log_info(now, delta, start_bias, kd, kd_note);
+
+                       last_timestamp = now;
+               } else {
+                       int     debugid = kd->debugid;
+                       int     thread = kd->arg5;
+                       int     type = kd->debugid & DBG_FUNC_MASK;
+
+                       if ((type >> 24) == DBG_TRACE) {
+                               if (((type >> 16) & 0xff) != DBG_TRACE_INFO) {
+                                       continue;
+                               }
+                       }
+                       if (type == BSC_thread_terminate || type == BSC_exit) {
                                continue;
-                             }
-
-                            /*
-                              We need to detect consecutive vfslookup entries.
-                              So, if we get here and find a START entry,
-                              fake the pathptr so we can bypass all further
-                              vfslookup entries.
-                           */
-
-                            if (kd->debugid & DBG_FUNC_START)
-                              {
-                                ti->pathptr = &ti->pathname[NUMPARMS];
-                              }
-                           else
-                             {
-                               *sargptr++ = kd->arg1;
-                               *sargptr++ = kd->arg2;
-                               *sargptr++ = kd->arg3;
-                               *sargptr++ = kd->arg4;
-                               /*
-                                * NULL terminate the 'string'
-                                */
-                               *sargptr = 0;
+                       }
 
-                               ti->pathptr = sargptr;
-                             }
+                       if (debugid & DBG_FUNC_START) {
+                               insert_start_event(thread, type, now);
+                       } else if (debugid & DBG_FUNC_END) {
+                               (void)consume_start_event(thread, type, now);
                        }
-                       kd++;
-                   }
-                   p = (char *)ti->pathname;
-
-                   kd--;
-                   /* print the tail end of the pathname */
-                   len = strlen(p);
-                   if (len > 42)
-                     len -= 42;
-                   else
-                     len = 0;
-                   
-                   fprintf(log_fp, "%9.1f %8.1f\t\t%-14.14s %-42s    %-8x   %-8x  %d  %s\n",
-                           timestamp - start_bias, delta, "VFS_LOOKUP", 
-                           &p[len], ti->arg1, thread, cpunum, command);
-
-                   last_timestamp = timestamp;
-                   break;
+               }
+       }
+       gc_start_events();
+       gc_lookup_events();
+}
 
-               default:
-                   if (debugid & DBG_FUNC_START)
-                           enter_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 1);
-                   else if (debugid & DBG_FUNC_END)
-                           exit_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 1);
-                   else
-                           print_entry(log_fp, kd, thread, type, command, timestamp, delta, start_bias);
 
-                   last_timestamp = timestamp;
-                   break;
+kd_buf *
+log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, double i_latency)
+{
+       kd_buf *kd_start, *kd_stop;
+       int kd_count; /* Limit the boundary of kd_start */
+       uint64_t now;
+       double sample_timestamp;
+       char buf1[128];
+
+       int thread = kd_beg->arg5;
+       int cpunum = CPU_NUMBER(kd_end);
+
+       for (kd_count = 0, kd_start = kd_beg - 1; (kd_start >= (kd_buf *)my_buffer); kd_start--, kd_count++) {
+               if (kd_count == MAX_LOG_COUNT) {
+                       break;
+               }
+
+               if (CPU_NUMBER(kd_start) != cpunum) {
+                       continue;
+               }
+                                                                                    
+               if ((kd_start->debugid & DBG_FUNC_MASK) == DECR_TRAP) {
+                       break;
+               }
+
+               if (kd_start->arg5 != thread) {
+                       break;
+               }
+       }
+       if (kd_start < (kd_buf *)my_buffer) {
+               kd_start = (kd_buf *)my_buffer;
+       }
+
+       thread = kd_end->arg5;
+
+       for (kd_stop = kd_end + 1; kd_stop < end_of_sample; kd_stop++) {
+               if (CPU_NUMBER(kd_stop) != cpunum) {
+                       continue;
+               }
+
+               if ((kd_stop->debugid & DBG_FUNC_MASK) == INTERRUPT) {
+                       break;
+               }
+
+               if (kd_stop->arg5 != thread) {
+                       break;
+               }
+       }
+       if (kd_stop >= end_of_sample) {
+               kd_stop = end_of_sample - 1;
+       }
+
+       if (RAW_flag) {
+               time_t TOD_secs;
+               uint64_t TOD_usecs;
+
+               now = kd_start->timestamp & KDBG_TIMESTAMP_MASK;
+               sample_timestamp = (double)(now - first_now) / divisor;
+
+               TOD_usecs = (uint64_t)sample_timestamp;
+               TOD_secs = sample_TOD_secs + ((sample_TOD_usecs + TOD_usecs) / 1000000);
+
+               sprintf(buf1, "%-19.19s     interrupt latency = %.1fus [timestamp %.1f]", ctime(&TOD_secs), i_latency, sample_timestamp);
+       } else {
+               sprintf(buf1, "%-19.19s     interrupt latency = %.1fus [sample %d]", &(ctime(&curr_time)[0]), i_latency, sample_generation);
+       }
+
+       log_range((kd_buf *)my_buffer, kd_start, kd_stop, 0, buf1);
+
+       return kd_stop;
+}
+
+
+void
+log_scheduler(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, double s_latency, uintptr_t thread)
+{
+       kd_buf *kd_start, *kd_stop;
+       uint64_t now;
+       double sample_timestamp;
+       char buf1[128];
+
+       int cpunum = CPU_NUMBER(kd_end);
+
+       for (kd_start = kd_beg; (kd_start >= (kd_buf *)my_buffer); kd_start--) {
+               if (CPU_NUMBER(kd_start) == cpunum) {
+                       break;
+               }
+       }
+       if (kd_start < (kd_buf *)my_buffer) {
+               kd_start = (kd_buf *)my_buffer;
+       }
+
+       for (kd_stop = kd_end + 1; kd_stop < end_of_sample; kd_stop++) {
+               if (kd_stop->arg5 == thread) {
+                       break;
+               }
+       }
+       if (kd_stop >= end_of_sample) {
+               kd_stop = end_of_sample - 1;
+       }
+
+       if (RAW_flag) {
+               time_t  TOD_secs;
+               uint64_t TOD_usecs;
+
+               now = kd_start->timestamp & KDBG_TIMESTAMP_MASK;
+               sample_timestamp = (double)(now - first_now) / divisor;
+
+               TOD_usecs = (uint64_t)sample_timestamp;
+               TOD_secs = sample_TOD_secs + ((sample_TOD_usecs + TOD_usecs) / 1000000);
+
+               sprintf(buf1, "%-19.19s     priority = %d,  scheduling latency = %.1fus [timestamp %.1f]", ctime(&TOD_secs), watch_priority, s_latency, sample_timestamp);
+       } else {
+               sprintf(buf1, "%-19.19s     priority = %d,  scheduling latency = %.1fus [sample %d]", &(ctime(&curr_time)[0]), watch_priority, s_latency, sample_generation);
+       }
+
+       log_range((kd_buf *)my_buffer, kd_start, kd_stop, kd_beg, buf1);
+}
+
+
+
+int
+check_for_scheduler_latency(int type, uintptr_t *thread, uint64_t now, kd_buf *kd, kd_buf **kd_start, double *latency)
+{
+       int found_latency = 0;
+
+       if (type == MACH_makerunnable) {
+               if (watch_priority == kd->arg2) {
+                       insert_run_event(kd->arg1, kd, now);
+               }
+       } else if (type == MACH_sched || type == MACH_stkhandoff) {
+               threadrun_t     trp;
+
+               if (type == MACH_sched || type == MACH_stkhandoff) {
+                       *thread = kd->arg2;
+               }
+
+               if ((trp = find_run_event(*thread))) {
+                       double d_s_latency = (((double)(now - trp->tr_timestamp)) / divisor);
+                       int s_latency = (int)d_s_latency;
+
+                       if (s_latency) {
+                               if (s_latency < 100) {
+                                       s_usec_10_bins[s_latency/10]++;
+                               }
+                               if (s_latency < 1000) {
+                                       s_usec_100_bins[s_latency/100]++;
+                               } else if (s_latency < 10000) {
+                                       s_msec_1_bins[s_latency/1000]++;
+                               } else if (s_latency < 50000) {
+                                       s_msec_10_bins[s_latency/10000]++;
+                               } else {
+                                       s_too_slow++;
+                               }
+
+                               if (s_latency > s_max_latency) {
+                                       s_max_latency = s_latency;
+                               }
+                               if (s_latency < s_min_latency || s_total_samples == 0) {
+                                       s_min_latency = s_latency;
+                               }
+                               s_total_latency += s_latency;
+                               s_total_samples++;
+
+                               if (s_thresh_hold && s_latency > s_thresh_hold) {
+                                       s_exceeded_threshold++;
+                                       
+                                       if (log_fp) {
+                                               *kd_start = trp->tr_entry;
+                                               *latency = d_s_latency;
+                                               found_latency = 1;
+                                       }
+                               }
+                       }
+                       delete_run_event(*thread);
                }
        }
-       return(kd_stop);
+       return found_latency;
 }
 
 
-double handle_decrementer(kd_buf *kd)
+double
+handle_decrementer(kd_buf *kd, int cpunum)
 {
-        double latency;
+       struct i_latencies *il;
+       double latency;
        long   elapsed_usecs;
 
-       if ((long)(kd->arg1) >= 0)
-              latency = 1;
-       else
-              latency = (((double)(-1 - kd->arg1)) / divisor);
+       if (i_latency_per_cpu == FALSE) {
+               cpunum = 0;
+       }
+
+       il = &i_lat[cpunum];
+
+       if ((long)(kd->arg1) >= 0) {
+               latency = 1;
+       } else {
+               latency = (((double)(-1 - kd->arg1)) / divisor);
+       }
        elapsed_usecs = (long)latency;
 
-       if (elapsed_usecs < 100)
-               i_usec_10_bins[elapsed_usecs/10]++;
-       if (elapsed_usecs < 1000)
-               i_usec_100_bins[elapsed_usecs/100]++;
-       else if (elapsed_usecs < 10000)
-               i_msec_1_bins[elapsed_usecs/1000]++;
-       else if (elapsed_usecs < 50000)
-               i_msec_10_bins[elapsed_usecs/10000]++;
-       else 
-               i_too_slow++;
-
-    if(use_high_res_bins && elapsed_usecs < N_HIGH_RES_BINS) {
-        if(elapsed_usecs > i_highest_latency)
-            i_highest_latency = elapsed_usecs;
-        i_high_res_bins[elapsed_usecs]++;
-    }
-
-       if (i_thresh_hold && elapsed_usecs > i_thresh_hold)
-               i_exceeded_threshold++;
-       if (elapsed_usecs > i_max_latency)
-               i_max_latency = elapsed_usecs;
-       if (elapsed_usecs < i_min_latency || i_total_samples == 0)
-               i_min_latency = elapsed_usecs;
-       i_total_latency += elapsed_usecs;
-       i_total_samples++;
-
-       return (latency);
+       if (elapsed_usecs < 100) {
+               il->i_usec_10_bins[elapsed_usecs/10]++;
+       }
+       
+       if (elapsed_usecs < 1000) {
+               il->i_usec_100_bins[elapsed_usecs/100]++;
+       } else if (elapsed_usecs < 10000) {
+               il->i_msec_1_bins[elapsed_usecs/1000]++;
+       } else if (elapsed_usecs < 50000) {
+               il->i_msec_10_bins[elapsed_usecs/10000]++;
+       } else {
+               il->i_too_slow++;
+       }
+
+       if (use_high_res_bins && elapsed_usecs < N_HIGH_RES_BINS) {
+               i_high_res_bins[elapsed_usecs]++;
+       }
+       if (i_thresh_hold && elapsed_usecs > i_thresh_hold) {
+               il->i_exceeded_threshold++;
+       }
+       if (elapsed_usecs > il->i_max_latency) {
+               il->i_max_latency = elapsed_usecs;
+       }
+       if (elapsed_usecs < il->i_min_latency || il->i_total_samples == 0) {
+               il->i_min_latency = elapsed_usecs;
+       }
+       il->i_total_latency += elapsed_usecs;
+       il->i_total_samples++;
+
+       return latency;
 }
 
 
-void init_code_file()
+
+char *
+find_code(int type)
+{
+       int i;
+       for (i = 0; i < num_of_codes; i++) {
+               if (codes_tab[i].type == type) {
+                       return codes_tab[i].name;
+               }
+       }
+       return NULL;
+}
+
+
+void
+init_code_file(void)
 {
-        FILE *fp;
-       int   i, n, code;
-       char name[128];
+       FILE *fp;
+       int i;
 
-       if ((fp = fopen(code_file, "r")) == (FILE *)0) {
-               if (log_fp)
-                       fprintf(log_fp, "open of %s failed\n", code_file);
-               return;
+       if ((fp = fopen(code_file, "r")) == NULL) {
+               if (log_fp) {
+                       fprintf(log_fp, "open of %s failed\n", code_file);
+               }
+               return;
        }
        for (i = 0; i < MAX_ENTRIES; i++) {
-               n = fscanf(fp, "%x%127s\n", &code, name);
+               int code;
+               char name[128];
+               int n = fscanf(fp, "%x%127s\n", &code, name);
 
                if (n == 1 && i == 0) {
                        /*
@@ -2153,8 +2542,9 @@ void init_code_file()
                         */
                        continue;
                }
-               if (n != 2)
-                       break;
+               if (n != 2) {
+                       break;
+               }
 
                strncpy(codes_tab[i].name, name, 32);
                codes_tab[i].type = code;
@@ -2166,203 +2556,228 @@ void init_code_file()
 
 
 void
-do_kernel_nm()
+do_kernel_nm(void)
 {
-  int i, len;
-  FILE *fp = (FILE *)0;
-  char tmp_nm_file[128];
-  char tmpstr[1024];
-  char inchr;
-
-  bzero(tmp_nm_file, 128);
-  bzero(tmpstr, 1024);
-
-  /* Build the temporary nm file path */
-  strcpy(tmp_nm_file,"/tmp/knm.out.XXXXXX");
-  if (!mktemp(tmp_nm_file)) {
-    fprintf(stderr, "Error in mktemp call\n");
-    return;
-  }
-
-  /* Build the nm command and create a tmp file with the output*/
-  sprintf (tmpstr, "/usr/bin/nm -f -n -s __TEXT __text %s > %s",
-          kernelpath, tmp_nm_file);
-  system(tmpstr);
+       int i, len;
+       FILE *fp = NULL;
+       char tmp_nm_file[128];
+       char tmpstr[1024];
+       char inchr;
+
+       bzero(tmp_nm_file, 128);
+       bzero(tmpstr, 1024);
+
+       /*
+        * Build the temporary nm file path
+        */
+       strcpy(tmp_nm_file,"/tmp/knm.out.XXXXXX");
+
+       if (!mktemp(tmp_nm_file)) {
+               fprintf(stderr, "Error in mktemp call\n");
+               return;
+       }
+
+       /*
+        * Build the nm command and create a tmp file with the output
+        */
+       sprintf (tmpstr, "/usr/bin/nm -f -n -s __TEXT __text %s > %s",
+                kernelpath, tmp_nm_file);
+       system(tmpstr);
   
-  /* Parse the output from the nm command */
-  if ((fp=fopen(tmp_nm_file, "r")) == (FILE *)0)
-    {
-      /* Hmmm, let's not treat this as fatal */
-      fprintf(stderr, "Failed to open nm symbol file [%s]\n", tmp_nm_file);
-      return;
-    }
-
-  /* Count the number of symbols in the nm symbol table */
-  kern_sym_count=0;
-  while ( (inchr = getc(fp)) != -1)
-    {
-      if (inchr == '\n')
-       kern_sym_count++;
-    }
-
-  rewind(fp);
-
-  /* Malloc the space for symbol table */
-  if (kern_sym_count > 0)
-    {
-       kern_sym_tbl = (kern_sym_t *)malloc(kern_sym_count * sizeof (kern_sym_t));
-       if (!kern_sym_tbl)
-        {
-          /* Hmmm, lets not treat this as fatal */
-          fprintf(stderr, "Can't allocate memory for kernel symbol table\n");
-        }
-       else
-        bzero(kern_sym_tbl, (kern_sym_count * sizeof(kern_sym_t)));
-    }
-  else
-    {
-      /* Hmmm, lets not treat this as fatal */
-      fprintf(stderr, "No kernel symbol table \n");
-    }
-
-  for (i=0; i<kern_sym_count; i++)
-    {
-      bzero(tmpstr, 1024);
-      if (fscanf(fp, "%lx %c %s", &kern_sym_tbl[i].k_sym_addr, &inchr, tmpstr) != 3)
-       break;
-      else
-       {
-         len = strlen(tmpstr);
-         kern_sym_tbl[i].k_sym_name = malloc(len + 1);
-
-         if (kern_sym_tbl[i].k_sym_name == (char *)0)
-           {
-             fprintf(stderr, "Can't allocate memory for symbol name [%s]\n", tmpstr);
-             kern_sym_tbl[i].k_sym_name = (char *)0;
-             len = 0;
-           }
-         else
-           strcpy(kern_sym_tbl[i].k_sym_name, tmpstr);
-
-         kern_sym_tbl[i].k_sym_len = len;
-       }
-    } /* end for */
-
-  if (i != kern_sym_count)
-    {
-      /* Hmmm, didn't build up entire table from nm */
-      /* scrap the entire thing */
-      if (kern_sym_tbl)
-       free (kern_sym_tbl);
-      kern_sym_tbl = (kern_sym_t *)0;
-      kern_sym_count = 0;
-    }
-
-  fclose(fp);
-
-  /* Remove the temporary nm file */
-  unlink(tmp_nm_file);
+       /*
+        * Parse the output from the nm command
+        */
+       if ((fp = fopen(tmp_nm_file, "r")) == NULL) {
+               /* Hmmm, let's not treat this as fatal */
+               fprintf(stderr, "Failed to open nm symbol file [%s]\n", tmp_nm_file);
+               return;
+       }
+       /*
+        * Count the number of symbols in the nm symbol table
+        */
+       kern_sym_count = 0;
+
+       while ((inchr = getc(fp)) != -1) {
+               if (inchr == '\n') {
+                       kern_sym_count++;
+               }
+       }
+       rewind(fp);
+
+       /*
+        * Malloc the space for symbol table
+        */
+       if (kern_sym_count > 0) {
+               kern_sym_tbl = malloc(kern_sym_count * sizeof(kern_sym_t));
+
+               if (!kern_sym_tbl) {
+                       /*
+                        * Hmmm, lets not treat this as fatal
+                        */
+                       fprintf(stderr, "Can't allocate memory for kernel symbol table\n");
+               } else {
+                       bzero(kern_sym_tbl, kern_sym_count * sizeof(kern_sym_t));
+               }
+       } else {
+               /*
+                * Hmmm, lets not treat this as fatal
+                */
+               fprintf(stderr, "No kernel symbol table \n");
+       }
+       for (i = 0; i < kern_sym_count; i++) {
+               bzero(tmpstr, 1024);
+
+               if (fscanf(fp, "%p %c %s", &kern_sym_tbl[i].k_sym_addr, &inchr, tmpstr) != 3) {
+                       break;
+               } else {
+                       len = strlen(tmpstr);
+                       kern_sym_tbl[i].k_sym_name = malloc(len + 1);
+
+                       if (kern_sym_tbl[i].k_sym_name == NULL) {
+                               fprintf(stderr, "Can't allocate memory for symbol name [%s]\n", tmpstr);
+                               kern_sym_tbl[i].k_sym_name = NULL;
+                               len = 0;
+                       } else {
+                               strcpy(kern_sym_tbl[i].k_sym_name, tmpstr);
+                       }
+
+                       kern_sym_tbl[i].k_sym_len = len;
+               }
+       }
+       if (i != kern_sym_count) {
+               /*
+                * Hmmm, didn't build up entire table from nm
+                * scrap the entire thing
+                */
+               free(kern_sym_tbl);
+               kern_sym_tbl = NULL;
+               kern_sym_count = 0;
+       }
+       fclose(fp);
 
+       /*
+        * Remove the temporary nm file
+        */
+       unlink(tmp_nm_file);
 #if 0
-  /* Dump the kernel symbol table */
-  for (i=0; i < kern_sym_count; i++)
-    {
-      if (kern_sym_tbl[i].k_sym_name)
-         printf ("[%d] 0x%x    %s\n", i, 
-                 kern_sym_tbl[i].k_sym_addr, kern_sym_tbl[i].k_sym_name);
-      else
-         printf ("[%d] 0x%x    %s\n", i, 
-                 kern_sym_tbl[i].k_sym_addr, "No symbol name");
-    }
+       /*
+        * Dump the kernel symbol table
+        */
+       for (i = 0; i < kern_sym_count; i++) {
+               if (kern_sym_tbl[i].k_sym_name) {
+                       printf ("[%d] %-16p    %s\n", i, 
+                               kern_sym_tbl[i].k_sym_addr, kern_sym_tbl[i].k_sym_name);
+               } else {
+                       printf ("[%d] %-16p    %s\n", i, 
+                               kern_sym_tbl[i].k_sym_addr, "No symbol name");
+               }
+       }
 #endif
 }
 
-char *
-pc_to_string(unsigned int pc, int max_len, int mode)
+void
+pc_to_string(char *pcstring, uintptr_t pc, int max_len, int mode)
 {
-  int ret;
-  int len;
-
-  int binary_search();
-
-  if (mode == 0)
-    {
-      sprintf(pcstring, "0x%-8x [usermode addr]", pc);
-      return(pcstring);
-    }
-
-  ret=0;
-  ret = binary_search(kern_sym_tbl, 0, kern_sym_count-1, pc);
-
-  if (ret == -1)
-    {
-      sprintf(pcstring, "0x%x", pc);
-      return(pcstring);
-    }
-  else if (kern_sym_tbl[ret].k_sym_name == (char *)0)
-    {
-      sprintf(pcstring, "0x%x", pc);
-      return(pcstring);
-    }
-  else
-    {
-      if ((len = kern_sym_tbl[ret].k_sym_len) > (max_len - 8))
-           len = max_len - 8;
-
-      memcpy(pcstring, kern_sym_tbl[ret].k_sym_name, len);
-      sprintf(&pcstring[len], "+0x%-5lx", pc - kern_sym_tbl[ret].k_sym_addr);
-
-      return (pcstring);
-    }
+       int ret;
+       int len;
+
+       if (mode == USER_MODE) {
+               sprintf(pcstring, "%-16lx [usermode addr]", pc);
+               return;
+       }
+       ret = binary_search(kern_sym_tbl, 0, kern_sym_count-1, pc);
+
+       if (ret == -1 || kern_sym_tbl[ret].k_sym_name == NULL) {
+               sprintf(pcstring, "%-16lx", pc);
+               return;
+       }
+       if ((len = kern_sym_tbl[ret].k_sym_len) > (max_len - 8)) {
+               len = max_len - 8;
+       }
+
+       memcpy(pcstring, kern_sym_tbl[ret].k_sym_name, len);
+
+       sprintf(&pcstring[len], "+0x%-5lx", pc - (uintptr_t)kern_sym_tbl[ret].k_sym_addr);
 }
 
 
-/* Return -1 if not found, else return index */
-int binary_search(list, low, high, addr)
-kern_sym_t *list;
-int low, high;
-unsigned int  addr;
+/*
+ * Return -1 if not found, else return index
+ */
+int
+binary_search(kern_sym_t *list, int low, int high, uintptr_t addr)
 {
-  int mid;
-  
-  mid = (low + high) / 2;
+       int mid;
   
-  if (low > high)
-    return (-1);   /* failed */
-  else if (low + 1 == high)
-    { 
-      if (list[low].k_sym_addr <= addr &&
-          addr < list[high].k_sym_addr)
-       {
-         /* We have a range match */
-         return(low);
-       }
-      else if (list[high].k_sym_addr <= addr)
-       {
-         return(high);
-       }
-      else
-       return(-1);   /* Failed */
-    }      
-  else if (addr < list[mid].k_sym_addr)
-    {
-      return(binary_search (list, low, mid, addr));
-    }
-  else
-    {
-      return(binary_search (list, mid, high, addr));
-    }
+       if (kern_sym_count == 0) {
+               return -1;
+       }
+
+       if (low > high) {
+               return -1;   /* failed */
+       }
+
+       if (low + 1 == high) { 
+               if ((uintptr_t)list[low].k_sym_addr <= addr && addr < (uintptr_t)list[high].k_sym_addr) {
+                       /*
+                        * We have a range match
+                        */
+                       return low;
+               }
+               if ((uintptr_t)list[high].k_sym_addr <= addr) {
+                       return high;
+               }
+               /*
+                * Failed
+                */
+               return -1;
+       }      
+       mid = (low + high) / 2;
+
+       if (addr < (uintptr_t)list[mid].k_sym_addr) {
+               return binary_search(list, low, mid, addr);
+       }
+
+       return binary_search(list, mid, high, addr);
 }
 
+
 void
-open_logfile(char *path)
+open_logfile(const char *path)
 {
-    log_fp = fopen(path, "a");
-
-    if (!log_fp)
-      {
-       /* failed to open path */
-       fprintf(stderr, "latency: failed to open logfile [%s]\n", path);
-       exit_usage();
-      }
+       log_fp = fopen(path, "a");
+
+       if (!log_fp) {
+               /*
+                * failed to open path
+                */
+               fprintf(stderr, "latency: failed to open logfile [%s]\n", path);
+               exit_usage();
+       }
+}
+
+
+void
+open_rawfile(const char *path)
+{
+       RAW_fd = open(path, O_RDONLY);
+
+       if (RAW_fd == -1) {
+               /*
+                * failed to open path
+                */
+               fprintf(stderr, "latency: failed to open RAWfile [%s]\n", path);
+               exit_usage();
+       }
+}
+
+
+void
+getdivisor(void)
+{
+       mach_timebase_info_data_t info;
+       
+       (void)mach_timebase_info(&info);
+
+       divisor = ((double)info.denom / (double)info.numer) * 1000;
 }
index 958b2c5441ae1d3d067c901730fb91604987d8ee..91a143054b2b62c6676baa192afb3eaeb9721986 100644 (file)
@@ -8,7 +8,7 @@ MANPAGES = login.1
 
 Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -D__FBSDID=__RCSID
@@ -27,6 +27,5 @@ Install_Program_Mode = 04555
 
 after_install:
        $(INSTALL_DIRECTORY) "$(DSTROOT)"/private/etc/pam.d
-       $(INSTALL_FILE) login.pam "$(DSTROOT)"/private/etc/pam.d/login
-       sed -e '/pam_launchd.so/d' < login.pam > "$(OBJROOT)"/login.term
-       $(INSTALL_FILE) "$(OBJROOT)"/login.term "$(DSTROOT)"/private/etc/pam.d/login.term
+       $(INSTALL_FILE) pam.d/login "$(DSTROOT)"/private/etc/pam.d/login
+       $(INSTALL_FILE) pam.d/login.term "$(DSTROOT)"/private/etc/pam.d/login.term
index 2b0d828ba693a5c06c70bf7395566fa3a3d39816..259907fd505a41ff1f8655ed4483207f386b2ef3 100644 (file)
@@ -105,6 +105,8 @@ __FBSDID("$FreeBSD: src/usr.bin/login/login.c,v 1.106 2007/07/04 00:00:40 scf Ex
 
 #ifdef USE_BSM_AUDIT
 #include <bsm/libbsm.h>
+#include <bsm/audit.h>
+#include <bsm/audit_session.h>
 #include <bsm/audit_uevents.h>
 #endif
 
@@ -127,7 +129,7 @@ __FBSDID("$FreeBSD: src/usr.bin/login/login.c,v 1.106 2007/07/04 00:00:40 scf Ex
 #include "pathnames.h"
 
 #ifdef USE_PAM
-static int              auth_pam(void);
+static int              auth_pam(int skip_auth);
 #endif /* USE_PAM */
 static void             bail(int, int);
 #ifdef USE_PAM
@@ -228,7 +230,7 @@ static struct lastlogx lastlog;
 #endif /* USE_PAM */
 
 #ifdef USE_BSM_AUDIT
-au_tid_t tid;
+extern au_tid_addr_t tid;
 #endif /* USE_BSM_AUDIT */
 #endif /* __APPLE__ */
 
@@ -386,16 +388,19 @@ main(int argc, char *argv[])
 #ifdef __APPLE__
 #ifdef USE_BSM_AUDIT
        /* Set the terminal id */
-       audit_set_terminal_id(&tid);
+       au_tid_t old_tid;
+       audit_set_terminal_id(&old_tid);
+       tid.at_type = AU_IPv4;
+       tid.at_addr[0] = old_tid.machine;
        if (fstat(STDIN_FILENO, &st) < 0) {
                fprintf(stderr, "login: Unable to stat terminal\n");
                au_login_fail("Unable to stat terminal", 1);
                exit(-1);
        }
        if (S_ISCHR(st.st_mode)) {
-               tid.port = st.st_rdev;
+               tid.at_port = st.st_rdev;
        } else {
-               tid.port = 0;
+               tid.at_port = 0;
        }
 #endif /* USE_BSM_AUDIT */
 #endif /* __APPLE__ */
@@ -483,8 +488,11 @@ main(int argc, char *argv[])
                 */
                if (pwd != NULL && fflag &&
                    (uid == (uid_t)0 || uid == (uid_t)pwd->pw_uid)) {
-                       /* already authenticated */
+#ifdef USE_PAM
+                       rval = auth_pam(fflag);
+#else
                        rval = 0;
+#endif /* USE_PAM */
 #ifdef USE_BSM_AUDIT
                        auditsuccess = 0; /* opened a terminal window only */
 #endif
@@ -500,7 +508,7 @@ main(int argc, char *argv[])
                        fflag = 0;
                        (void)setpriority(PRIO_PROCESS, 0, -4);
 #ifdef USE_PAM
-                       rval = auth_pam();
+                       rval = auth_pam(fflag);
 #else
                {
                        char* salt = pwd->pw_passwd;
@@ -585,7 +593,7 @@ main(int argc, char *argv[])
 #ifdef USE_BSM_AUDIT
        /* Audit successful login. */
        if (auditsuccess)
-               au_login_success();
+               au_login_success(fflag);
 #endif
 
 #ifdef LOGIN_CAP
@@ -778,12 +786,14 @@ main(int argc, char *argv[])
        }
 #endif /* !__APPLE__ */
 #ifdef USE_PAM
-       pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED);
-       if (pam_err != PAM_SUCCESS) {
-               pam_syslog("pam_setcred()");
-               bail(NO_SLEEP_EXIT, 1);
+       if (!fflag) {
+               pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED);
+               if (pam_err != PAM_SUCCESS) {
+                       pam_syslog("pam_setcred()");
+                       bail(NO_SLEEP_EXIT, 1);
+               }
+               pam_cred_established = 1;
        }
-       pam_cred_established = 1;
 
        pam_err = pam_open_session(pamh, pam_silent);
        if (pam_err != PAM_SUCCESS) {
@@ -872,7 +882,6 @@ main(int argc, char *argv[])
        (void)setgid(pwd->pw_gid);
        if (initgroups(username, pwd->pw_gid) == -1)
                syslog(LOG_ERR, "login: initgroups() failed");
-       pwd = getpwnam(username); // 7258548
        (void) setuid(rootlogin ? 0 : pwd->pw_uid);             
 #else /* !__APPLE__ */
        if (setusercontext(lc, pwd, pwd->pw_uid,
@@ -907,7 +916,7 @@ main(int argc, char *argv[])
        if (pwd->pw_shell) {
                (void)setenv("SHELL", pwd->pw_shell, 1);
        } else {
-               syslog(LOG_ERR, "pwd->pw_shell not set - exiting", username);
+               syslog(LOG_ERR, "pwd->pw_shell not set - exiting");
                bail(NO_SLEEP_EXIT, 1);
        }
        if (pwd->pw_dir) {
@@ -964,7 +973,7 @@ main(int argc, char *argv[])
                  break;
                }
        } while (0);
-#endif __APPLE__
+#endif /* __APPLE__ */
 
        if (!quietlog) {
 #ifdef LOGIN_CAP
@@ -1058,54 +1067,59 @@ main(int argc, char *argv[])
  * fall back to a different authentication mechanism.
  */
 static int
-auth_pam(void)
+auth_pam(int skip_auth)
 {
        const char *tmpl_user;
        const void *item;
        int rval;
 
-       pam_err = pam_authenticate(pamh, pam_silent);
-       switch (pam_err) {
+       rval = 0;
+       
+       if (skip_auth == 0)
+       {
+               pam_err = pam_authenticate(pamh, pam_silent);
+               switch (pam_err) {
 
-       case PAM_SUCCESS:
-               /*
-                * With PAM we support the concept of a "template"
-                * user.  The user enters a login name which is
-                * authenticated by PAM, usually via a remote service
-                * such as RADIUS or TACACS+.  If authentication
-                * succeeds, a different but related "template" name
-                * is used for setting the credentials, shell, and
-                * home directory.  The name the user enters need only
-                * exist on the remote authentication server, but the
-                * template name must be present in the local password
-                * database.
-                *
-                * This is supported by two various mechanisms in the
-                * individual modules.  However, from the application's
-                * point of view, the template user is always passed
-                * back as a changed value of the PAM_USER item.
-                */
-               pam_err = pam_get_item(pamh, PAM_USER, &item);
-               if (pam_err == PAM_SUCCESS) {
-                       tmpl_user = (const char *)item;
-                       if (strcmp(username, tmpl_user) != 0)
-                               pwd = getpwnam(tmpl_user);
-               } else {
-                       pam_syslog("pam_get_item(PAM_USER)");
+               case PAM_SUCCESS:
+                       /*
+                        * With PAM we support the concept of a "template"
+                        * user.  The user enters a login name which is
+                        * authenticated by PAM, usually via a remote service
+                        * such as RADIUS or TACACS+.  If authentication
+                        * succeeds, a different but related "template" name
+                        * is used for setting the credentials, shell, and
+                        * home directory.  The name the user enters need only
+                        * exist on the remote authentication server, but the
+                        * template name must be present in the local password
+                        * database.
+                        *
+                        * This is supported by two various mechanisms in the
+                        * individual modules.  However, from the application's
+                        * point of view, the template user is always passed
+                        * back as a changed value of the PAM_USER item.
+                        */
+                       pam_err = pam_get_item(pamh, PAM_USER, &item);
+                       if (pam_err == PAM_SUCCESS) {
+                               tmpl_user = (const char *)item;
+                               if (strcmp(username, tmpl_user) != 0)
+                                       pwd = getpwnam(tmpl_user);
+                       } else {
+                               pam_syslog("pam_get_item(PAM_USER)");
+                       }
+                       rval = 0;
+                       break;
+
+               case PAM_AUTH_ERR:
+               case PAM_USER_UNKNOWN:
+               case PAM_MAXTRIES:
+                       rval = 1;
+                       break;
+
+               default:
+                       pam_syslog("pam_authenticate()");
+                       rval = -1;
+                       break;
                }
-               rval = 0;
-               break;
-
-       case PAM_AUTH_ERR:
-       case PAM_USER_UNKNOWN:
-       case PAM_MAXTRIES:
-               rval = 1;
-               break;
-
-       default:
-               pam_syslog("pam_authenticate()");
-               rval = -1;
-               break;
        }
 
        if (rval == 0) {
@@ -1114,11 +1128,18 @@ auth_pam(void)
                case PAM_SUCCESS:
                        break;
                case PAM_NEW_AUTHTOK_REQD:
-                       pam_err = pam_chauthtok(pamh,
-                           pam_silent|PAM_CHANGE_EXPIRED_AUTHTOK);
-                       if (pam_err != PAM_SUCCESS) {
-                               pam_syslog("pam_chauthtok()");
-                               rval = 1;
+                       if (skip_auth == 0)
+                       {
+                               pam_err = pam_chauthtok(pamh,
+                                   pam_silent|PAM_CHANGE_EXPIRED_AUTHTOK);
+                               if (pam_err != PAM_SUCCESS) {
+                                       pam_syslog("pam_chauthtok()");
+                                       rval = 1;
+                               }
+                       }
+                       else
+                       {
+                               pam_syslog("pam_acct_mgmt()");
                        }
                        break;
                default:
index 1d0e72e258ada8b27a808b52a8e04496a2b32ab8..fd6d1726806b9bc7a68bc08372466fe57aa70a50 100644 (file)
@@ -28,7 +28,7 @@
 void   login_fbtab(char *, uid_t, gid_t);
 
 #ifdef USE_BSM_AUDIT
-void   au_login_success(void);
+void   au_login_success(int fflag);
 void   au_login_fail(const char *errmsg, int na);
 void   audit_logout(void);
 #endif
diff --git a/login.tproj/login.pam b/login.tproj/login.pam
deleted file mode 100644 (file)
index 494813a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# login: auth account password session
-auth       optional       pam_krb5.so
-auth       optional       pam_mount.so
-auth       sufficient     pam_serialnumber.so serverinstall legacy
-auth       required       pam_opendirectory.so
-account    required       pam_nologin.so
-account    required       pam_opendirectory.so
-password   required       pam_deny.so
-session    required       pam_launchd.so
-session    required       pam_uwtmp.so
-session    optional       pam_mount.so
index 4f6bb9d913111f137fdd824851f7c2ccfa35d025..6fc37eeb2a96fe2fd767ad2f9d9d1ef3dbf64a4a 100644 (file)
@@ -38,11 +38,13 @@ __FBSDID("$FreeBSD: src/usr.bin/login/login_audit.c,v 1.2 2007/05/07 11:01:36 dw
 
 #include <bsm/libbsm.h>
 #include <bsm/audit_uevents.h>
+#include <bsm/audit_session.h>
 
 #include <err.h>
 #include <errno.h>
 #include <pwd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <strings.h>
 #include <unistd.h>
 
@@ -51,49 +53,70 @@ __FBSDID("$FreeBSD: src/usr.bin/login/login_audit.c,v 1.2 2007/05/07 11:01:36 dw
 /*
  * Audit data
  */
-static au_tid_t tid;
+au_tid_addr_t tid;
 
 /*
  * The following tokens are included in the audit record for a successful
  * login: header, subject, return.
  */
 void
-au_login_success(void)
+au_login_success(int fflag)
 {
        token_t *tok;
        int aufd;
-       au_mask_t aumask;
-       auditinfo_t auinfo;
+       auditinfo_addr_t auinfo;
        uid_t uid = pwd->pw_uid;
        gid_t gid = pwd->pw_gid;
        pid_t pid = getpid();
        long au_cond;
 
-       /* If we are not auditing, don't cut an audit record; just return. */
+       /* Determine whether auditing is enabled. */
        if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
                if (errno == ENOSYS)
                        return;
                errx(1, "login: Could not determine audit condition");
        }
-       if (au_cond == AUC_NOAUDIT)
-               return;
 
-       /* Compute and set the user's preselection mask. */
-       if (au_user_mask(pwd->pw_name, &aumask) == -1)
-               errx(1, "login: Could not set audit mask\n");
+       /* Initialize with the current audit info. */
+       if (getaudit_addr(&auinfo, sizeof(auinfo)) < 0) {
+               err(1, "getaudit_addr");
+       }
+       auinfo.ai_auid = pwd->pw_uid;
+       memcpy(&auinfo.ai_termid, &tid, sizeof(auinfo.ai_termid));
+
+       /* Do the SessionCreate() equivalent. */
+       if (!fflag) {
+               auinfo.ai_asid = AU_ASSIGN_ASID;
+               auinfo.ai_flags |= AU_SESSION_FLAG_HAS_TTY;
+               auinfo.ai_flags |= AU_SESSION_FLAG_HAS_AUTHENTICATED;
+       }
 
-       /* Set the audit info for the user. */
-       auinfo.ai_auid = uid;
-       auinfo.ai_asid = pid;
-       bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid));
-       bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask));
-       if (setaudit(&auinfo) != 0)
-               err(1, "login: setaudit failed");
+       if (au_cond != AUC_NOAUDIT) {
+               /* Compute and set the user's preselection mask. */
+               if (au_user_mask(pwd->pw_name, &auinfo.ai_mask) < 0) {
+                       errx(1, "login: Could not set audit mask\n");
+               }
+       }
+
+       if (setaudit_addr(&auinfo, sizeof(auinfo)) < 0)
+               err(1, "login: setaudit_addr failed");
+       
+       char *session = NULL;
+       asprintf(&session, "%x", auinfo.ai_asid);
+       if (NULL == session) {
+               errx(1, "asprintf failed");
+       }
+       setenv("SECURITYSESSIONID", session, 1);
+       free(session);
+       
+       /* If we are not auditing, don't cut an audit record; just return. */
+       if (au_cond == AUC_NOAUDIT)
+               return;
 
        if ((aufd = au_open()) == -1)
                errx(1,"login: Audit Error: au_open() failed");
 
-       if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid,
+       if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, gid, pid,
            pid, &tid)) == NULL)
                errx(1, "login: Audit Error: au_to_subject32() failed");
        au_write(aufd, tok);
@@ -137,14 +160,14 @@ au_login_fail(const char *errmsg, int na)
                 * Non attributable event.  Assuming that login is not called
                 * within a user's session => auid,asid == -1.
                 */
-               if ((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1,
+               if ((tok = au_to_subject32_ex(-1, geteuid(), getegid(), -1, -1,
                    pid, -1, &tid)) == NULL)
                        errx(1, "login: Audit Error: au_to_subject32() failed");
        } else {
                /* We know the subject -- so use its value instead. */
                uid = pwd->pw_uid;
                gid = pwd->pw_gid;
-               if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid,
+               if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid,
                    gid, pid, pid, &tid)) == NULL)
                        errx(1, "login: Audit Error: au_to_subject32() failed");
        }
@@ -190,7 +213,7 @@ audit_logout(void)
                errx(1, "login: Audit Error: au_open() failed");
 
        /* The subject that is created (euid, egid of the current process). */
-       if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid, gid, pid,
+       if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, gid, pid,
            pid, &tid)) == NULL)
                errx(1, "login: Audit Error: au_to_subject32() failed");
        au_write(aufd, tok);
diff --git a/login.tproj/pam.d/login b/login.tproj/pam.d/login
new file mode 100644 (file)
index 0000000..b035d54
--- /dev/null
@@ -0,0 +1,12 @@
+# login: auth account password session
+auth       optional       pam_krb5.so use_kcminit
+auth       optional       pam_ntlm.so try_first_pass
+auth       optional       pam_mount.so try_first_pass
+auth       sufficient     pam_serialnumber.so try_first_pass serverinstall
+auth       required       pam_opendirectory.so try_first_pass
+account    required       pam_nologin.so
+account    required       pam_opendirectory.so
+password   required       pam_opendirectory.so
+session    required       pam_launchd.so
+session    required       pam_uwtmp.so
+session    optional       pam_mount.so
diff --git a/login.tproj/pam.d/login.term b/login.tproj/pam.d/login.term
new file mode 100644 (file)
index 0000000..2c57c34
--- /dev/null
@@ -0,0 +1,4 @@
+# login: account session
+account    required       pam_nologin.so
+account    required       pam_opendirectory.so
+session    required       pam_uwtmp.so
index c35c1f364b7df995b27621a404e0daa899a52616..fee842d6de0f5f1e840b9ed5fc9b3c63cf263a1f 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/libexec
 CFILES = makekey.c
 MANPAGES = makekey.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 9e5601810b819e7face057cf319d5a04a37c00bd..4ea92553b0d6f03dac7991e1cde0082264b33811 100644 (file)
@@ -9,8 +9,8 @@
 
 #include <mach/mach.h>
 #include <mach/task.h>
-
-#include <sys/resource.h>
+#include <mach/thread_act.h>
+#include <mach/thread_policy.h>
 
 #include <errno.h>
 #include <getopt.h>
 
 void usage(void);
 
-#ifndef PRIO_DARWIN_PROCESS
-#define PRIO_DARWIN_PROCESS 4       /* Second argument is a PID */
-#endif
 
 void 
 usage(void)
 {
-               fprintf(stderr, "Usage: mean -t <pid>\n");
-               fprintf(stderr, "\tthrottle <pid>'s usage of cpu, I/O, and networking\n");
-               fprintf(stderr, "mean -u <pid>\n");
-               fprintf(stderr,  "\treturn <pid> to normal priority\n");
-               fprintf(stderr, "mean -[s|r] <pid>\n");
-               fprintf(stderr,  "\tsuspend or resume <pid>\n");
+               fprintf(stderr, "Usage: mean -[r|s|u] <pid>\n");
+               fprintf(stderr,  "\tLower <pid>'s priority.\n");
+               fprintf(stderr,  "\t-u: return <pid> to normal priority\n");
+               fprintf(stderr,  "\t-r: resume <pid>\n");
+               fprintf(stderr,  "\t-s: suspend <pid>\n");
                exit(0);
 }
 
 int 
 main(int argc, char **argv)
 {
-       int pid, err, ch;
+       int pid, err, i, ch;
+       unsigned int count;
        mach_port_t task;
-       int priority = 0;
+       thread_act_array_t threads;
+       thread_precedence_policy_data_t policy;
        
-       boolean_t do_resume = 0, do_suspend = 0;
-       boolean_t do_throttle = 0, do_undo = 0;
+       boolean_t do_high = 0, do_resume = 0, do_suspend = 0;
+       boolean_t do_low = 1;
        
        if (argc < 2) 
                usage();
        
-       while ((ch = getopt(argc, argv, "rstu")) != -1)
+       while ((ch = getopt(argc, argv, "rsu")) != -1)
        switch (ch) {
                case 'u':
-                       do_undo = 1;
+                       do_high = 1;
+                       do_low = 0;
                        continue;
                case 'r':
                        do_resume = 1;
+                       do_low = 0;
                        continue;
                case 's':
                        do_suspend = 1;
-                       continue;
-               case 't':
-                       do_throttle = 1;
+                       do_low = 0;
                        continue;
                default:
                        usage();
@@ -74,40 +72,57 @@ main(int argc, char **argv)
        pid = atoi(*argv);
        if (!pid) 
                usage();
+       
+       err = task_for_pid(mach_task_self(), pid, &task);
+       if (err) {
+               fprintf(stderr, "Failed to get task port (%d)\n", err);
+               exit(0);
+       }
 
-       if (do_throttle || do_undo) {
-               priority = PRIO_DARWIN_BG;
-
-               if (do_undo)
-                       priority = 0;
+       if (do_low || do_high) {
 
-               err = setpriority(PRIO_DARWIN_PROCESS, pid, priority);
+               err = task_threads(task, &threads, &count);
                if (err) {
-                       fprintf(stderr, "Failed to set priority (%d)\n", errno);
+                       fprintf(stderr, "Failed to get thread list (%d)\n", err);
                        exit(0);
                }
-       }
 
-       if (do_suspend || do_resume) {
-               err = task_for_pid(mach_task_self(), pid, &task);
-               if (err) {
-                       fprintf(stderr, "Failed to get task port (%d)\n", err);
-                       exit(0);
-               }
+               if (do_low)
+                       policy.importance = -100;
+               else
+                       policy.importance = 0;
 
-               if (do_suspend) {
-                       err = task_suspend(task);
+               for (i = 0; i < count; i++) {
+                       err = thread_policy_set(threads[i], 
+                                       THREAD_PRECEDENCE_POLICY, 
+                                       (thread_policy_t) &policy, 
+                                       THREAD_PRECEDENCE_POLICY_COUNT);
                        if (err) {
-                               fprintf(stderr, "Failed to suspend task (%d)\n", err);
+                               fprintf(stderr, "Failed to set thread priority (%d)\n", err);
+                               exit(0);
                        }
-
                }
 
-               if (do_resume) {
-                       err = task_resume(task);
-                       if (err) {
-                               fprintf(stderr, "Failed to resume task (%d)\n", err);
-                       }
+               printf("Process %d's threads set to %s priority.\n", pid, 
+                               (do_low ? "lowest" : "highest"));       
+       }
+       
+       if (do_suspend) {
+               err = task_suspend(task);
+               if (err) {
+                       fprintf(stderr, "Failed to suspend task (%d)\n", err);
+               } else {
+                       printf("Process %d suspended.\n", pid);
+               }
+               
+       }
+       
+       if (do_resume) {
+               err = task_resume(task);
+               if (err) {
+                       fprintf(stderr, "Failed to resume task (%d)\n", err);
+               } else {
+                       printf("Process %d resumed.\n", pid);
                }
        }
 
index 7ca1598af2ee86af4000d8a7e9f32b87c9b83230..b2a5c40c2176b0e4c1d4cf15de6c8dd74f95e59f 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = mkfile.c
 MANPAGES = mkfile.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 65aa49deecf44d5364eeaf0f300a4fe27d6285e8..90849085bb2e1849a41647eb70a5326df5859954 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = newgrp.c
 MANPAGES = newgrp.1
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID
 Extra_LD_Flags = -dead_strip
 
index 733213455bbc13f87372e3542f26532a5ed6b6dd..d713444d33f3c752ea750664fb3039635c9354f7 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /sbin
 CFILES = nologin.c
 MANPAGES = nologin.5 nologin.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID
 Extra_LD_Flags = -dead_strip
 
index 5689c52112278727898b94f366edf9149ce92e9b..4ce24683c7c2491400164c7e6c2b3c6bf10c676a 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = nvram.c
 MANPAGES = nvram.8
 
-Extra_CC_Flags = -mdynamic-no-pic -Wall -Werror
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_Frameworks = -framework CoreFoundation -framework IOKit
index 26e486f92aabd451214fc1ae8ec65cbc3f8b77ea..9cb94ae67ac5dee592fd574aee69d29eb0a9de4f 100644 (file)
@@ -46,6 +46,8 @@ static void ClearOFVariables(void);
 static void ClearOFVariable(const void *key,const void *value,void *context);
 static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value);
 
+static void NVRamSyncNow(char *name);
+
 // Global Variables
 static char                *gToolName;
 static io_registry_entry_t gOptionsRef;
@@ -325,7 +327,7 @@ static void ParseXMLFile(char *fileName)
                     NULL,      
                     NULL,
                     &errorCode) || data == NULL ) {
-          errx(1, "Error reading XML file (%d)", errorCode);
+          errx(1, "Error reading XML file (%d)", (int)errorCode);
         }
 
         CFRelease(fileURL);
@@ -382,6 +384,7 @@ static void SetOrGetOFVariable(char *str)
     value = str;
     
     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));
@@ -495,6 +498,10 @@ static void DeleteOFVariable(char *name)
   SetOFVariable(kIONVRAMDeletePropertyKey, name);
 }
 
+static void NVRamSyncNow(char *name)
+{
+  SetOFVariable(kIONVRAMSyncNowPropertyKey, name);
+}
 
 // PrintOFVariables()
 //
index b3136d1c3b389cfcdf7d44e44e0e664e6dd9a000..d0303f12d5a5405f9bb8cbc67edbc83a6016582d 100644 (file)
@@ -1,13 +1,12 @@
 Project = passwd
 Install_Dir = /usr/bin
 
-HFILES = stringops.h
-CFILES = passwd.c file_passwd.c stringops.c
+CFILES = passwd.c file_passwd.c
 MANPAGES = passwd.1
 
 Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 ifeq ($(Embedded),NO)
@@ -17,7 +16,7 @@ endif
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
 
-Install_Program_Mode = 04555
+Install_Program_Mode = 0555
 
 after_install:
        $(INSTALL_DIRECTORY) "$(DSTROOT)"/private/etc/pam.d
index ffc81ca21a287ff2d81d2c8da9c472f01728de52..002f38e4b8266e19bfa840bab8c8f6cd22c791fb 100644 (file)
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
 #include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <errno.h>
-#include <fcntl.h>
 #include <sysexits.h>
+#include <unistd.h>
 #include <sys/time.h>
-#include <sys/resource.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
-#include "stringops.h"
-
-#define TEMP_FILE_TEMPLATE "/var/run/.pwtmpXXXXXX"
-#define LOCK_FILE "/var/run/.passwd.lock"
 
 #define _PASSWD_FILE "/etc/master.passwd"
 #define _COMPAT_FILE "/etc/passwd"
 #define _PASSWD_FIELDS 10
 #define BUFSIZE 8192
 
-extern void getpasswd(char *, int, int, int, int, char *, char **, char**, char **);
-
-//static int do_compat = 1; (unused)
+void getpasswd(char *, int, int, int, int, char *, char **, char**, char **);
 
-char *
-getline(FILE *fp)
+static struct passwd *
+parse_user(char *line, size_t len)
 {
-       static char s[BUFSIZE];
-       int len;
-
-    s[0] = '\0';
-
-    fgets(s, BUFSIZE, fp);
-    if (s == NULL || s[0] == '\0') return NULL;
-
-       if (s[0] == '#') return s;
-
-       len = strlen(s) - 1;
-       s[len] = '\0';
-
-       return s;
-}
-
-struct passwd *
-parse_user(char *line)
-{
-       static struct passwd pw = {0};
-       char **tokens;
-       int i, len;
-
-       if (pw.pw_name != NULL) free(pw.pw_name);
-       pw.pw_name = NULL;
-       if (pw.pw_passwd != NULL) free(pw.pw_passwd);
-       pw.pw_passwd = NULL;
-       if (pw.pw_gecos != NULL) free(pw.pw_gecos);
-       pw.pw_gecos = NULL;
-       if (pw.pw_dir != NULL) free(pw.pw_dir);
-       pw.pw_dir = NULL;
-       if (pw.pw_shell != NULL) free(pw.pw_shell);
-       pw.pw_shell = NULL;
-
-       if (pw.pw_class != NULL) free(pw.pw_class);
-       pw.pw_class = NULL;
-
-       if (line == NULL) return (struct passwd *)NULL;
-       tokens = explode(line, ':');
-       len = listLength(tokens);
-
-       if (len != _PASSWD_FIELDS)
-       {
-               freeList(tokens);
-               return (struct passwd *)NULL;
+       static struct passwd pw;
+       int i,j;
+       char *tokens[_PASSWD_FIELDS];
+       char *token = NULL;
+       bool comment = true;
+
+       free(pw.pw_name);
+       free(pw.pw_passwd);
+       free(pw.pw_class);
+       free(pw.pw_gecos);
+       free(pw.pw_dir);
+       free(pw.pw_shell);
+       memset(&pw, 0, sizeof(pw));
+
+       if (line == NULL) return NULL;
+
+       memset(&tokens, 0, sizeof(char *) * _PASSWD_FIELDS);
+
+       for (i = 0, j = 0; i < len && j < _PASSWD_FIELDS; ++i) {
+               int c = line[i];
+               if (!isspace(c) && c != '#') {
+                       comment = false;
+               }
+               if (!comment && token == NULL) {
+                       // start a new token
+                       token = &line[i];
+               } else if (token && (c == ':' || c == '\n')) {
+                       // end the current token
+                       // special case for empty token
+                       while (token[0] == ':' && token < &line[i]) {
+                               tokens[j++] = strdup("");
+                               ++token;
+                       }
+                       tokens[j++] = strndup(token, &line[i] - token);
+                       token = NULL;
+               }
        }
 
-       i = 0;
-       pw.pw_name = tokens[i++];
-       pw.pw_passwd = tokens[i++];
-       pw.pw_uid = atoi(tokens[i]);
-       free(tokens[i++]);
-       pw.pw_gid = atoi(tokens[i]);
-       free(tokens[i++]);
-       pw.pw_class = tokens[i++];
-       pw.pw_change = atoi(tokens[i]);
-       free(tokens[i++]);
-       pw.pw_expire = atoi(tokens[i]);
-       free(tokens[i++]);
-       pw.pw_gecos = tokens[i++];
-       pw.pw_dir = tokens[i++];
-       pw.pw_shell = tokens[i++];
+       if (comment || j != _PASSWD_FIELDS) return NULL;
+
+       j = 0;
+       pw.pw_name = tokens[j++];
+       pw.pw_passwd = tokens[j++];
+       pw.pw_uid = atoi(tokens[j]);
+       free(tokens[j++]);
+       pw.pw_gid = atoi(tokens[j]);
+       free(tokens[j++]);
+       pw.pw_class = tokens[j++];
+       pw.pw_change = atoi(tokens[j]);
+       free(tokens[j++]);
+       pw.pw_expire = atoi(tokens[j]);
+       free(tokens[j++]);
+       pw.pw_gecos = tokens[j++];
+       pw.pw_dir = tokens[j++];
+       pw.pw_shell = tokens[j++];
 
        return &pw;
 }
 
-struct passwd *
-find_user(char *uname, FILE *fp)
+static struct passwd *
+find_user(FILE *fp, char *uname)
 {
+       size_t len;
        char *line;
-       struct passwd *pw;
 
        rewind(fp);
 
-       while (NULL != (line = getline(fp)))
-       {
-               if (line[0] == '#') continue;
-               pw = parse_user(line);
-               if (pw == (struct passwd *)NULL) continue;
-               if (!strcmp(uname, pw->pw_name)) return pw;
+       while ((line = fgetln(fp, &len)) != NULL) {
+               struct passwd *pw = parse_user(line, len);
+               if (pw && strcmp(uname, pw->pw_name) == 0) {
+                       return pw;
+               }
        }
-
-       pw = parse_user(NULL);
-       return (struct passwd *)NULL;
+       return NULL;
 }
 
-void
-rewrite_file(char *pwname, FILE *fp, struct passwd *newpw, char *locn)
+static void
+rewrite_file(char *path, FILE *fp, struct passwd *newpw)
 {
-       char *line;
-       struct passwd *pw;
-       FILE *tfp, *cfp;
        int fd;
-       char fname[256];
+       char *line;
+       size_t len;
+       FILE *tfp = NULL;
+       char *tempname = NULL; // temporary master.passwd file
+
+       asprintf(&tempname, "%s.XXXXXX", path);
        
-       sprintf(fname, "%s.%.5d", TEMP_FILE_TEMPLATE, getpid());
-       fd = mkstemps(fname, 6);
-       if (fd == -1)
-       {
-               fprintf(stderr, "can't create temporary file \"%s\": ", fname);
-               perror("");
-               exit(1);
-       }
-       if (fchmod(fd, (S_IRUSR | S_IWUSR)) != 0)
-       {
-               close(fd);
-               unlink(fname);
-               fprintf(stderr, "can't set permissions for temporary file \"%s\": ", fname);
-               perror("");
-               exit(1);
+       fd = mkstemp(tempname);
+       if (fd == -1) {
+               err(EXIT_FAILURE, "%s", tempname);
        }
        tfp = fdopen(fd, "w+");
-       if (tfp == NULL)
-       {
-               close(fd);
-               unlink(fname);
-               fprintf(stderr, "can't write temporary file \"%s\": ", fname);
-               perror("");
-               exit(1);
-       }
-       
-       cfp = NULL;
-       if (!strcmp(pwname, _PASSWD_FILE))
-       {
-               cfp = fopen(_COMPAT_FILE, "w");
-               if (cfp == NULL)
-               {
-                       fprintf(stderr, "warning: can't write compatability file \"%s\": ",
-                               _COMPAT_FILE);
-                       perror("");
+       if (tfp == NULL || fchmod(fd, S_IRUSR | S_IWUSR) != 0) {
+               int save = errno;
+               unlink(tempname);
+               errno = save;
+               err(EXIT_FAILURE, "%s", tempname);
+       }
+       
+       while ((line = fgetln(fp, &len)) != NULL) {
+               struct passwd *pw = parse_user(line, len);
+
+               // if this is not the entry we're looking for or if parsing
+               // failed (likely a comment) then print the entry as is.
+               if (pw == NULL || strcmp(newpw->pw_name, pw->pw_name) != 0) {
+                       fwrite(line, sizeof(char), len, tfp);
+               } else {
+                       fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
+                               newpw->pw_name,
+                               newpw->pw_passwd,
+                               newpw->pw_uid,
+                               newpw->pw_gid,
+                               newpw->pw_class,
+                               newpw->pw_change,
+                               newpw->pw_expire,
+                               newpw->pw_gecos,
+                               newpw->pw_dir,
+                               newpw->pw_shell);
                }
        }
 
-       if (cfp != NULL)
-       {
-               fprintf(cfp, "#\n");
-               fprintf(cfp, "# 4.3BSD-compatable User Database\n");
-               fprintf(cfp, "#\n");
-               fprintf(cfp, "# Note that this file is not consulted for login.\n");
-               fprintf(cfp, "# It only exisits for compatability with 4.3BSD utilities.\n");
-               fprintf(cfp, "#\n");
-               fprintf(cfp, "# This file is automatically re-written by various system utilities.\n");
-               fprintf(cfp, "# Do not edit this file.  Changes will be lost.\n");
-               fprintf(cfp, "#\n");
+       // Move the temporary file into place.
+       if (fclose(tfp) != 0 || rename(tempname, path) != 0) {
+               int save = errno;
+               unlink(tempname);
+               errno = save;
+               err(EXIT_FAILURE, "%s", tempname);
        }
-       
-       rewind(fp);
-
-       while (NULL != (line = getline(fp)))
-       {
-               if (line[0] == '#')
-               {
-                       fprintf(tfp, "%s", line);
-                       continue;
-               }
-
-               pw = parse_user(line);
-               if (pw == (struct passwd *)NULL)
-               {
-                       fprintf(stderr, "warning: bad format for entry: \"%s\"\n", line);
-                       fprintf(tfp, "%s\n", line);
-                       if (cfp != NULL) fprintf(cfp, "%s\n", line);
-                       continue;
-               }
 
-               if (strcmp(newpw->pw_name, pw->pw_name))
-               {
-                       fprintf(tfp, "%s\n", line);
-                       if (cfp != NULL) fprintf(cfp, "%s\n", line);
-                       continue;
-               }
-               
-               fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
-                       newpw->pw_name, newpw->pw_passwd, newpw->pw_uid, newpw->pw_gid,
-                       newpw->pw_class, newpw->pw_change, newpw->pw_expire,
-                       newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell);
-               if (cfp != NULL)
-               {
-                       fprintf(cfp, "%s:",newpw->pw_name);
-                       if ((newpw->pw_passwd == NULL) || (newpw->pw_passwd[0] == '\0'))
-                               fprintf(cfp, ":");
-                       else
-                               fprintf(cfp, "*:");
-                       fprintf(cfp, "%d:%d:%s:%s:%s\n",
-                               newpw->pw_uid, newpw->pw_gid, newpw->pw_gecos,
-                               newpw->pw_dir, newpw->pw_shell);
-               }
-       }
-
-       if (cfp != NULL) fclose(cfp);
-       fclose(fp);
-       
-       rewind(tfp);
-
-       if (locn != NULL) {
-               if (seteuid(getuid()) != 0) {
-                       fprintf(stderr, "Unable to set privileges.");
-                       perror("seteuid");
-                       exit(1);
-               }
-       }
-       fp = fopen(pwname, "w");
-       if (fp == NULL)
-       {
-               fprintf(stderr, "ERROR: can't update \"%s\"\n", pwname);
-               fprintf(stderr, "new passwd file is \"%s\"\n", fname);
-               perror("open");
-               exit(1);
-       }
-       
-       while (NULL != (line = getline(tfp)))
-       {
-               fprintf(fp, "%s", line);
-               if (line[0] != '#') fprintf(fp, "\n");
-       }
-       fclose(fp);
-       fclose(tfp);
-       unlink(fname);
+       free(tempname);
 }
 
 int
-_file_passwd_main(char *uname, char *locn)
+file_passwd(char *uname, char *locn)
 {
        char *ne, *oc, *nc;
+       int fd;
        FILE *fp;
+       uid_t uid;
        char *fname;
        struct passwd *pw;
        struct passwd newpw;
-       struct stat sb;
-       int uid;
-       uid_t euid;
        
        fname = _PASSWD_FILE;
        if (locn != NULL) fname = locn;
        
-       umask((S_IRWXG | S_IRWXO));
-        
-       if ( lstat(fname, &sb) != 0 )
-       {
-               fprintf(stderr, "The file does not exist.\n");
-               exit(1);
-       }
-       
-       euid = geteuid();
-       if (locn != NULL) {
-       if (seteuid(getuid()) != 0) {
-               fprintf(stderr, "Permission denied.\n");
-               exit(1);
+       fd = open(fname, O_RDONLY | O_EXLOCK);
+       if (fd == -1) {
+               err(EXIT_FAILURE, "%s", fname);
        }
+
+       fp = fdopen(fd, "r");
+       if (fp == NULL) {
+               err(EXIT_FAILURE, "%s", fname);
        }
-       fp = fopen(fname, "a+");
-       if (locn != NULL) {
-       seteuid(euid);
-       }
-       
-       if (fp == NULL)
-       {
-               fprintf(stderr, "can't write to file \"%s\": ", fname);
-               perror("");
-               exit(1);
-       }
-       if (fchmod(fileno(fp), (S_IRUSR | S_IWUSR)) != 0)
-       {
-               fclose(fp);
-               fprintf(stderr, "can't set permissions for file \"%s\": ", fname);
-               perror("");
-               exit(1);
-       }
-       
-       pw = find_user(uname, fp);
-       if (pw == (struct passwd *)NULL)
-       {
-               fprintf(stderr, "user %s not found in file %s\n", uname, fname);
-               exit(1);
+
+       pw = find_user(fp, uname);
+       if (pw == NULL) {
+               errx(EXIT_FAILURE, "user %s not found in %s", uname, fname);
        }
 
        uid = getuid();
-       if ((uid != 0) && (uid != pw->pw_uid))
-       {
-               fprintf(stderr, "Permission denied\n");
-               exit(1);
+       if (uid != 0 && uid != pw->pw_uid) {
+               errno = EACCES;
+               err(EXIT_FAILURE, "%s", uname);
        }
 
-       /*
-        * Get the new password
-        */
+       // Get the password
        getpasswd(uname, (uid == 0), 5, 0, 0, pw->pw_passwd, &ne, &oc, &nc);
 
-       newpw.pw_name = copyString(pw->pw_name);
-       newpw.pw_passwd = copyString(ne);
+       newpw.pw_name = strdup(pw->pw_name);
+       newpw.pw_passwd = strdup(ne);
        newpw.pw_uid = pw->pw_uid;
        newpw.pw_gid = pw->pw_gid;
-       newpw.pw_class = copyString(pw->pw_class);
+       newpw.pw_class = strdup(pw->pw_class);
        newpw.pw_change = pw->pw_change;
        newpw.pw_expire = pw->pw_expire;
-       newpw.pw_gecos = copyString(pw->pw_gecos);
-       newpw.pw_dir = copyString(pw->pw_dir);
-       newpw.pw_shell = copyString(pw->pw_shell);
-
-       /*
-        * Re-write the file
-        */
-       rewrite_file(fname, fp, &newpw, locn);
+       newpw.pw_gecos = strdup(pw->pw_gecos);
+       newpw.pw_dir = strdup(pw->pw_dir);
+       newpw.pw_shell = strdup(pw->pw_shell);
 
-       /*
-        * Clean up memory
-        */
-       pw = parse_user(NULL);
-       free(newpw.pw_name);
-       free(newpw.pw_passwd);
-       free(newpw.pw_gecos);
-       free(newpw.pw_dir);
-       free(newpw.pw_shell);
-       free(newpw.pw_class);
+       // Rewrite the file
+       rewind(fp);
+       rewrite_file(fname, fp, &newpw);
 
        fclose(fp);
 
        return 0;
 }
-
-
-void sighandler(int inSignal)
-{
-       unlink(LOCK_FILE);
-       exit(1);
-}
-
-
-int
-file_passwd(char *uname, char *locn)
-{
-       pid_t pid;
-       int retVal = 0;
-       int waitResult = 0;
-       int retries = 0;
-       struct stat sb;
-       FILE *lockFile;
-       struct sigaction action = {{0}};
-       struct rlimit rlim;
-       
-       /* unlimit the resource limits */
-       rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
-       (void)setrlimit(RLIMIT_CPU, &rlim);
-       (void)setrlimit(RLIMIT_FSIZE, &rlim);
-       (void)setrlimit(RLIMIT_STACK, &rlim);
-       (void)setrlimit(RLIMIT_DATA, &rlim);
-       (void)setrlimit(RLIMIT_RSS, &rlim);
-       (void)setrlimit(RLIMIT_NOFILE, &rlim);
-       
-       /* trap signals */
-       sigfillset( &action.sa_mask );
-       action.sa_flags = SA_RESTART;
-       action.sa_handler = sighandler;
-       sigaction(SIGHUP, &action, NULL);
-       sigaction(SIGINT, &action, NULL);               // ctrl-c
-       sigaction(SIGQUIT, &action, NULL);
-       sigaction(SIGABRT, &action, NULL);
-       sigaction(SIGPIPE, &action, NULL);
-       sigaction(SIGALRM, &action, NULL);
-       sigaction(SIGTERM, &action, NULL);
-       sigaction(SIGSTOP, &action, NULL);
-       sigaction(SIGTSTP, &action, NULL);
-       
-       /* Check/create lock file */
-       for (retries = 0; retries < 5; retries++)
-       {
-               retVal = lstat(LOCK_FILE, &sb);
-               if (retVal != 0)
-                       break;
-               /* try in 100 milliseconds */
-               usleep(100000);
-       }
-       if (retVal == 0)
-       {
-               fprintf(stderr, "another passwd process is running.\n");
-               exit(EX_TEMPFAIL);
-       }
-       
-       umask((S_IRWXG | S_IRWXO));
-       lockFile = fopen(LOCK_FILE, "w");
-       if (lockFile == NULL)
-       {
-               fprintf(stderr, "can't create lock file.\n");
-               exit(EX_CANTCREAT);
-       }
-       fprintf(lockFile, "%d\n", getpid());
-       fclose(lockFile);
-       
-       pid = fork();
-       if (pid == -1)
-       {
-               fprintf(stderr, "can't fork\n");
-               exit(EX_OSERR);
-       }
-       
-       /* Handle the child */
-       if (pid == 0)
-       {
-               retVal = _file_passwd_main(uname, locn);
-               exit(retVal);
-       }
-       
-       /* Handle the parent */
-       waitResult = waitpid(pid, &retVal, 0);
-       retVal = (waitResult == 0) ? WEXITSTATUS(retVal) : 1;
-       
-       /* delete lock file */
-       unlink(LOCK_FILE);
-       
-       return retVal;
-}
-
index 908d9990557c30d2d84879e0ed541d466417a1ac..16bcf8964eb9485aa8c4c8569c37301fc8d17331 100644 (file)
@@ -74,57 +74,15 @@ show_error(CFErrorRef error) {
        }
 }
 
-static int
-is_singleuser(void) {
-       uint32_t su = 0;
-       size_t susz = sizeof(su);
-       if (sysctlbyname("kern.singleuser", &su, &susz, NULL, 0) != 0) {
-               return 0;
-       } else {
-               return (int)su;
-       }
-}
-
-static int
-load_DirectoryServicesLocal() {
-       const char* launchctl = "/bin/launchctl";
-       const char* plist = "/System/Library/LaunchDaemons/com.apple.DirectoryServicesLocal.plist";
-
-       pid_t pid = fork();
-       int status, res;
-       switch (pid) {
-               case -1: // ERROR
-                       perror("launchctl");
-                       return 0;
-               case 0: // CHILD
-                       execl(launchctl, launchctl, "load", plist, NULL);
-                       /* NOT REACHED */
-                       perror("launchctl");
-                       exit(1);
-                       break;
-               default: // PARENT
-                       do {
-                               res = waitpid(pid, &status, 0);
-                       } while (res == -1 && errno == EINTR);
-                       if (res == -1) {
-                               perror("launchctl");
-                               return 0;
-                       }
-                       break;
-       }
-       return (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS));
-}
-
 int
 od_passwd(char* uname, char* locn, char* aname)
 {
-       int                     change_pass_on_self;
-       CFErrorRef      error = NULL;
+       int change_pass_on_self;
+       CFErrorRef error = NULL;
        CFStringRef username = NULL;
        CFStringRef location = NULL;
        CFStringRef authname = NULL;
-       ODSessionRef    session = NULL;
-       ODNodeRef       node = NULL;
+       ODNodeRef node = NULL;
        ODRecordRef rec = NULL;
        CFStringRef oldpass = NULL;
        CFStringRef newpass = NULL;
@@ -156,44 +114,15 @@ od_passwd(char* uname, char* locn, char* aname)
                if (!username) return -1;
        }
 
-       /*
-        * Connect to DS server
-        */
-       session = ODSessionCreate(NULL, NULL, &error);
-       if ( !session && error && CFErrorGetCode(error) == kODErrorSessionDaemonNotRunning ) {
-               /*
-                * In single-user mode, attempt to load the local DS daemon.
-                */
-               if (is_singleuser() && load_DirectoryServicesLocal()) {
-                       CFTypeRef keys[] = { kODSessionLocalPath };
-                       CFTypeRef vals[] = { CFSTR("/var/db/dslocal") };
-                       CFDictionaryRef opts = CFDictionaryCreate(NULL, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                       if (opts) {
-                               session = ODSessionCreate(NULL, opts, &error);
-                               CFRelease(opts);
-                       }
-
-                       if (!location) {
-                               location = CFRetain(CFSTR("/Local/Default"));
-                       }
-               } else {
-                       show_error(error);
-                       return -1;
-               }
-       }
-
-
        /*
         * Copy the record from the specified node, or perform a search.
         */
        if (location) {
-               node = ODNodeCreateWithName(NULL, session, location, &error);
+               node = ODNodeCreateWithName(NULL, kODSessionDefault, location, &error);
        } else {
-               node = ODNodeCreateWithNodeType(NULL, session, kODNodeTypeAuthentication, &error);
+               node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODNodeTypeAuthentication, &error);
        }
 
-       if (session) CFRelease(session);
-
        if (node) {
                rec = ODNodeCopyRecord(node, kODRecordTypeUsers, username, NULL, &error );
                CFRelease(node);
@@ -259,22 +188,7 @@ od_passwd(char* uname, char* locn, char* aname)
                }
        }
 
-       if (needs_auth) {
-               CFTypeRef       values[] = { username, newpass, authname, oldpass };
-               CFArrayRef      authItems = CFArrayCreate(NULL, values, 4, &kCFTypeArrayCallBacks);
-
-               ODRecordSetNodeCredentialsExtended(rec,
-                       kODRecordTypeUsers,
-                       kODAuthenticationTypeSetPassword,
-                       authItems,
-                       NULL,
-                       NULL,
-                       &error);
-
-               CFRelease(authItems);
-       } else {
-               ODRecordChangePassword(rec, oldpass, newpass, &error);
-       }
+       ODRecordChangePassword(rec, oldpass, newpass, &error);
 
        if (error) {
                show_error(error);
index 2f8599aea2947e74016751f78c59380f1e856d4d..7041406665d4b337d662294f1ffa0312592ef28b 100644 (file)
 #define INFO_PAM 4
 #endif
 
-#ifndef __SLICK__
 #define _PASSWD_FILE "/etc/master.passwd"
-#else
-#define _PASSWD_FILE "/etc/passwd"
-#endif
 
 #include <stdio.h>
 #include <errno.h>
@@ -41,7 +37,6 @@
 #include <libc.h>
 #include <ctype.h>
 #include <string.h>
-#include "stringops.h"
 
 #ifdef __SLICK__
 #define _PASSWORD_LEN 8
diff --git a/passwd.tproj/stringops.c b/passwd.tproj/stringops.c
deleted file mode 100644 (file)
index a3621e3..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#import <string.h>
-#import <stdlib.h>
-#import <stdio.h>
-#import <stdarg.h>
-#import "stringops.h"
-
-char *copyString(char *s)
-{
-       int len;
-       char *t;
-
-       if (s == NULL) return NULL;
-
-       len = strlen(s) + 1;
-       t = malloc(len);
-       bcopy(s, t, len);
-       return t;
-}
-
-char *concatString(char *s, char *t)
-{
-       int len;
-
-       if (t == NULL) return s;
-
-       len = strlen(s) + strlen(t) + 1;
-       s = realloc(s, len);
-       strcat(s, t);
-       return s;
-}
-
-char **insertString(char *s, char **l, unsigned int x)
-{
-       int i, len;
-
-       if (s == NULL) return l;
-       if (l == NULL) 
-       {
-               l = (char **)malloc(2 * sizeof(char *));
-               l[0] = copyString(s);
-               l[1] = NULL;
-               return l;
-       }
-
-       for (i = 0; l[i] != NULL; i++);
-       len = i + 1; /* count the NULL on the end of the list too! */
-
-       l = (char **)realloc(l, (len + 1) * sizeof(char *));
-
-       if ((x >= (len - 1)) || (x == IndexNull))
-       {
-               l[len - 1] = copyString(s);
-               l[len] = NULL;
-               return l;
-       }
-
-       for (i = len; i > x; i--) l[i] = l[i - 1];
-       l[x] = copyString(s);
-       return l;
-}
-
-char **appendString(char *s, char **l)
-{
-       return insertString(s, l, IndexNull);
-}
-
-void freeList(char **l)
-{
-       int i;
-
-       if (l == NULL) return;
-       for (i = 0; l[i] != NULL; i++)
-       {
-               if (l[i] != NULL) free(l[i]);
-               l[i] = NULL;
-       }
-       if (l != NULL) free(l);
-}
-
-void freeString(char *s)
-{
-       if (s == NULL) return;
-       free(s);
-}
-
-unsigned int listLength(char **l)
-{
-       int i;
-
-       if (l == NULL) return 0;
-       for (i = 0; l[i] != NULL; i++);
-       return i;
-}
-
-unsigned int listIndex(char *s,char **l)
-{
-       int i;
-
-       if (l == NULL) return IndexNull;
-       for (i = 0; l[i] != NULL; i++)
-       {
-               if (strcmp(s, l[i]) == 0) return i;
-       }
-       return IndexNull;
-}
-
-char *prefix(char *s, char c)
-{
-       int i;
-       char *t;
-
-       if (s == NULL) return NULL;
-
-       for (i = 0; ((s[i] != '\0') && (s[i] != c)); i++);
-       if (i == 0) return NULL;
-       if (s[i] == '\0') return copyString(s);
-
-       t = malloc(i + 1);
-       bcopy(s, t, i);
-       t[i] = '\0';
-       return t;
-}
-
-char *postfix(char *s, char c)
-{
-       int i, len;
-       char *t;
-
-       if (s == NULL) return NULL;
-
-       for (i = 0; ((s[i] != '\0') && (s[i] != c)); i++);
-       if (s[i] == '\0') return NULL;
-       len = strlen(s) - i;
-       if (len == 1) return NULL;
-
-       t = malloc(len);
-       len--;
-       bcopy((s + i + 1), t, len);
-       t[len] = '\0';
-       return t;
-}
-       
-char *presuffix(char *s, char c)
-{
-       int i, len;
-       char *t;
-
-       if (s == NULL) return NULL;
-
-       len = strlen(s);
-       for (i = len - 1; ((i >= 0) && (s[i] != c)); i--);
-       if (i == 0) return NULL;
-       if (s[0] == '\0') return NULL;
-
-       t = malloc(i + 1);
-       bcopy(s, t, i);
-       t[i] = '\0';
-       return t;
-}
-
-char *suffix(char *s, char c)
-{
-       int i, len;
-       char *t;
-
-       if (s == NULL) return NULL;
-
-       len = strlen(s);
-       for (i = len - 1; ((i >= 0) && (s[i] != c)); i--);
-       if (i == 0) return NULL;
-       len -= i;
-       if (len == 1) return NULL;
-       t = malloc(len);
-       len--;
-       bcopy((s + i + 1), t, len);
-       t[len] = '\0';
-       return t;
-}
-
-char *lowerCase(char *s)
-{
-       int i;
-       char *t;
-
-       if (s == NULL) return NULL;
-       t = malloc(strlen(s) + 1);
-
-       for (i = 0; s[i] != '\0'; i++) 
-       {
-               if ((s[i] >= 'A') && (s[i] <= 'Z')) t[i] = s[i] + 32;
-               else t[i] = s[i];
-       }
-       t[i] = '\0';
-       return t;
-}
-
-char **explode(char *s, char c)
-{
-       char **l = NULL;
-       char *p, *t;
-       int i, n;
-
-       if (s == NULL) return NULL;
-
-       p = s;
-       while (p[0] != '\0')
-       {
-               for (i = 0; ((p[i] != '\0') && p[i] != c); i++);
-               n = i;
-               t = malloc(n + 1);
-               for (i = 0; i < n; i++) t[i] = p[i];
-               t[n] = '\0';
-               l = appendString(t, l);
-               free(t);
-               t = NULL;
-               if (p[i] == '\0') return l;
-               if (p[i + 1] == '\0') l = appendString("", l);
-               p = p + i + 1;
-       }
-       return l;
-}
diff --git a/passwd.tproj/stringops.h b/passwd.tproj/stringops.h
deleted file mode 100644 (file)
index e0a679e..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#define streq(A, B) (strcmp(A, B) == 0)
-#define IndexNull (unsigned int)-1
-char *copyString(char *);
-char *concatString(char *, char *);
-char **insertString(char *, char **, unsigned int);
-char **appendString(char *, char **);
-void freeList(char **);
-void freeString(char *);
-unsigned int listLength(char **);
-unsigned int listIndex(char *,char **);
-char *prefix(char *, char);
-char *postfix(char *, char);
-char *presuffix(char *, char);
-char *suffix(char *, char);
-char *lowerCase(char *);
-char **explode(char *, char);
index 03e22f01fa57089cf319733257de26651c628cd3..22368c3a461f633e0544bc0d9ae866bc7e386fd9 100644 (file)
@@ -6,7 +6,7 @@ CFILES = pwd_mkdb.c pw_scan.c
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble pwd_mkdb.8
 MANPAGES = pwd_mkdb.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -D_PW_NAME_LEN=MAXLOGNAME -D_PW_YPTOKEN=\"__YP!\"
index de64cd696a9a0910db56212f3b70fd74e615730c..075200ae904dea2fde584eb872f594edbe32b37d 100644 (file)
@@ -385,9 +385,7 @@ fmt:                errno = EFTYPE; /* XXX */
 }
 
 void                    
-cp(from, to, mode)              
-       char *from, *to;
-       mode_t mode;    
+cp(char *from, char *to, mode_t mode)              
 {               
        static char buf[MAXBSIZE];
        int from_fd, rcount, to_fd, wcount;
index 59a49c470e9995310a45b49cb12ab1647aac4ccf..47332e7e3f08d4faf3ddf58ed39041a8123997b6 100644 (file)
@@ -9,7 +9,7 @@ ifeq ($(Embedded),NO)
 USERDEFS = kextmanager.defs
 endif
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 515b592c59c62e429a84ac91eaf154bc6bb5439c..dbd741593ec857dbc6742ae0f1eb6e890b5d994d 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = main.c pdb.c usrdb.c db.c
 MANPAGES = sa.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID
 Extra_CC_Flags += -DAHZV1=64
 Extra_LD_Flags = -dead_strip
index 93bd5b1445ddceed599cf93bfca3752a85ed17d9..6f98e256f64974a0c0dc585b4d1367731d5140cb 100644 (file)
@@ -8,7 +8,7 @@ MANPAGES = sa1.8 sa2.8 sadc.8
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble sa1.8 sa1.sh\
             sa2.8 sa2.sh sadc.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -I.
index a88e3ff93a4774d63b3cb44b032e4c821324cc94..70ead05adb74445e22bb536534fc364cacc68da9 100644 (file)
@@ -472,7 +472,7 @@ record_device(io_registry_entry_t drive, struct drivestats* drivestat, int ndriv
          CFSTR(kIOBSDNameKey));
        if (name) {
            CFStringGetCString(name, BSDName,
-             MAXDRIVENAME, CFStringGetSystemEncoding());
+             MAXDRIVENAME, kCFStringEncodingUTF8);
            retval++;
        }
 
index ec59ecccf77f74ac1c4bbf8bcd46141c60448db3..1e6d99191b19480aa480c94847d9cff64c256061 100644 (file)
@@ -5,7 +5,7 @@ HFILES = sar.h
 CFILES = sar.c
 MANPAGES = sar.1
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -I. -I../sadc.tproj
index 22818aca6c20efc201e1aa2244aa7dbaf6ee609c..fd8b88a36f03972d12c52196c7d94dc9310a51d6 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = sc_usage.c
 MANPAGES = sc_usage.1
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip
 
 Extra_CC_Flags += -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders\
@@ -12,8 +12,3 @@ Extra_CC_Flags += -I$(SDKROOT)/System/Library/Frameworks/System.framework/Privat
 Extra_LD_Flags += -lcurses -lutil
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       $(INSTALL_DIRECTORY) $(DSTROOT)/usr/share/misc
-       $(INSTALL_FILE) trace.codes $(DSTROOT)/usr/share/misc
-
diff --git a/sc_usage.tproj/trace.codes b/sc_usage.tproj/trace.codes
deleted file mode 100644 (file)
index c9ff79b..0000000
+++ /dev/null
@@ -1,1507 +0,0 @@
-0x1f000000      DYLD_initialize
-0x1f010000      DYLD_CALL_image_init_routine
-0x1f010004      DYLD_CALL_dependent_init_routine
-0x1f010008      DYLD_CALL_lazy_init_routine
-0x1f01000c      DYLD_CALL_module_init_for_library
-0x1f010010      DYLD_CALL_module_init_for_object
-0x1f010014      DYLD_CALL_module_terminator_for_object
-0x1f010018      DYLD_CALL_module_init_for_dylib
-0x1f01001c      DYLD_CALL_mod_term_func
-0x1f010020      DYLD_CALL_object_func
-0x1f010024      DYLD_CALL_library_func
-0x1f010028      DYLD_CALL_add_image_func
-0x1f01002c      DYLD_CALL_remove_image_func
-0x1f010030      DYLD_CALL_link_object_module_func
-0x1f010034      DYLD_CALL_link_library_module_func
-0x1f010038      DYLD_CALL_link_module_func
-0x1f020000      DYLD_lookup_and_bind_with_hint
-0x1f020004      DYLD_lookup_and_bind_fully
-0x1f020008      DYLD_link_module
-0x1f02000c      DYLD_ulink_module
-0x1f020010      DYLD_bind_objc_module
-0x1f020014      DYLD_bind_fully_image_containing_address
-0x1f020018      DYLD_make_delayed_module_initializer_calls
-0x1f02001c      DYLD_NSNameOfSymbol
-0x1f020020      DYLD_NSAddressOfSymbol
-0x1f020024      DYLD_NSModuleForSymbol
-0x1f020028      DYLD_NSLookupAndBindSymbolWithHint
-0x1f02002c      DYLD_NSLookupSymbolInModule
-0x1f020030      DYLD_NSLookupSymbolInImage
-0x1f020034      DYLD_NSIsSymbolNameDefined
-0x1f020038      DYLD_NSIsSymbolNameDefinedWithHint
-0x1f02003c      DYLD_NSIsSymbolNameDefinedInImage
-0x1f020040      DYLD_NSNameOfModule
-0x1f020044      DYLD_NSLibraryNameForModule
-0x1f020048      DYLD_NSAddLibrary
-0x1f02004c      DYLD_NSAddLibraryWithSearching
-0x1f020050      DYLD_NSAddImage
-0x1f030000      DYLD_lookup_symbol
-0x1f030004      DYLD_bind_lazy_symbol_reference
-0x1f030008      DYLD_bind_symbol_by_name
-0x1f03000c      DYLD_link_in_need_modules
-0x1f040000      DYLD_map_image
-0x1f040004      DYLD_load_executable_image
-0x1f040008      DYLD_load_library_image
-0x1f04000c      DYLD_map_library_image
-0x1f040010      DYLD_map_bundle_image
-0x1f040014      DYLD_load_dependent_libraries
-0x1f040018      DYLD_notify_prebinding_agent
-0x21060000      LAUNCH_CPSTraceLineNum
-0x21060004      LAUNCH_CPSLaunch
-0x21060008      LAUNCH_CPSRegisterwithServer
-0x2106000c      LAUNCH_CPSCheckInNewProcess
-0x21060010      LAUNCH_CPSServerSideLaunch
-0x21060014      LAUNCH_CPSExecProcess
-0x21070000      LAUNCH_LSOpen
-0x21070004      LAUNCH_LSRegisterItem
-0x21070008      LAUNCH_LSGetApplicationAndFlagsForInfo
-0x1fff0000      LAUNCH_START_FINDER
-0x1fff0100      LAUNCH_START_DOCK
-0x1fff0310      LAUNCH_APP_EnterEventLoop
-0x1fff0314      LAUNCH_APP_WillOpenUntitled
-0x1fff031c      LAUNCH_APP_DidOpenUntitled
-0x1fffffff      LAUNCH_END
-0xff000104     MSG_mach_notify_port_deleted
-0xff000114     MSG_mach_notify_port_destroyed
-0xff000118     MSG_mach_notify_no_senders
-0xff00011c     MSG_mach_notify_send_once
-0xff000120     MSG_mach_notify_dead_name
-0xff0001ec     MSG_audit_triggers
-0xff000320     MSG_host_info
-0xff000324     MSG_host_kernel_version
-0xff000328     MSG_host_page_size
-0xff00032c     MSG_mach_memory_object_memory_entry
-0xff000330     MSG_host_processor_info
-0xff000334     MSG_host_get_io_master
-0xff000338     MSG_host_get_clock_service
-0xff00033c     MSG_kmod_get_info
-0xff000340     MSG_host_zone_info
-0xff000344     MSG_host_virtual_physical_table_info
-0xff000348     MSG_host_ipc_hash_info
-0xff00034c     MSG_enable_bluebox
-0xff000350     MSG_disable_bluebox
-0xff000354     MSG_processor_set_default
-0xff000358     MSG_processor_set_create
-0xff00035c     MSG_mach_memory_object_memory_entry_64
-0xff000360     MSG_host_statistics
-0xff000364     MSG_host_request_notification
-0xff000368     MSG_host_lockgroup_info
-0xff000640     MSG_host_get_boot_info
-0xff000644     MSG_host_reboot
-0xff000648     MSG_host_priv_statistics
-0xff00064c     MSG_host_default_memory_manager
-0xff000650     MSG_vm_wire
-0xff000654     MSG_thread_wire
-0xff000658     MSG_vm_allocate_cpm
-0xff00065c     MSG_host_processors
-0xff000660     MSG_host_get_clock_control
-0xff000664     MSG_kmod_create
-0xff000668     MSG_kmod_destroy
-0xff00066c     MSG_kmod_control
-0xff000670     MSG_host_get_special_port
-0xff000674     MSG_host_set_special_port
-0xff000678     MSG_host_set_exception_ports
-0xff00067c     MSG_host_get_exception_ports
-0xff000680     MSG_host_swap_exception_ports
-0xff000684     MSG_host_load_symbol_table
-0xff000688     MSG_mach_vm_wire
-0xff00068c     MSG_host_processor_sets
-0xff000690     MSG_host_processor_set_priv
-0xff000694     MSG_set_dp_control_port
-0xff000698     MSG_get_dp_control_port
-0xff00069c     MSG_host_set_UNDServer
-0xff0006a0     MSG_host_get_UNDServer
-0xff000960     MSG_host_security_create_task_token
-0xff000964     MSG_host_security_set_task_token
-0xff000fa0     MSG_clock_get_time
-0xff000fa4     MSG_clock_get_attributes
-0xff000fa8     MSG_clock_alarm
-0xff0012c0     MSG_clock_set_time
-0xff0012c4     MSG_clock_set_attributes
-0xff001f40     MSG_memory_object_get_attributes
-0xff001f44     MSG_memory_object_change_attributes
-0xff001f48     MSG_memory_object_synchronize_completed
-0xff001f4c     MSG_memory_object_lock_request
-0xff001f50     MSG_memory_object_destroy
-0xff001f54     MSG_memory_object_upl_request
-0xff001f58     MSG_memory_object_super_upl_request
-0xff001f5c     MSG_memory_object_page_op
-0xff001f60     MSG_memory_object_recover_named
-0xff001f64     MSG_memory_object_release_name
-0xff001f68     MSG_memory_object_range_op
-0xff002008     MSG_upl_abort
-0xff00200c     MSG_upl_abort_range
-0xff002010     MSG_upl_commit
-0xff002014     MSG_upl_commit_range
-0xff002260     MSG_memory_object_init
-0xff002264     MSG_memory_object_terminate
-0xff002268     MSG_memory_object_data_request
-0xff00226c     MSG_memory_object_data_return
-0xff002270     MSG_memory_object_data_initialize
-0xff002274     MSG_memory_object_data_unlock
-0xff002278     MSG_memory_object_synchronize
-0xff00227c     MSG_memory_object_unmap
-0xff002328     MSG_memory_object_create
-0xff00238c     MSG_default_pager_object_create
-0xff002390     MSG_default_pager_info
-0xff002394     MSG_default_pager_objects
-0xff002398     MSG_default_pager_object_pages
-0xff0023a0     MSG_default_pager_backing_store_create
-0xff0023a4     MSG_default_pager_backing_store_delete
-0xff0023a8     MSG_default_pager_backing_store_info
-0xff0023ac     MSG_default_pager_add_file
-0xff0023b0     MSG_default_pager_triggers
-0xff0023b4     MSG_default_pager_info_64
-0xff0023dc     MSG_default_pager_space_alert
-0xff002584     MSG_exception_raise
-0xff002588     MSG_exception_raise_state
-0xff00258c     MSG_exception_raise_state_identity
-0xff002bc0     MSG_io_object_get_class
-0xff002bc4     MSG_io_object_conforms_to
-0xff002bc8     MSG_io_iterator_next
-0xff002bcc     MSG_io_iterator_reset
-0xff002bd0     MSG_io_service_get_matching_services
-0xff002bd4     MSG_io_registry_entry_get_property
-0xff002bd8     MSG_io_registry_create_iterator
-0xff002bdc     MSG_io_registry_iterator_enter_entry
-0xff002be0     MSG_io_registry_iterator_exit_entry
-0xff002be4     MSG_io_registry_entry_from_path
-0xff002be8     MSG_io_registry_entry_get_name
-0xff002bec     MSG_io_registry_entry_get_properties
-0xff002bf0     MSG_io_registry_entry_get_property_bytes
-0xff002bf4     MSG_io_registry_entry_get_child_iterator
-0xff002bf8     MSG_io_registry_entry_get_parent_iterator
-0xff002bfc     MSG_io_service_open
-0xff002c00     MSG_io_service_close
-0xff002c04     MSG_io_connect_get_service
-0xff002c08     MSG_io_connect_set_notification_port
-0xff002c0c     MSG_io_connect_map_memory
-0xff002c10     MSG_io_connect_add_client
-0xff002c14     MSG_io_connect_set_properties
-0xff002c18     MSG_io_connect_method_scalarI_scalarO
-0xff002c1c     MSG_io_connect_method_scalarI_structureO
-0xff002c20     MSG_io_connect_method_scalarI_structureI
-0xff002c24     MSG_io_connect_method_structureI_structureO
-0xff002c28     MSG_io_registry_entry_get_path
-0xff002c2c     MSG_io_registry_get_root_entry
-0xff002c30     MSG_io_registry_entry_set_properties
-0xff002c34     MSG_io_registry_entry_in_plane
-0xff002c38     MSG_io_object_get_retain_count
-0xff002c3c     MSG_io_service_get_busy_state
-0xff002c40     MSG_io_service_wait_quiet
-0xff002c44     MSG_io_registry_entry_create_iterator
-0xff002c48     MSG_io_iterator_is_valid
-0xff002c4c     MSG_io_make_matching
-0xff002c50     MSG_io_catalog_send_data
-0xff002c54     MSG_io_catalog_terminate
-0xff002c58     MSG_io_catalog_get_data
-0xff002c5c     MSG_io_catalog_get_gen_count
-0xff002c60     MSG_io_catalog_module_loaded
-0xff002c64     MSG_io_catalog_reset
-0xff002c68     MSG_io_service_request_probe
-0xff002c6c     MSG_io_registry_entry_get_name_in_plane
-0xff002c70     MSG_io_service_match_property_table
-0xff002c74     MSG_io_async_method_scalarI_scalarO
-0xff002c78     MSG_io_async_method_scalarI_structureO
-0xff002c7c     MSG_io_async_method_scalarI_structureI
-0xff002c80     MSG_io_async_method_structureI_structureO
-0xff002c84     MSG_io_service_add_notification
-0xff002c88     MSG_io_service_add_interest_notification
-0xff002c8c     MSG_io_service_acknowledge_notification
-0xff002c90     MSG_io_connect_get_notification_semaphore
-0xff002c94     MSG_io_connect_unmap_memory
-0xff002c98     MSG_io_registry_entry_get_location_in_plane
-0xff002c9c     MSG_io_registry_entry_get_property_recursively
-0xff002ca0     MSG_io_service_get_state
-0xff002ca4     MSG_io_service_get_matching_services_ool
-0xff002ca8     MSG_io_service_match_property_table_ool
-0xff002cac     MSG_io_service_add_notification_ool
-0xff002cb0     MSG_io_object_get_superclass
-0xff002cb4     MSG_io_object_get_bundle_identifier
-0xff002cb8      MSG_io_service_open_extended
-0xff002cbc      MSG_io_connect_map_memory_into_task
-0xff002cc0      MSG_io_connect_unmap_memory_from_task
-0xff002cc4      MSG_io_connect_method
-0xff002cc8      MSG_io_connect_async_method
-0xff002ccc      MSG_io_connect_set_notification_port_64
-0xff002cd0      MSG_io_service_add_notification_64
-0xff002cd4      MSG_io_service_add_interest_notification_64
-0xff002cd8      MSG_io_service_add_notification_ool_64
-0xff002ee0     MSG_processor_start
-0xff002ee4     MSG_processor_exit
-0xff002ee8     MSG_processor_info
-0xff002eec     MSG_processor_control
-0xff002ef0     MSG_processor_assign
-0xff002ef4     MSG_processor_get_assignment
-0xff003200     MSG_mach_port_names
-0xff003204     MSG_mach_port_type
-0xff003208     MSG_mach_port_rename
-0xff00320c     MSG_mach_port_allocate_name
-0xff003210     MSG_mach_port_allocate
-0xff003214     MSG_mach_port_destroy
-0xff003218     MSG_mach_port_deallocate
-0xff00321c     MSG_mach_port_get_refs
-0xff003220     MSG_mach_port_mod_refs
-0xff003228     MSG_mach_port_set_mscount
-0xff00322c     MSG_mach_port_get_set_status
-0xff003230     MSG_mach_port_move_member
-0xff003234     MSG_mach_port_request_notification
-0xff003238     MSG_mach_port_insert_right
-0xff00323c     MSG_mach_port_extract_right
-0xff003240     MSG_mach_port_set_seqno
-0xff003244     MSG_mach_port_get_attributes
-0xff003248     MSG_mach_port_set_attributes
-0xff00324c     MSG_mach_port_allocate_qos
-0xff003250     MSG_mach_port_allocate_full
-0xff003254     MSG_task_set_port_space
-0xff003258     MSG_mach_port_get_srights
-0xff00325c     MSG_mach_port_space_info
-0xff003260     MSG_mach_port_dnrequest_info
-0xff003264     MSG_mach_port_kernel_object
-0xff003268     MSG_mach_port_insert_member
-0xff00326c     MSG_mach_port_extract_member
-0xff003520     MSG_task_create
-0xff003524     MSG_task_terminate
-0xff003528     MSG_task_threads
-0xff00352c     MSG_mach_ports_register
-0xff003530     MSG_mach_ports_lookup
-0xff003534     MSG_task_info
-0xff003538     MSG_task_set_info
-0xff00353c     MSG_task_suspend
-0xff003540     MSG_task_resume
-0xff003544     MSG_task_get_special_port
-0xff003548     MSG_task_set_special_port
-0xff00354c     MSG_thread_create
-0xff003550     MSG_thread_create_running
-0xff003554     MSG_task_set_exception_ports
-0xff003558     MSG_task_get_exception_ports
-0xff00355c     MSG_task_swap_exception_ports
-0xff003560     MSG_lock_set_create
-0xff003564     MSG_lock_set_destroy
-0xff003568     MSG_semaphore_create
-0xff00356c     MSG_semaphore_destroy
-0xff003570     MSG_task_policy_set
-0xff003574     MSG_task_policy_get
-0xff003578     MSG_task_sample
-0xff00357c     MSG_task_policy
-0xff003580     MSG_task_set_emulation
-0xff003584     MSG_task_get_emulation_vector
-0xff003588     MSG_task_set_emulation_vector
-0xff00358c     MSG_task_set_ras_pc
-0xff003594     MSG_task_assign
-0xff003598     MSG_task_assign_default
-0xff00359c     MSG_task_get_assignment
-0xff0035a0     MSG_task_set_policy
-0xff003840     MSG_thread_terminate
-0xff003844     MSG_act_get_state
-0xff003848     MSG_act_set_state
-0xff00384c     MSG_thread_get_state
-0xff003850     MSG_thread_set_state
-0xff003854     MSG_thread_suspend
-0xff003858     MSG_thread_resume
-0xff00385c     MSG_thread_abort
-0xff003860     MSG_thread_abort_safely
-0xff003864     MSG_thread_depress_abort
-0xff003868     MSG_thread_get_special_port
-0xff00386c     MSG_thread_set_special_port
-0xff003870     MSG_thread_info
-0xff003874     MSG_thread_set_exception_ports
-0xff003878     MSG_thread_get_exception_ports
-0xff00387c     MSG_thread_swap_exception_ports
-0xff003880     MSG_thread_policy
-0xff003884     MSG_thread_policy_set
-0xff003888     MSG_thread_policy_get
-0xff00388c     MSG_thread_sample
-0xff003890     MSG_etap_trace_thread
-0xff003894     MSG_thread_assign
-0xff003898     MSG_thread_assign_default
-0xff00389c     MSG_thread_get_assignment
-0xff0038a0     MSG_thread_set_policy
-0xff003b60     MSG_vm_region
-0xff003b64     MSG_vm_allocate
-0xff003b68     MSG_vm_deallocate
-0xff003b6c     MSG_vm_protect
-0xff003b70     MSG_vm_inherit
-0xff003b74     MSG_vm_read
-0xff003b78     MSG_vm_read_list
-0xff003b7c     MSG_vm_write
-0xff003b80     MSG_vm_copy
-0xff003b84     MSG_vm_read_overwrite
-0xff003b88     MSG_vm_msync
-0xff003b8c     MSG_vm_behavior_set
-0xff003b90     MSG_vm_map
-0xff003b94     MSG_vm_machine_attribute
-0xff003b98     MSG_vm_remap
-0xff003b9c     MSG_task_wire
-0xff003ba0     MSG_mach_make_memory_entry
-0xff003ba4     MSG_vm_map_page_query
-0xff003ba8     MSG_mach_vm_region_info
-0xff003bac     MSG_vm_mapped_pages_info
-0xff003bb4     MSG_vm_region_recurse
-0xff003bb8     MSG_vm_region_recurse_64
-0xff003bbc     MSG_mach_vm_region_info_64
-0xff003bc0     MSG_vm_region_64
-0xff003bc4     MSG_mach_make_memory_entry_64
-0xff003bc8     MSG_vm_map_64
-0xff003bcc     MSG_vm_map_get_upl
-0xff003bd8     MSG_vm_purgable_control
-0xff003e80     MSG_processor_set_statistics
-0xff003e84     MSG_processor_set_destroy
-0xff003e88     MSG_processor_set_max_priority
-0xff003e8c     MSG_processor_set_policy_enable
-0xff003e90     MSG_processor_set_policy_disable
-0xff003e94     MSG_processor_set_tasks
-0xff003e98     MSG_processor_set_threads
-0xff003e9c     MSG_processor_set_policy_control
-0xff003ea0     MSG_processor_set_stack_usage
-0xff003ea4     MSG_processor_set_info
-0xff004b00     MSG_mach_vm_allocate
-0xff004b04     MSG_mach_vm_deallocate
-0xff004b08     MSG_mach_vm_protect
-0xff004b0c     MSG_mach_vm_inherit
-0xff004b10     MSG_mach_vm_read
-0xff004b14     MSG_mach_vm_read_list
-0xff004b18     MSG_mach_vm_write
-0xff004b1c     MSG_mach_vm_copy
-0xff004b20     MSG_mach_vm_read_overwrite
-0xff004b24     MSG_mach_vm_msync
-0xff004b28     MSG_mach_vm_behavior_set
-0xff004b2c     MSG_mach_vm_map
-0xff004b30     MSG_mach_vm_machine_attribute
-0xff004b34     MSG_mach_vm_remap
-0xff004b38     MSG_mach_vm_page_query
-0xff004b3c     MSG_mach_vm_region_recurse
-0xff004b40     MSG_mach_vm_region
-0xff004b44     MSG__mach_make_memory_entry
-0xff004b48     MSG__mach_vm_purgable_control
-0xff004e20     MSG_ledger_create
-0xff004e24     MSG_ledger_terminate
-0xff004e28     MSG_ledger_transfer
-0xff004e2c     MSG_ledger_read
-0xff005dc0     MSG_UNDExecute_rpc
-0xff005dc4     MSG_UNDDisplayNoticeFromBundle_rpc
-0xff005dc8     MSG_UNDDisplayAlertFromBundle_rpc
-0xff005dcc     MSG_UNDDisplayCustomFromBundle_rpc
-0xff005dd0     MSG_UNDDisplayCustomFromDictionary_rpc
-0xff005dd4     MSG_UNDCancelNotification_rpc
-0xff005dd8     MSG_UNDDisplayNoticeSimple_rpc
-0xff005ddc     MSG_UNDDisplayAlertSimple_rpc
-0xff0060e0     MSG_UNDAlertCompletedWithResult_rpc
-0xff0060e4     MSG_UNDNotificationCreated_rpc
-0xff25a8a0     MSG_lock_acquire
-0xff25a8a4     MSG_lock_release
-0xff25a8a8     MSG_lock_try
-0xff25a8ac     MSG_lock_make_stable
-0xff25a8b0     MSG_lock_handoff
-0xff25a8b4     MSG_lock_handoff_accept
-0xff25abc0     MSG_semaphore_signal
-0xff25abc4     MSG_semaphore_signal_all
-0xff25abc8     MSG_semaphore_wait
-0xff25abcc     MSG_semaphore_signal_thread
-0xff25abd0     MSG_semaphore_timedwait
-0xff25abd4     MSG_semaphore_wait_signal
-0xff25abd8     MSG_semaphore_timedwait_signal
-0xffbebdcc     MSG_clock_alarm_reply
-0x1020000      KTrap_DivideError
-0x1020004      KTrap_Debug
-0x1020008      KTrap_NMI
-0x102000c      KTrap_Int3
-0x1020010      KTrap_Overflow
-0x1020014      KTrap_BoundRange
-0x1020018      KTrap_InvalidOpcode
-0x102001c      KTrap_DeviceNotAvail
-0x1020020      KTrap_DoubleFault
-0x1020024      KTrap_Coprocessor
-0x1020028      KTrap_InvalidTSS
-0x102002c      KTrap_SegmentNotPresent
-0x1020030      KTrap_StackFault
-0x1020034      KTrap_GeneralProtection
-0x1020038      KTrap_PageFault
-0x102003c      KTrap_unknown
-0x1020040      KTrap_FloatPointError
-0x1020044      KTrap_AlignmentCheck
-0x1020048      KTrap_MachineCheck
-0x102004c      KTrap_SIMD_FP
-0x10203fc      KTrap_Preempt
-0x1070000      UTrap_DivideError
-0x1070004      UTrap_Debug
-0x1070008      UTrap_NMI
-0x107000c      UTrap_Int3
-0x1070010      UTrap_Overflow
-0x1070014      UTrap_BoundRange
-0x1070018      UTrap_InvalidOpcode
-0x107001c      UTrap_DeviceNotAvail
-0x1070020      UTrap_DoubleFault
-0x1070024      UTrap_Coprocessor
-0x1070028      UTrap_InvalidTSS
-0x107002c      UTrap_SegmentNotPresent
-0x1070030      UTrap_StackFault
-0x1070034      UTrap_GeneralProtection
-0x1070038      UTrap_PageFault
-0x107003c      UTrap_unknown
-0x1070040      UTrap_FloatPointError
-0x1070044      UTrap_AlignmentCheck
-0x1070048      UTrap_MachineCheck
-0x107004c      UTrap_SIMD_FP
-0x1300004      MACH_Pageout
-0x1300008      MACH_vmfault
-0x1300100      MACH_purgable_token_add
-0x1300104      MACH_purgable_token_delete
-0x1300108      MACH_purgable_token_ripened
-0x130010c      MACH_purgable_token_purged
-0x1400000      MACH_SCHED
-0x1400004      MACH_STKATTACH
-0x1400008      MACH_STKHANDOFF
-0x140000c      MACH_CALLCONT
-0x1400010      MACH_CALLOUT
-0x1400014      MACH_ServiceT
-0x1400018      MACH_MKRUNNABLE
-0x140001c      MACH_PROMOTE
-0x1400020      MACH_DEMOTE
-0x1400024      MACH_IDLE
-0x1500000      MACH_MSGID_INVALID
-0x1090000      DecrTrap
-0x1090004      DecrSet
-0x1090008      TimerCallIntr
-0x109000c      pmsStep
-0x1090010      clock_deadline
-0x10c0000      MACH_SysCall
-0x10c0004      MSC_kern_invalid_#1
-0x10c0008      MSC_kern_invalid_#2
-0x10c000c      MSC_kern_invalid_#3
-0x10c0010      MSC_kern_invalid_#4
-0x10c0014      MSC_kern_invalid_#5
-0x10c0018      MSC_kern_invalid_#6
-0x10c001c      MSC_kern_invalid_#7
-0x10c0020      MSC_kern_invalid_#8
-0x10c0024      MSC_kern_invalid_#9
-0x10c0028      MSC_kern_invalid_#10
-0x10c002c      MSC_kern_invalid_#11
-0x10c0030      MSC_kern_invalid_#12
-0x10c0034      MSC_kern_invalid_#13
-0x10c0038      MSC_kern_invalid_#14
-0x10c003c      MSC_kern_invalid_#15
-0x10c0040      MSC_kern_invalid_#16
-0x10c0044      MSC_kern_invalid_#17
-0x10c0048      MSC_kern_invalid_#18
-0x10c004c      MSC_kern_invalid_#19
-0x10c0050      MSC_kern_invalid_#20
-0x10c0054      MSC_kern_invalid_#21
-0x10c0058      MSC_kern_invalid_#22
-0x10c005c      MSC_kern_invalid_#23
-0x10c0060      MSC_kern_invalid_#24
-0x10c0064      MSC_kern_invalid_#25
-0x10c0068      MSC_mach_reply_port
-0x10c006c      MSC_thread_self_trap
-0x10c0070      MSC_task_self_trap
-0x10c0074      MSC_host_self_trap
-0x10c0078      MSC_kern_invalid_#30
-0x10c007c       MSC_mach_msg_trap
-0x10c0080      MSC_mach_msg_overwrite_trap
-0x10c0084      MSC_semaphore_signal_trap
-0x10c0088      MSC_semaphore_signal_all_trap
-0x10c008c      MSC_semaphore_signal_thread_trap
-0x10c0090      MSC_semaphore_wait_trap
-0x10c0094      MSC_semaphore_wait_signal_trap
-0x10c0098      MSC_semaphore_timedwait_trap
-0x10c009c      MSC_semaphore_timedwait_signal_trap
-0x10c00a0      MSC_kern_invalid_#40
-0x10c00a4      MSC_init_process
-0x10c00a8      MSC_kern_invalid_#42
-0x10c00ac      MSC_map_fd
-0x10c00b0      MSC_kern_invalid_#44
-0x10c00b4      MSC_task_for_pid
-0x10c00b8      MSC_pid_for_task
-0x10c00bc      MSC_kern_invalid_#47
-0x10c00c0      MSC_macx_swapon
-0x10c00c4      MSC_macx_swapoff
-0x10c00c8      MSC_kern_invalid_#50
-0x10c00cc      MSC_macx_triggers
-0x10c00d0      MSC_kern_invalid_#52
-0x10c00d4      MSC_kern_invalid_#53
-0x10c00d8      MSC_kern_invalid_#54
-0x10c00dc      MSC_kern_invalid_#55
-0x10c00e0      MSC_kern_invalid_#56
-0x10c00e4      MSC_kern_invalid_#57
-0x10c00e8      MSC_kern_invalid_#58
-0x10c00ec      MSC_swtch_pri
-0x10c00f0      MSC_swtch
-0x10c00f4      MSC_thread_switch
-0x10c00f8      MSC_clock_sleep_trap
-0x10c00fc      MSC_kern_invalid_#63
-0x10c0100      MSC_kern_invalid_#64
-0x10c0104      MSC_kern_invalid_#65
-0x10c0108      MSC_kern_invalid_#66
-0x10c010c      MSC_kern_invalid_#67
-0x10c0110      MSC_kern_invalid_#68
-0x10c0114      MSC_kern_invalid_#69
-0x10c0118      MSC_kern_invalid_#70
-0x10c011c      MSC_kern_invalid_#71
-0x10c0120      MSC_kern_invalid_#72
-0x10c0124      MSC_kern_invalid_#73
-0x10c0128      MSC_kern_invalid_#74
-0x10c012c      MSC_kern_invalid_#75
-0x10c0130      MSC_kern_invalid_#76
-0x10c0134      MSC_kern_invalid_#77
-0x10c0138      MSC_kern_invalid_#78
-0x10c013c      MSC_kern_invalid_#79
-0x10c0140      MSC_kern_invalid_#80
-0x10c0144      MSC_kern_invalid_#81
-0x10c0148      MSC_kern_invalid_#82
-0x10c014c      MSC_kern_invalid_#83
-0x10c0150      MSC_kern_invalid_#84
-0x10c0154      MSC_kern_invalid_#85
-0x10c0158      MSC_kern_invalid_#86
-0x10c015c      MSC_kern_invalid_#87
-0x10c0160      MSC_kern_invalid_#88
-0x10c0164      MSC_mach_timebase_info
-0x10c0168      MSC_mach_wait_until
-0x10c016c      MSC_mk_timer_create
-0x10c0170      MSC_mk_timer_destroy
-0x10c0174      MSC_mk_timer_arm
-0x10c0178      MSC_mk_timer_cancel
-0x10c017c      MSC_mk_timebase_info
-0x10c0180      MSC_kern_invalid_#96
-0x10c0184      MSC_kern_invalid_#97
-0x10c0188      MSC_kern_invalid_#98
-0x10c018c      MSC_kern_invalid_#99
-0x10c0190      MSC_audio_fast_trap
-0x10c0194      MSC_kern_invalid_#101
-0x10c0198      MSC_kern_invalid_#102
-0x10c019c      MSC_kern_invalid_#103
-0x10c01a0      MSC_kern_invalid_#104
-0x10c01a4      MSC_kern_invalid_#105
-0x10c01a8      MSC_kern_invalid_#106
-0x10c01ac      MSC_kern_invalid_#107
-0x10c01b0      MSC_kern_invalid_#108
-0x10c01b4      MSC_kern_invalid_#109
-0x10c01b8      MSC_kern_invalid_#110
-0x10c01bc      MSC_kern_invalid_#111
-0x10c01c0      MSC_kern_invalid_#112
-0x10c01c4      MSC_kern_invalid_#113
-0x10c01c8      MSC_kern_invalid_#114
-0x10c01cc      MSC_kern_invalid_#115
-0x10c01d0      MSC_kern_invalid_#116
-0x10c01d4      MSC_kern_invalid_#117
-0x10c01d8      MSC_kern_invalid_#118
-0x10c01dc      MSC_kern_invalid_#119
-0x10c01e0      MSC_kern_invalid_#120
-0x10c01e4      MSC_kern_invalid_#121
-0x10c01e8      MSC_kern_invalid_#122
-0x10c01ec      MSC_kern_invalid_#123
-0x10c01f0      MSC_kern_invalid_#124
-0x10c01f4      MSC_kern_invalid_#125
-0x10c01f8      MSC_kern_invalid_#126
-0x10c01fc      MSC_kern_invalid_#127
-0x1050000      INTERRUPT
-0x3010090      VFS_LOOKUP
-0x3020000      P_WrData
-0x3020008      P_RdData
-0x3020020      P_WrMeta
-0x3020028      P_RdMeta
-0x3020040      P_PgOut
-0x3020048      P_PgIn
-0x3020010      P_WrDataAsync
-0x3020018      P_RdDataAsync
-0x3020030      P_WrMetaAsync
-0x3020038      P_RdMetaAsync
-0x3020050      P_PgOutAsync
-0x3020058      P_PgInAsync
-0x3020004      P_WrDataDone
-0x302000C      P_RdDataDone
-0x3020024      P_WrMetaDone
-0x302002C      P_RdMetaDone
-0x3020044      P_PgOutDone
-0x302004C      P_PgInDone
-0x3020014      P_WrDataAsyncDone
-0x302001C      P_RdDataAsyncDone
-0x3020034      P_WrMetaAsyncDone
-0x302003C      P_RdMetaAsyncDone
-0x3020054      P_PgOutAsyncDone
-0x302005C      P_PgInAsyncDone
-0x3050004      journal_flush
-0x4010004      proc_exit
-0x4010008      force_exit
-0x40c0000      BSC_SysCall
-0x40c0004      BSC_exit
-0x40c0008      BSC_fork
-0x40c000c      BSC_read
-0x40c0010      BSC_write
-0x40c0014      BSC_open
-0x40c0018      BSC_close
-0x40c001c      BSC_wait4
-0x40c0020      BSC_obs_creat
-0x40c0024      BSC_link
-0x40c0028      BSC_unlink
-0x40c002c      BSC_obs_execv
-0x40c0030      BSC_chdir
-0x40c0034      BSC_fchdir
-0x40c0038      BSC_mknod
-0x40c003c      BSC_chmod
-0x40c0040      BSC_chown
-0x40c0044      BSC_obs_break
-0x40c0048      BSC_getfsstat
-0x40c004c      BSC_old_lseek
-0x40c0050      BSC_getpid
-0x40c0054      BSC_obs_mount
-0x40c0058      BSC_obs_unmount
-0x40c005c      BSC_setuid
-0x40c0060      BSC_getuid
-0x40c0064      BSC_geteuid
-0x40c0068      BSC_ptrace
-0x40c006c      BSC_recvmsg
-0x40c0070      BSC_sendmsg
-0x40c0074      BSC_recvfrom
-0x40c0078      BSC_accept
-0x40c007c      BSC_getpeername
-0x40c0080      BSC_getsockname
-0x40c0084      BSC_access
-0x40c0088      BSC_chflags
-0x40c008c      BSC_fchflags
-0x40c0090      BSC_sync
-0x40c0094      BSC_kill
-0x40c0098      BSC_obs_stat
-0x40c009c      BSC_getppid
-0x40c00a0      BSC_obs_lstat
-0x40c00a4      BSC_dup
-0x40c00a8      BSC_pipe
-0x40c00ac      BSC_getegid
-0x40c00b0      BSC_profil
-0x40c00b4      BSC_obs_ktrace
-0x40c00b8      BSC_sigaction
-0x40c00bc      BSC_getgid
-0x40c00c0      BSC_sigprocmask
-0x40c00c4      BSC_getlogin
-0x40c00c8      BSC_setlogin
-0x40c00cc      BSC_acct
-0x40c00d0      BSC_sigpending
-0x40c00d4      BSC_sigaltstack
-0x40c00d8      BSC_ioctl
-0x40c00dc      BSC_reboot
-0x40c00e0      BSC_revoke
-0x40c00e4      BSC_symlink
-0x40c00e8      BSC_readlink
-0x40c00ec      BSC_execve
-0x40c00f0      BSC_umask
-0x40c00f4      BSC_chroot
-0x40c00f8      BSC_obs_fstat
-0x40c00fc      BSC_#63
-0x40c0100      BSC_obs_getpagesize
-0x40c0104      BSC_msync
-0x40e0104      BSC_msync_extended_info
-0x40c0108      BSC_vfork
-0x40c010c      BSC_obs_vread
-0x40c0110      BSC_obs_vwrite
-0x40c0114      BSC_sbrk
-0x40c0118      BSC_sstk
-0x40c011c      BSC_obs_mmap
-0x40c0120      BSC_obs_vadvise
-0x40c0124      BSC_munmap
-0x40c0128      BSC_mprotect
-0x40c012c      BSC_madvise
-0x40c0130      BSC_obs_vhangup
-0x40c0134      BSC_obs_vlimit
-0x40c0138      BSC_mincore
-0x40c013c      BSC_getgroups
-0x40c0140      BSC_setgroups
-0x40c0144      BSC_getpgrp
-0x40c0148      BSC_setpgid
-0x40c014c      BSC_setitimer
-0x40c0150      BSC_obs_wait
-0x40c0154      BSC_swapon
-0x40c0158      BSC_getitimer
-0x40c015c      BSC_obs_gethostname
-0x40c0160      BSC_obs_sethostname
-0x40c0164      BSC_getdtablesize
-0x40c0168      BSC_dup2
-0x40c016c      BSC_obs_getdopt
-0x40c0170      BSC_fcntl
-0x40c0174      BSC_select
-0x40c0178      BSC_obs_setdopt
-0x40c017c      BSC_fsync
-0x40c0180      BSC_setpriority
-0x40c0184      BSC_socket
-0x40c0188      BSC_connect
-0x40c018c      BSC_obs_accept
-0x40c0190      BSC_getpriority
-0x40c0194      BSC_obs_send
-0x40c0198      BSC_obs_recv
-0x40c019c      BSC_obs_sigreturn
-0x40c01a0      BSC_bind
-0x40c01a4      BSC_setsockopt
-0x40c01a8      BSC_listen
-0x40c01ac      BSC_obs_vtimes
-0x40c01b0      BSC_obs_sigvec
-0x40c01b4      BSC_obs_sigblock
-0x40c01b8      BSC_obs_sigsetmask
-0x40c01bc      BSC_sigsuspend
-0x40c01c0      BSC_obs_sigstack
-0x40c01c4      BSC_obs_recvmsg
-0x40c01c8      BSC_obs_sendmsg
-0x40c01cc      BSC_obs_vtrace
-0x40c01d0      BSC_gettimeofday
-0x40c01d4      BSC_getrusage
-0x40c01d8      BSC_getsockopt
-0x40c01dc      BSC_obs_resuba
-0x40c01e0      BSC_readv
-0x40c01e4      BSC_writev
-0x40c01e8      BSC_settimeofday
-0x40c01ec      BSC_fchown
-0x40c01f0      BSC_fchmod
-0x40c01f4      BSC_obs_recvfrom
-0x40c01f8      BSC_setreuid
-0x40c01fc      BSC_setregid
-0x40c0200      BSC_rename
-0x40c0204      BSC_obs_truncate
-0x40c0208      BSC_obs_ftruncate
-0x40c020c      BSC_flock
-0x40c0210      BSC_mkfifo
-0x40c0214      BSC_sendto
-0x40c0218      BSC_shutdown
-0x40c021c      BSC_socketpair
-0x40c0220      BSC_mkdir
-0x40c0224      BSC_rmdir
-0x40c0228      BSC_utimes
-0x40c022c      BSC_futimes
-0x40c0230      BSC_adjtime
-0x40c0234      BSC_obs_getpeername
-0x40c0238      BSC_gethostuuid
-0x40c023c      BSC_obs_sethostid
-0x40c0240      BSC_obs_getrlimit
-0x40c0244      BSC_obs_setrlimit
-0x40c0248      BSC_obs_killpg
-0x40c024c      BSC_setsid
-0x40c0250      BSC_obs_setquota
-0x40c0254      BSC_obs_qquota
-0x40c0258      BSC_obs_getsockname
-0x40c025c      BSC_getpgid
-0x40c0260      BSC_setprivexec
-0x40c0264      BSC_pread
-0x40e0264      BSC_pread_extended_info
-0x40c0268      BSC_pwrite
-0x40e0268      BSC_pwrite_extended_info
-0x40c026c      BSC_nfssvc
-0x40c0270      BSC_obs_getdirentries
-0x40c0274      BSC_statfs
-0x40c0278      BSC_fstatfs
-0x40c027c      BSC_unmount
-0x40c0280      BSC_obs_async_daemon
-0x40c0284      BSC_getfh
-0x40c0288      BSC_obs_getdomainname
-0x40c028c      BSC_obs_setdomainname
-0x40c0290      BSC_#164
-0x40c0294       BSC_quotactl
-0x40c0298       BSC_obs_exportfs
-0x40c029c       BSC_mount
-0x40c02a0       BSC_obs_ustat
-0x40c02a4       BSC_csops
-0x40c02a8       BSC_obs_table
-0x40c02ac       BSC_obs_wait3
-0x40c02b0       BSC_obs_rpause
-0x40c02b4       BSC_waitid
-0x40c02b8       BSC_obs_getdents
-0x40c02bc       BSC_obs_gc_control
-0x40c02c0       BSC_add_profil
-0x40c02c4       BSC_#177
-0x40c02c8       BSC_#178
-0x40c02cc       BSC_#179
-0x40c02d0       BSC_kdebug_trace
-0x40c02d4       BSC_setgid
-0x40c02d8       BSC_setegid
-0x40c02dc       BSC_seteuid
-0x40c02e0       BSC_sigreturn
-0x40c02e4      BSC_chud
-0x40c02e8      BSC_#186
-0x40c02ec      BSC_#187
-0x40c02f0      BSC_stat
-0x40c02f4      BSC_fstat
-0x40c02f8      BSC_lstat
-0x40c02fc      BSC_pathconf
-0x40c0300      BSC_fpathconf
-0x40c0304      BSC_#193
-0x40c0308      BSC_getrlimit
-0x40c030c      BSC_setrlimit
-0x40c0310      BSC_getdirentries
-0x40c0314      BSC_mmap
-0x40e0314      BSC_mmap_extended_info
-0x40f0314      BSC_mmap_extended_info2
-0x40c0318      BSC__syscall
-0x40c031c      BSC_lseek
-0x40c0320      BSC_truncate
-0x40c0324      BSC_ftruncate
-0x40c0328      BSC___sysctl
-0x40c032c      BSC_mlock
-0x40c0330      BSC_munlock
-0x40c0334      BSC_undelete
-0x40c0338      BSC_ATsocket
-0x40c033c      BSC_ATgetmsg
-0x40c0340      BSC_ATputmsg
-0x40c0344      BSC_ATPsndreq
-0x40c0348      BSC_ATPsndrsp
-0x40c034c      BSC_ATPgetreq
-0x40c0350      BSC_ATPgetrsp
-0x40c0354      BSC_#213
-0x40c0358       BSC_kqueue_from_portset_np
-0x40c035c       BSC_kqueue_portset_np
-0x40c0360       BSC_mkcomplex
-0x40c0364       BSC_statv
-0x40c0368       BSC_lstatv
-0x40c036c       BSC_fstatv
-0x40c0370      BSC_getattrlist
-0x40c0374      BSC_setattrlist
-0x40c0378      BSC_getdirentriesattr
-0x40c037c      BSC_exchangedata
-0x40c0380      BSC_224
-0x40c0384      BSC_searchfs
-0x40c0388      BSC_delete_Carbon
-0x40c038c      BSC_copyfile
-0x40c0390      BSC_#228
-0x40c0394      BSC_#229
-0x40c0398      BSC_poll
-0x40c039c      BSC_watchevent
-0x40c03a0      BSC_waitevent
-0x40c03a4      BSC_modwatch
-0x40c03a8       BSC_getxattr
-0x40c03ac       BSC_fgetxattr
-0x40c03b0       BSC_setxattr
-0x40c03b4       BSC_fsetxattr
-0x40c03b8       BSC_removexattr
-0x40c03bc       BSC_fremovexattr
-0x40c03c0       BSC_listxattr
-0x40c03c4       BSC_flistxattr
-0x40c03c8      BSC_fsctl
-0x40c03cc      BSC_initgroups
-0x40c03d0      BSC_posix_spawn
-0x40c03d4      BSC_#245
-0x40c03d8      BSC_#246
-0x40c03dc      BSC_nfsclnt
-0x40c03e0      BSC_fhopen
-0x40c03e4      BSC_#249
-0x40c03e8      BSC_minherit
-0x40c03ec      BSC_semsys
-0x40c03f0      BSC_msgsys
-0x40c03f4      BSC_shmsys
-0x40c03f8      BSC_semctl
-0x40c03fc      BSC_semget
-0x40c0400      BSC_semop
-0x40c0404      BSC_#257
-0x40c0408      BSC_msgctl
-0x40c040c      BSC_msgget
-0x40c0410      BSC_msgsnd
-0x40c0414      BSC_msgrcv
-0x40c0418      BSC_shmat
-0x40c041c      BSC_shmctl
-0x40c0420      BSC_shmdt
-0x40c0424      BSC_shmget
-0x40c0428      BSC_shm_open
-0x40c042c      BSC_shm_unlink
-0x40c0430      BSC_sem_open
-0x40c0434      BSC_sem_close
-0x40c0438      BSC_sem_unlink
-0x40c043c      BSC_sem_wait
-0x40c0440      BSC_sem_trywait
-0x40c0444      BSC_sem_post
-0x40c0448      BSC_sem_getvalue
-0x40c044c      BSC_sem_init
-0x40c0450      BSC_sem_destroy
-0x40c0454      BSC_open_extended
-0x40c0458      BSC_umask_extended
-0x40c045c      BSC_stat_extended
-0x40c0460      BSC_lstat_extended
-0x40c0464      BSC_fstat_extended
-0x40c0468      BSC_chmod_extended
-0x40c046c      BSC_fchmod_extended
-0x40c0470      BSC_access_extended
-0x40c0474      BSC_settid
-0x40c0478      BSC_gettid
-0x40c047c      BSC_setsgroups
-0x40c0480      BSC_getsgroups
-0x40c0484      BSC_setwgroups
-0x40c0488      BSC_getwgroups
-0x40c048c      BSC_mkfifo_extended
-0x40c0490      BSC_mkdir_extended
-0x40c0494      BSC_identitysvc
-0x40c0498      BSC_shared_region_chk_np
-0x40c049c      BSC_shared_region_map_np
-0x40c04a0      BSC_obs_load_shared_file
-0x40c04a4      BSC_obs_reset_shared_file
-0x40c04a8      BSC_obs_new_system_shared_regions
-0x40c04ac      BSC_obs_shared_region_map_file_np
-0x40c04b0      BSC_obs_shared_region_make_private_np
-0x40c04b4      BSC_pthread_mutex_destroy
-0x40c04b8      BSC_pthread_mutex_init
-0x40c04bc      BSC_pthread_mutex_lock
-0x40c04c0      BSC_pthread_mutex_trylock
-0x40c04c4      BSC_pthread_mutex_unlock
-0x40c04c8      BSC_pthread_cond_init
-0x40c04cc      BSC_pthread_cond_destroy
-0x40c04d0      BSC_pthread_cond_broadcast
-0x40c04d4      BSC_pthread_cond_signal
-0x40c04d8      BSC_getsid
-0x40c04dc      BSC_settid_with_pid
-0x40c04e0      BSC_pthread_cond_timedwait
-0x40c04e4       BSC_aio_fsync
-0x40c04e8       BSC_aio_return
-0x40c04ec       BSC_aio_suspend
-0x40c04f0       BSC_aio_cancel
-0x40c04f4       BSC_aio_error
-0x40c04f8       BSC_aio_read
-0x40c04fc       BSC_aio_write
-0x40c0500      BSC_lio_listio
-0x40c0504      BSC__pthread_cond_wait
-0x40c0508      BSC_iopolicysys
-0x40c050c      BSC_#323
-0x40c0510      BSC_mlockall
-0x40c0514      BSC_munlockall
-0x40c0518      BSC_#326
-0x40c051c      BSC_issetugid
-0x40c0520      BSC_pthread_kill
-0x40c0524      BSC_pthread_sigmask
-0x40c0528      BSC_sigwait
-0x40c052c      BSC_disable_threadsignal
-0x40c0530      BSC_pthread_markcancel
-0x40c0534      BSC_pthread_canceled
-0x40c0538      BSC_semwait_signal
-0x40c053c      BSC_obs_utrace
-0x40c0540      BSC_proc_info
-0x40c0544      BSC_sendfile
-0x40c0548      BSC_stat64
-0x40c054c      BSC_fstat64
-0x40c0550      BSC_lstat64
-0x40c0554      BSC_stat64_extended
-0x40c0558      BSC_lstat64_extended
-0x40c055c      BSC_fstat64_extended
-0x40c0560      BSC_getdirentries64
-0x40c0564      BSC_statfs64
-0x40c0568      BSC_fstatfs64
-0x40c056c      BSC_getfsstat64
-0x40c0570      BSC_pthread_chdir
-0x40c0574      BSC_pthread_fchdir
-0x40c0578       BSC_audit
-0x40c057c       BSC_auditon
-0x40c0580       BSC_#352
-0x40c0584       BSC_getauid
-0x40c0588       BSC_setauid
-0x40c058c       BSC_getaudit
-0x40c0590       BSC_setaudit
-0x40c0594       BSC_getaudit_addr
-0x40c0598       BSC_setaudit_addr
-0x40c059c       BSC_auditctl
-0x40c05a0       BSC_bsdthread_create
-0x40c05a4       BSC_bsdthread_terminate
-0x40c05a8       BSC_kqueue
-0x40c05ac       BSC_kevent
-0x40c05b0       BSC_lchown
-0x40c05b4       BSC_stack_snapshot
-0x40c05b8       BSC_bsdthread_register
-0x40c05bc       BSC_workq_open
-0x40c05c0       BSC_workq_ops
-0x40c05c4       BSC_#369
-0x40c05c8       BSC_#370
-0x40c05cc       BSC_#371
-0x40c05d0       BSC_#372
-0x40c05d4       BSC_#373
-0x40c05d8       BSC_#374
-0x40c05dc       BSC_#375
-0x40c05e0       BSC_#376
-0x40c05e4       BSC_#377
-0x40c05e8       BSC_#378
-0x40c05ec       BSC_#379
-0x40c05f0      BSC_mac_execve
-0x40c05f4       BSC_mac_syscall
-0x40c05f8       BSC_mac_get_file
-0x40c06fc       BSC_mac_set_file
-0x40c0600       BSC_mac_get_link
-0x40c0604       BSC_mac_set_link
-0x40c0608       BSC_mac_get_proc
-0x40c060c       BSC_mac_set_proc
-0x40c0610       BSC_mac_get_fd
-0x40c0614       BSC_mac_set_fd
-0x40c0618       BSC_mac_get_pid
-0x40c061c       BSC_mac_get_lcid
-0x40c0620       BSC_mac_get_lctx
-0x40c0624       BSC_mac_set_lctx
-0x40c0628       BSC_setlcid
-0x40c062c       BSC_getlcid
-0x40c0630       BSC_read_nocancel
-0x40c0634       BSC_write_nocancel
-0x40c0638       BSC_open_nocancel
-0x40c063c       BSC_close_nocancel
-0x40c0640       BSC_wait4_nocancel
-0x40c0644       BSC_recvmsg_nocancel
-0x40c0648       BSC_sendmsg_nocancel
-0x40c064c       BSC_recvfrom_nocancel
-0x40c0650       BSC_accept_nocancel
-0x40c0654       BSC_msync_nocancel
-0x40c0658       BSC_fcntl_nocancel
-0x40c065c       BSC_select_nocancel
-0x40c0660       BSC_fsync_nocancel
-0x40c0664       BSC_connect_nocancel
-0x40c0668       BSC_sigsuspend_nocancel
-0x40c066c       BSC_readv_nocancel
-0x40c0670       BSC_writev_nocancel
-0x40c0674       BSC_sendto_nocancel
-0x40c0678       BSC_pread_nocancel
-0x40c067c       BSC_pwrite_nocancel
-0x40c0680       BSC_waitid_nocancel
-0x40c0684       BSC_poll_nocancel
-0x40c0688       BSC_msgsnd_nocancel
-0x40c068c       BSC_msgrcv_nocancel
-0x40c0690       BSC_sem_wait_nocancel
-0x40c0694       BSC_aio_suspend_nocancel
-0x40c0698       BSC_sigwait_nocancel
-0x40c069c       BSC_semwait_signal_nocancel
-0x40c06a0       BSC_mac_mount
-0x40c06a4       BSC_mac_get_mount
-0x40c06a8       BSC_mac_getfsstat
-0x5020004      IES_client
-0x5020008      IES_latency
-0x502000c      IES_sema
-0x5020010      IES_intctxt
-0x5020018      IES_action
-0x502001c      IES_filter
-0x5030004      TES_client
-0x5030008      TES_latency
-0x503000c      TES_sema
-0x5030010      TES_action
-0x5040004      CQ_client
-0x5040008      CQ_latency
-0x504000c      CQ_sema
-0x5040010      CQ_psema
-0x5040014      CQ_plock
-0x5040018      CQ_action
-0x5100004       PM_SetParent
-0x5100008       PM_AddChild
-0x510000c       PM_RemoveChild
-0x5100010       PM_CtrlDriver
-0x5100014       PM_CtrlDrvrE1
-0x5100018       PM_CtrlDrvrE2
-0x510001c       PM_CtrlDrvrE3
-0x5100020       PM_CtrlDrvrE4
-0x5100024       PM_IntDriver
-0x5100028       PM_AckE1
-0x510002c       PM_ChildAck
-0x5100030       PM_DriverAck
-0x5100034       PM_AckE2
-0x5100038       PM_AckE3
-0x510003c       PM_AckE4
-0x5100040       PM_DrvrAckSPwr
-0x5100044       PM_WillChange
-0x5100048       PM_DidChange
-0x510004c       PM_ReqstDomain
-0x5100050       PM_MakeUsable
-0x5100054       PM_ChangeTo
-0x5100058       PM_ChngeToPriv
-0x510005c       PM_SetAggrssvs
-0x5100060       PM_CritclTemp
-0x5100064       PM_OverrideOn
-0x5100068       PM_OverrideOff
-0x510006c       PM_EnqueueErr
-0x5100070       PM_CollapseQ
-0x5100074       PM_ChangeDone
-0x5100078       PM_CtrlDrvTrdy
-0x510007c       PM_IntDrvrTrdy
-0x5100080       PM_StartAckTmr
-0x5100084       PM_ParentChnge
-0x5100088       PM_AmndPrnChng
-0x510008c       PM_DeviceChnge
-0x5100090       PM_ReqDenied
-0x5100094       PM_CtrlDrvrE45
-0x5100098       PM_PrgrmHrdwre
-0x510009c       PM_InfDrvrPre
-0x51000a0       PM_InfDrvrPost
-0x51000a4       PM_RemoveDrivr
-0x51000a8       PM_IdlTimerPrd
-0x51000ac       PM_SystemWake
-0x51000b0       PM_AckE5
-0x51000b4       PM_ClientAck
-0x51000b8       PM_ClientTardy
-0x51000bc       PM_ClientCancl
-0x51000c0       PM_ClientNotfy
-0x51000c4       PM_AppNotify
-0x5310004       CPUPM_PSTATE
-0x5310008       CPUPM_IDLE_CSTATE
-0x531000c       CPUPM_IDLE_HALT
-0x5310010       CPUPM_IDLE_LOOP
-0x5310014       CPUPM_HPET_START
-0x5310018       CPUPM_HPET_END
-0x531001c       CPUPM_HPET_INTR
-0x5310020       CPUPM_PSTATE_HW
-0x5310024       CPUPM_PSTATE_LIMIT
-0x5310028       CPUPM_PSTATE_PARK
-0x531002c       CPUPM_PSTATE_START
-0x5310030       CPUPM_PSTATE_PAUSE
-0x5310034       CPUPM_PSTATE_RESUME
-0x5310038       CPUPM_PSTATE_DOWN
-0x531003c       CPUPM_PSTATE_UP
-0x5310040       CPUPM_PSTATE_NORM
-0x5310044       CPUPM_PSTATE_FORCE
-0x5310048       CPUPM_PSTATE_TIMEOUT
-0x531004c       CPUPM_PSTATE_SETTO
-0x5310050       CPUPM_SET_DEADLINE
-0x5310054       CPUPM_GET_DEADLINE
-0x5310058       CPUPM_DEADLINE
-0x531005c       CPUPM_IDLE_SNOOP
-0x5310060       CPUPM_IDLE_LATENCY
-0x5310064       CPUPM_IDLE_WAKEUP
-0x5310068       CPUPM_IDLE_SW_WAKEUP
-0x531006c       CPUPM_IDLE_SELECT
-0x5310070       CPUPM_IDLE_SELECTED
-0x5310074       CPUPM_IDLE_INTSKIP
-0x5310078       CPUPM_IDLE_LOCK
-0x531007c       CPUPM_IDLE_UNLOCK
-0x5310080       CPUPM_IDLE_NO_HPET
-0x5310084       CPUPM_FI_UP
-0x5310088       CPUPM_FI_UP_CPU
-0x531008c       CPUPM_FI_MP
-0x5310090       CPUPM_FI_MP_CPU
-0x5310094       CPUPM_FI_PAUSE
-0x5310098       CPUPM_FI_RUN
-0x531009c       CPUPM_PROC_HALT
-0x53100a0       CPUPM_TRACE_STOPPED
-0x53100a4       CPUPM_HPET_INT_LOCK
-0x53100a8       CPUPM_HPET_INT_UNLOCK
-0x53100ac       CPUPM_HPET_TRY_AGAIN
-0x53100b0       CPUPM_HPET_SETDEADLINE
-0x53100b4       CPUPM_LOCK_HELDBY
-0x53100b8       CPUPM_HPET_DELTA
-0x53100bc       CPUPM_HPET_TOO_LATE
-0x53100c0       CPUPM_HPET_NO_DEADLINE
-0x53100c4       CPUPM_IDLE
-0x53100c8       CPUPM_CORE_CHK_DEADLINE
-0x53100cc       CPUPM_SET_HPET_DEADLINE
-0x53100d0       CPUPM_HPET_READ
-0x53100d4       CPUPM_TIME_ADJUST
-0x53100d8       CPUPM_IDLE_MWAIT
-0x53100dc       CPUPM_FI_SLAVE_IDLE
-0x53100e0       CPUPM_FI_SLAVE_BLOCK
-0x53100e4       CPUPM_FI_MAST_SIGNAL
-0x53100e8       CPUPM_CORE_DEADLINE
-0x53100ec       CPUPM_IDLE_FAST
-0x53100f0       CPUPM_IDLE_PAUSE
-0x53100f4       CPUPM_IDLE_SHORT
-0x53100f8       CPUPM_IDLE_NORMAL
-0x53100fc       CPUPM_IDLE_SPURIOUS
-0x5310100       CPUPM_PSTATE_INFO
-0x5310104       CPUPM_PSTATE_INFO_HW
-0x5310108       CPUPM_PSTATE_FSM
-0x531010c       CPUPM_PSTATE_FSM_STEP
-0x5310110       CPUPM_PSTATE_FSM_EVAL
-0x5310114       CPUPM_PSTATE_FSM_MAP
-0x5310118       CPUPM_CPUSTEP_STEP
-0x531011c       CPUPM_CPUSTEP_STEP_UP
-0x5310120       CPUPM_CPUSTEP_STEP_DOWN
-0x5310124       CPUPM_CPUSTEP_AVAIL
-0x5310128       CPUPM_CPUSTEP_AVAIL_STEP
-0x531012c       CPUPM_CPUSTEP_AVAIL_CHNG
-0x5310130       CPUPM_CPUSTEP_LOAD
-0x5310134       CPUPM_CPUSTEP_START
-0x5310138       CPUPM_CPUSTEP_STOP
-0x531013c       CPUPM_CPUSTEP_COPY
-0x5310140       CPUPM_CPUSTEP_CLEAR
-0x5310144       CPUPM_CPUSTEP_RUNCOUNT
-0x5310148       CPUPM_CPUSTEP_WAKEUP
-0x7000004      TRACE_DATA_NEWTHREAD
-0x7010004      TRACE_STRING_NEWTHREAD
-0x7010008      TRACE_STRING_EXEC
-0x8000000      USER_TEST
-0x8000004      USER_run
-0x8000008      USER_join
-0x800000c      USER_create
-0x8000010      USER_pthread_create
-0x8000014      USER_pthread_exit
-0x8000018      USER_pthread_join
-0x800001c      USER_pthread_run
-0x8000020      USER_pthread_cleanup_push
-0x8040000      USER_STOP
-0x21800000     SMB_smbd_idle
-0x21800004     SMB_syscall_opendir
-0x21800008     SMB_syscall_readdir
-0x2180000c     SMB_syscall_seekdir
-0x21800010     SMB_syscall_telldir
-0x21800014     SMB_syscall_rewinddir
-0x21800018     SMB_syscall_mkdir
-0x2180001c     SMB_syscall_rmdir
-0x21800020     SMB_syscall_closedir
-0x21800024     SMB_syscall_open
-0x21800028     SMB_syscall_close
-0x2180002c     SMB_syscall_read
-0x21800030     SMB_syscall_pread
-0x21800034     SMB_syscall_write
-0x21800038     SMB_syscall_pwrite
-0x2180003c     SMB_syscall_lseek
-0x21800040     SMB_syscall_sendfile
-0x21800044     SMB_syscall_rename
-0x21800048     SMB_syscall_fsync
-0x2180004c     SMB_syscall_stat
-0x21800050     SMB_syscall_fstat
-0x21800054     SMB_syscall_lstat
-0x21800058     SMB_syscall_unlink
-0x2180005c     SMB_syscall_chmod
-0x21800060     SMB_syscall_fchmod
-0x21800064     SMB_syscall_chown
-0x21800068     SMB_syscall_fchown
-0x2180006c     SMB_syscall_chdir
-0x21800070     SMB_syscall_getwd
-0x21800074     SMB_syscall_utime
-0x21800078     SMB_syscall_ftruncate
-0x2180007c     SMB_syscall_fcntl_lock
-0x21800080     SMB_syscall_kernel_flock
-0x21800084     SMB_syscall_fcntl_getlock
-0x21800088     SMB_syscall_readlink
-0x2180008c     SMB_syscall_symlink
-0x21800090     SMB_syscall_link
-0x21800094     SMB_syscall_mknod
-0x21800098     SMB_syscall_realpath
-0x2180009c     SMB_syscall_get_quota
-0x218000a0     SMB_syscall_set_quota
-0x218000a4     SMB_smbmkdir
-0x218000a8     SMB_smbrmdir
-0x218000ac     SMB_smbopen
-0x218000b0     SMB_smbcreate
-0x218000b4     SMB_smbclose
-0x218000b8     SMB_smbflush
-0x218000bc     SMB_smbunlink
-0x218000c0     SMB_smbmv
-0x218000c4     SMB_smbgetatr
-0x218000c8     SMB_smbsetatr
-0x218000cc     SMB_smbread
-0x218000d0     SMB_smbwrite
-0x218000d4     SMB_smblock
-0x218000d8     SMB_smbunlock
-0x218000dc     SMB_smbctemp
-0x218000e0     SMB_smbmknew
-0x218000e4     SMB_smbcheckpath
-0x218000e8     SMB_smbexit
-0x218000ec     SMB_smblseek
-0x218000f0     SMB_smblockread
-0x218000f4     SMB_smbwriteunlock
-0x218000f8     SMB_smbreadbraw
-0x218000fc     SMB_smbreadbmpx
-0x21800100     SMB_smbreadbs
-0x21800104     SMB_smbwritebraw
-0x21800108     SMB_smbwritebmpx
-0x2180010c     SMB_smbwritebs
-0x21800110     SMB_smbwritec
-0x21800114     SMB_smbsetattre
-0x21800118     SMB_smbgetattre
-0x2180011c     SMB_smblockingx
-0x21800120     SMB_smbtrans
-0x21800124     SMB_smbtranss
-0x21800128     SMB_smbioctl
-0x2180012c     SMB_smbioctls
-0x21800130     SMB_smbcopy
-0x21800134     SMB_smbmove
-0x21800138     SMB_smbecho
-0x2180013c     SMB_smbwriteclose
-0x21800140     SMB_smbopenx
-0x21800144     SMB_smbreadx
-0x21800148     SMB_smbwritex
-0x2180014c     SMB_smbtrans2
-0x21800150     SMB_smbtranss2
-0x21800154     SMB_smbfindclose
-0x21800158     SMB_smbfindnclose
-0x2180015c     SMB_smbtcon
-0x21800160     SMB_smbtdis
-0x21800164     SMB_smbnegprot
-0x21800168     SMB_smbsesssetupx
-0x2180016c     SMB_smbulogoffx
-0x21800170     SMB_smbtconx
-0x21800174     SMB_smbdskattr
-0x21800178     SMB_smbsearch
-0x2180017c     SMB_smbffirst
-0x21800180     SMB_smbfunique
-0x21800184     SMB_smbfclose
-0x21800188     SMB_smbnttrans
-0x2180018c     SMB_smbnttranss
-0x21800190     SMB_smbntcreatex
-0x21800194     SMB_smbntcancel
-0x21800198     SMB_smbntrename
-0x2180019c     SMB_smbsplopen
-0x218001a0     SMB_smbsplwr
-0x218001a4     SMB_smbsplclose
-0x218001a8     SMB_smbsplretq
-0x218001ac     SMB_smbsends
-0x218001b0     SMB_smbsendb
-0x218001b4     SMB_smbfwdname
-0x218001b8     SMB_smbcancelf
-0x218001bc     SMB_smbgetmac
-0x218001c0     SMB_smbsendstrt
-0x218001c4     SMB_smbsendend
-0x218001c8     SMB_smbsendtxt
-0x218001cc     SMB_smbinvalid
-0x218001d0     SMB_pathworks_setdir
-0x218001d4     SMB_trans2_open
-0x218001d8     SMB_trans2_findfirst
-0x218001dc     SMB_trans2_findnext
-0x218001e0     SMB_trans2_qfsinfo
-0x218001e4     SMB_trans2_setfsinfo
-0x218001e8     SMB_trans2_qpathinfo
-0x218001ec     SMB_trans2_setpathinfo
-0x218001f0     SMB_trans2_qfileinfo
-0x218001f4     SMB_trans2_setfileinfo
-0x218001f8     SMB_trans2_fsctl
-0x218001fc     SMB_trans2_ioctl
-0x21800200     SMB_trans2_findnotifyfirst
-0x21800204     SMB_trans2_findnotifynext
-0x21800208     SMB_trans2_mkdir
-0x2180020c     SMB_trans2_session_setup
-0x21800210     SMB_trans2_get_dfs_referral
-0x21800214     SMB_trans2_report_dfs_inconsistancy
-0x21800218     SMB_nt_transact_create
-0x2180021c     SMB_nt_transact_ioctl
-0x21800220     SMB_nt_transact_set_security_desc
-0x21800224     SMB_nt_transact_notify_change
-0x21800228     SMB_nt_transact_rename
-0x2180022c     SMB_nt_transact_query_security_desc
-0x21800230     SMB_nt_transact_get_user_quota
-0x21800234     SMB_nt_transact_set_user_quota
-0x21800238     SMB_get_nt_acl
-0x2180023c     SMB_fget_nt_acl
-0x21800240     SMB_set_nt_acl
-0x21800244     SMB_fset_nt_acl
-0x21800248     SMB_chmod_acl
-0x2180024c     SMB_fchmod_acl
-0x21800250     SMB_name_release
-0x21800254     SMB_name_refresh
-0x21800258     SMB_name_registration
-0x2180025c     SMB_node_status
-0x21800260     SMB_name_query
-0x21800264     SMB_host_announce
-0x21800268     SMB_workgroup_announce
-0x2180026c     SMB_local_master_announce
-0x21800270     SMB_master_browser_announce
-0x21800274     SMB_lm_host_announce
-0x21800278     SMB_get_backup_list
-0x2180027c     SMB_reset_browser
-0x21800280     SMB_announce_request
-0x21800284     SMB_lm_announce_request
-0x21800288     SMB_domain_logon
-0x2180028c     SMB_sync_browse_lists
-0x21800290     SMB_run_elections
-0x21800294     SMB_election
-0xb000000      AFP_asp_tcp_usr_send
-0xb000004      AFP_asp_tcp_usr_send_after_Request
-0xb000008      AFP_asp_tcp_usr_send_after_FindDSIReq
-0xb00000c      AFP_asp_tcp_usr_send_after_Reply
-0xb000010      AFP_asp_tcp_slowtimo
-0xb000014      AFP_asp_tcp_usr_control
-0xb000018      AFP_asp_tcp_fasttimo
-0xb000020      AFP_Send
-0xb000024      AFP_Send_before_sosend
-0xb000028      AFP_Send_after_sosend
-0xb00002c      AFP_Send_before_write
-0xb000030      AFP_Send_after_write
-0xb000040      AFP_Reply
-0xb000044      AFP_Reply_rcvdAlready
-0xb000048      AFP_Reply_before_RcvLock
-0xb00004c      AFP_Reply_fail_RcvLock
-0xb000050      AFP_Reply_before_ReadDSIHdr
-0xb000054      AFP_Reply_after_ReadDSIHdr
-0xb000058      AFP_Reply_fail_ReadDSIHdr
-0xb00005c      AFP_Reply_after_FindDSIReqInfo
-0xb000060      AFP_Reply_SetAFPCmd
-0xb000064      AFP_Reply_before_ReadDSIPacket
-0xb000068      AFP_Reply_setRcvdReplyLen
-0xb000070      AFP_SendReply
-0xb000080      AFP_CreateDSIHeader
-0xb000084      AFP_CreateDSIHeader_after_GetReqID
-0xb000090      AFP_Request
-0xb0000a0      AFP_ReceiveLock
-0xb0000b0      AFP_ReceiveWakeUp
-0xb0000c0      AFP_ReceiveUnLock
-0xb0000e0      AFP_SendLock
-0xb0000e4      AFP_SendUnLock
-0xb0000f0      AFP_SendQueueLock
-0xb000100      AFP_SendQueueUnLock
-0xb000110      AFP_ReadDSIHeader
-0xb000120      AFP_Receive
-0xb000124      AFP_Receive_before_sorcv
-0xb000128      AFP_Receive_after_sorcv
-0xb000130      AFP_ReadDSIPacket
-0xb000140      AFP_DoCopyOut
-0xb000150      AFP_DoCopyIn
-0xb000160      AFP_CheckRcvTickle
-0xb000164      AFP_CheckRcvTickleTO
-0xb000170      AFP_CheckSendTickle
-0xb000180      AFP_CheckIncomingPkts
-0xb000190      AFP_ProcessOptions
-0xb000200      AFP_FindDSIReqInfo
-0xb000204      AFP_FindDSIReqInfo_foundReqInfo
-0xb000208      AFP_FindDSIReqInfo_flags
-0xb00020c      AFP_FindDSIReqLeave
-0xb000210      AFP_UsrDisconnect
-0xc000000      AFPVFS_UserReply
-0xc000004      AFPVFS_UserReplyGetMbuf
-0xc000008      AFPVFS_UserReplysosend
-0xc000010      AFPVFS_UserCommand
-0xc000018      AFPVFS_UserCommandsosend
-0xc000020      AFPVFS_ReadFork
-0xc000024      AFPVFS_ReadForkFillQPB
-0xc000028      AFPVFS_ReadForkNbrRequests
-0xc00002c      AFPVFS_ReadForkSendQPB
-0xc000030      AFPVFS_ReadForkSendErr
-0xc000040      AFPVFS_ReadForkGetReply
-0xc000044      AFPVFS_ReadForkGetReplyResult
-0xc000050      AFPVFS_WriteFork
-0xc000054      AFPVFS_WriteForkFillQPB
-0xc000058      AFPVFS_WriteForkNbrRequests
-0xc00005c      AFPVFS_WriteForkSendQPB
-0xc000060      AFPVFS_WriteForkSendErr
-0xc000064      AFPVFS_WriteForkGetReply
-0xc000068      AFPVFS_WriteForkGetReplyResult
-0xc000070      AFPVFS_GetAttr
-0xc000080      AFPVFS_SetAttr
-0xc000090      AFPVFS_GetAttrList
-0xc0000a0      AFPVFS_SetAttrList
-0xc0000b0      AFPVFS_FSCTL
-0xc0000c0      AFPVFS_LookUp
-0xc0000d0      AFPVFS_CacheLookUp
-0xc0000e0      AFPVFS_Write
-0xc0000e4      AFPVFS_WriteNoCluster
-0xc0000e8      AFPVFS_WriteDone
-0xc0000f0      AFPVFS_DoWrite
-0xc000100      AFPVFS_Lock
-0xc000110      AFPVFS_Statfs
-0xc000120      AFPVFS_Sync
-0xc000130      AFPVFS_VGet
-0xc000140      AFPVFS_FlushFiles
-0xc000150      AFPVFS_Create
-0xc000160      AFPVFS_Mknod
-0xc000170      AFPVFS_Open
-0xc000180      AFPVFS_Close
-0xc000190      AFPVFS_Access
-0xc000194      AFPVFS_AccessUID
-0xc000198      AFPVFS_AccessGID
-0xc00019c      AFPVFS_AccessWID
-0xc0001a0      AFPVFS_Writeperm
-0xc0001b0      AFPVFS_Chmod
-0xc0001c0      AFPVFS_Chflags
-0xc0001d0      AFPVFS_Exchange
-0xc0001e0      AFPVFS_Chid
-0xc0001f0      AFPVFS_Fsync
-0xc000200      AFPVFS_Remove
-0xc000210      AFPVFS_Rename
-0xc000220      AFPVFS_Copyfile
-0xc000230      AFPVFS_Mkdir
-0xc000230      AFPVFS_Rmdir
-0xc000240      AFPVFS_Symlink
-0xc000250      AFPVFS_Readdir
-0xc000260      AFPVFS_Readdirattr
-0xc000264      AFPVFS_Readdirattr1
-0xc000268      AFPVFS_Readdirattr2
-0xc00026c      AFPVFS_Readdirattr3
-0xc000270      AFPVFS_Readlink
-0xc000280      AFPVFS_Abortop
-0xc000290      AFPVFS_Inactive
-0xc0002a0      AFPVFS_Reclaim
-0xc0002b0      AFPVFS_Unlock
-0xc0002c0      AFPVFS_Islocked
-0xc0002d0      AFPVFS_Pathconf
-0xc0002e0      AFPVFS_Update
-0xc0002e0      AFPVFS_Vinit
-0xc0002f0      AFPVFS_Makenode
-0xc000300      AFPVFS_Allocate
-0xc000310      AFPVFS_Search
-0xc000320      AFPVFS_Reconnect
-0x14200000     TRACE_LAST_WRAPPER
index b21ef26bcca8ff4361c3c831b66c7c2ca86eed1a..c5fc276a00d6a8f5f93cec4ebeecc0b13b7fbf18 100644 (file)
@@ -6,7 +6,7 @@ CFILES = shutdown.c
 USERDEFS = kextmanager.defs
 MANPAGES = shutdown.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 Extra_Frameworks = -framework IOKit
index 502fbde1b243fc34b41a45aa430f32e6f264121a..894c3e6d2327357501957a68d804345088cc862e 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /bin
 CFILES = sync.c
 MANPAGES = sync.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_CC_Flags += -D__FBSDID=__RCSID
 Extra_LD_Flags = -dead_strip
 
index 9c0145919c214872be57d5eb6324f12cce673b2e..3dac0956c4be1fb3120ec9fee1ae77222fd9736e 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = sysctl.c
 MANPAGES = sysctl.8 sysctl.conf.5
 
-Extra_CC_Flags = -mdynamic-no-pic -Wall -Werror
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index c6498269975dba121f7af4d54c63f8c94ec98a4b..3b16137a38687189a2fee0cb23266b5c58a054e0 100644 (file)
@@ -1,23 +1,22 @@
-/*
- * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
+ /*
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -157,7 +152,7 @@ struct list secondlevel[] = {
        { username, USER_MAXID },       /* CTL_USER_NAMES */
 };
 
-static int     Aflag, aflag, bflag, nflag, wflag, Xflag;
+static int     Aflag, aflag, bflag, hflag, nflag, wflag, Xflag;
 static int     foundSome = 0;
 static int     invalid_name_used = 0;
 
@@ -195,6 +190,7 @@ main(argc, argv)
                        case 'A': Aflag = 1; break;
                        case 'a': aflag = 1; break;
                        case 'b': bflag = 1; break;
+                       case 'h': hflag = 1; break;
                        case 'n': nflag = 1; break;
                        case 'w': wflag = 1; break;
                        case 'X': Xflag = Aflag = 1; break;
@@ -745,8 +741,13 @@ parse(char *string, int flags)
                return;
        }
 
+       /*
+        * An non-zero return here is an OID space containing parameters which
+        * needs to be ignored in the interests of backward compatibility with
+        * pre-newsysctl sysctls.
+        */
        if (oidfmt(mib, len, fmt, &kind))
-               err(1, "couldn't find format of oid '%s'", bufp);
+               return;
 
        if (!wflag) {
                if ((kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -772,7 +773,7 @@ parse(char *string, int flags)
                                        if ((uintval == 0) &&
                                            (errno == EINVAL)) {
                                                errx(1, "invalid argument: %s",
-                                                       newval);
+                                                       (char *)newval);
                                                return;
                                        }
                                        newval = &uintval;
@@ -782,7 +783,7 @@ parse(char *string, int flags)
                                        if ((intval == 0) &&
                                            (errno == EINVAL)) {
                                                errx(1, "invalid argument: %s",
-                                                       newval);
+                                                       (char *)newval);
                                                return;
                                        }
                                        newval = &intval;
@@ -794,11 +795,11 @@ parse(char *string, int flags)
                        case CTLTYPE_QUAD:
                                quadval = strtoq(newval, NULL, 0);
                                if ((quadval == 0) && (errno == EINVAL)) {
-                                       errx(1, "invalid argument %s", newval);
+                                       errx(1, "invalid argument %s", (char *)newval);
                                        return;
                                }
                                newval = &quadval;
-                               newsize = sizeof quadval;
+                               newsize = sizeof(quadval);
                                break;
                        default:
                                errx(1, "oid '%s' is type %d,"
@@ -842,9 +843,13 @@ static int
 S_clockinfo(int l2, void *p)
 {
        struct clockinfo *ci = (struct clockinfo*)p;
-       if (l2 != sizeof *ci)
-               err(1, "S_clockinfo %d != %d", l2, sizeof *ci);
-       printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
+
+       if (l2 != sizeof(*ci)) {
+               warnx("S_clockinfo %d != %ld", l2, sizeof(*ci));
+               return (1);
+       }
+       printf(hflag ? "{ hz = %'d, tick = %'d, tickadj = %'d, profhz = %'d, stathz = %'d }" :
+               "{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
                ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
        return (0);
 }
@@ -854,10 +859,11 @@ S_loadavg(int l2, void *p)
 {
        struct loadavg *tv = (struct loadavg*)p;
 
-       if (l2 != sizeof *tv)
-               err(1, "S_loadavg %d != %d", l2, sizeof *tv);
-
-       printf("{ %.2f %.2f %.2f }",
+       if (l2 != sizeof(*tv)) {
+               warnx("S_loadavg %d != %ld", l2, sizeof(*tv));
+               return (1);
+       }
+       printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
                (double)tv->ldavg[0]/(double)tv->fscale,
                (double)tv->ldavg[1]/(double)tv->fscale,
                (double)tv->ldavg[2]/(double)tv->fscale);
@@ -871,42 +877,50 @@ S_timeval(int l2, void *p)
        time_t tv_sec;
        char *p1, *p2;
 
-       if (l2 != sizeof *tv)
-               err(1, "S_timeval %d != %d", l2, sizeof *tv);
-       printf("{ sec = %ld, usec = %ld } ",
-               (long) tv->tv_sec, (long) tv->tv_usec);
+       if (l2 != sizeof(*tv)) {
+               warnx("S_timeval %d != %ld", l2, sizeof(*tv));
+               return (1);
+       }
+       printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
+               "{ sec = %jd, usec = %ld } ",
+               (intmax_t)tv->tv_sec, (long)tv->tv_usec);
        tv_sec = tv->tv_sec;
        p1 = strdup(ctime(&tv_sec));
        for (p2=p1; *p2 ; p2++)
                if (*p2 == '\n')
                        *p2 = '\0';
        fputs(p1, stdout);
+       free(p1);
        return (0);
 }
 
 static int
 S_xswusage(int l2, void *p)
 {
-        struct xsw_usage       *xsu = (struct xsw_usage *)p;
+        struct xsw_usage *xsu = (struct xsw_usage *)p;
   
-       if(l2 != sizeof (*xsu))
-           err(1, "S_xswusage %d != %d", l2, sizeof *xsu);
-
+       if (l2 != sizeof(*xsu)) {
+               warnx("S_xswusage %d != %ld", l2, sizeof(*xsu));
+               return (1);
+       }
        fprintf(stdout,
                "total = %.2fM  used = %.2fM  free = %.2fM  %s",
-               ((double) xsu->xsu_total) / (1024.0 * 1024.0),
-               ((double) xsu->xsu_used) / (1024.0 * 1024.0),
-               ((double) xsu->xsu_avail) / (1024.0 * 1024.0),
+               ((double)xsu->xsu_total) / (1024.0 * 1024.0),
+               ((double)xsu->xsu_used) / (1024.0 * 1024.0),
+               ((double)xsu->xsu_avail) / (1024.0 * 1024.0),
                xsu->xsu_encrypted ? "(encrypted)" : "");
-       return 0;
+       return (0);
 }
 
 static int
 T_dev_t(int l2, void *p)
 {
        dev_t *d = (dev_t *)p;
-       if (l2 != sizeof *d)
-               err(1, "T_dev_T %d != %d", l2, sizeof *d);
+
+       if (l2 != sizeof(*d)) {
+               warnx("T_dev_T %d != %ld", l2, sizeof(*d));
+               return (1);
+       }
        if ((int)(*d) != -1) {
                if (minor(*d) > 255 || minor(*d) < 0)
                        printf("{ major = %d, minor = 0x%x }",
@@ -957,17 +971,27 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
        qoid[1] = 4;
        memcpy(qoid + 2, oid, len * sizeof(int));
 
-       j = sizeof buf;
+       j = sizeof(buf);
        i = sysctl(qoid, len + 2, buf, &j, 0, 0);
-       if (i)
-               err(1, "sysctl fmt %d %d %d", i, j, errno);
+       if (i) {
+               /*
+                * An ENOENT error return indicates that the OID in question
+                * is a node OID followed not by additional OID elements, but
+                * by integer parameters.  We really do not want to support
+                * this type of thing going forward, but we alow it here for
+                * historical compatibility.  Eventually, this will go away.
+                */
+               if (errno == ENOENT)
+                       return ENOENT;
+               err(1, "sysctl fmt %d %ld %d", i, j, errno);
+       }
 
        if (kind)
                *kind = *(u_int *)buf;
 
        if (fmt)
                strcpy(fmt, (char *)(buf + sizeof(u_int)));
-       return 0;
+       return (0);
 }
 
 /*
@@ -997,7 +1021,7 @@ show_var(int *oid, int nlen, int show_masked)
        j = sizeof name;
        i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
        if (i || !j)
-               err(1, "sysctl name %d %d %d", i, j, errno);
+               err(1, "sysctl name %d %ld %d", i, j, errno);
 
        /* find an estimate of how much we need for this var */
        j = 0;
@@ -1021,8 +1045,20 @@ show_var(int *oid, int nlen, int show_masked)
        qoid[1] = 4;
        j = sizeof buf;
        i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
+       /*
+        * An ENOENT error return indicates that the OID in question
+        * is a node OID followed not by additional OID elements, but
+        * by integer parameters.  We really do not want to support
+        * this type of thing going forward, but we alow it here for
+        * historical compatibility.  Eventially, this will go away.
+        */
+       if (i && errno == ENOENT) {
+               retval = 1;
+               goto RETURN;
+       }
+               
        if (i || !j)
-               err(1, "sysctl fmt %d %d %d", i, j, errno);
+               err(1, "sysctl fmt %d %ld %d", i, j, errno);
 
        kind = *(u_int *)buf;
        if (!show_masked && (kind & CTLFLAG_MASKED)) {
@@ -1170,7 +1206,7 @@ sysctl_all (int *oid, int len)
                        if (errno == ENOENT)
                                return 0;
                        else
-                               err(1, "sysctl(getnext) %d %d", j, l2);
+                               err(1, "sysctl(getnext) %d %ld", j, l2);
                }
 
                l2 /= sizeof (int);
diff --git a/trace.tproj/Makefile b/trace.tproj/Makefile
new file mode 100644 (file)
index 0000000..dc51126
--- /dev/null
@@ -0,0 +1,14 @@
+Project = trace
+Install_Dir = /usr/bin
+
+CFILES = trace.c
+MANPAGES = trace.1
+
+Extra_CC_Flags =
+Extra_LD_Flags = -dead_strip
+
+Extra_CC_Flags += -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders\
+       -I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders/bsd
+Extra_LD_Flags += -lutil
+
+include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
diff --git a/trace.tproj/trace.1 b/trace.tproj/trace.1
new file mode 100644 (file)
index 0000000..9cc4cc8
--- /dev/null
@@ -0,0 +1,60 @@
+.\" Copyright (c) 2010, Apple Inc.  All rights reserved.
+.\"
+.Dd October 28, 2010
+.Dt TRACE 1
+.Os "Mac OS X"
+.Sh NAME
+.Nm trace
+.Nd configure and record kernel trace events
+.Sh SYNOPSIS
+.Nm trace
+.Fl h
+.Pp
+.Nm trace
+.Fl i
+.Op Fl b Ar numbufs
+.Pp
+.Nm trace
+.Fl g
+.Pp
+.Nm trace
+.Fl d
+.Op Fl a Ar pid | Fl x Ar pid
+.Pp
+.Nm trace
+.Fl r
+.Pp
+.Nm trace
+.Fl n
+.Pp
+.Nm trace
+.Fl e
+.Op Fl c Ar class Oo Fl p Ar class Oc Oo Fl s Ar subclass Oc
+.Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code | Fl k Ar code | Fl k Ar code | Fl k Ar code
+.Pp
+.Nm trace
+.Fl E
+.Op Fl c Ar class Oo Fl p Ar class Oc Oo Fl s Ar subclass Oc
+.Op Fl a Ar pid | Fl x Ar pid
+.Op Fl k Ar code | Fl k Ar code | Fl k Ar code | Fl k Ar code
+.Ar executable_path
+.Op Ar optional args to executable
+.Pp
+.Nm trace
+.Fl t
+.Op Fl R Ar rawfile
+.Op Fl o Ar OutputFilename
+.Op Ar CodeFilename
+.Sh DESCRIPTION
+The
+.Nm trace
+command allows developers to initialize and configure
+the kernel trace subsystem. Trace events can be recorded
+to an in-memory buffer, or logged directly to a file. Raw
+data files can later be decoded to a plaintext format.
+.Sh SEE ALSO
+.Xr fs_usage 1 ,
+.Xr sc_usage 1 ,
+.Xr latency 1 ,
+.Xr top 1
diff --git a/trace.tproj/trace.c b/trace.tproj/trace.c
new file mode 100644 (file)
index 0000000..e884179
--- /dev/null
@@ -0,0 +1,2240 @@
+/*
+    cc -I/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -arch x86_64 -arch i386  -O -o trace trace.c
+*/
+
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mbuf.h>
+#include <sys/mman.h>
+#include <sys/ucred.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+#include <err.h>
+
+#include <libutil.h>
+
+#include <sys/kdebug.h>
+
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+
+int nbufs = 0;
+int enable_flag=0;
+int execute_flag=0;
+int logRAW_flag=0;
+int LogRAW_flag=0;
+int readRAW_flag = 0;
+int disable_flag=0;
+int init_flag=0;
+int kval_flag=0;
+int remove_flag=0;
+int bufset_flag=0;
+int bufget_flag=0;
+int class_flag=0;
+int subclass_flag=0;
+int trace_flag=0;
+int nowrap_flag=0;
+int freerun_flag=0;
+int verbose_flag=0;
+int pid_flag=0;
+int pid_exflag=0;
+int ppt_flag=0;
+unsigned int class=0;
+unsigned int class2=0;
+unsigned int subclass=0;
+unsigned int value1=0;
+unsigned int value2=0;
+unsigned int value3=0;
+unsigned int value4=0;
+pid_t pid=0;
+int reenable=0;
+
+int mib[6];
+size_t needed;
+
+char *logfile = (char *)0;      /* This file is trace format */
+char *RAW_file = (char *)0;
+FILE *output_file;
+int   output_fd;
+
+extern char **environ;
+
+
+#define DBG_FUNC_ALL           (DBG_FUNC_START | DBG_FUNC_END)
+#define DBG_FUNC_MASK  0xfffffffc
+#define SHORT_HELP 1
+#define LONG_HELP 0
+
+#define CSC_MASK               0xffff0000
+
+#define VFS_LOOKUP             0x03010090
+#define BSC_exit               0x040c0004
+#define BSC_thread_terminate   0x040c05a4
+#define TRACE_DATA_NEWTHREAD   0x07000004
+#define TRACE_STRING_NEWTHREAD 0x07010004
+#define TRACE_STRING_EXEC      0x07010008
+#define TRACE_LOST_EVENTS      0x07020008
+#define MACH_SCHEDULED         0x01400000
+#define MACH_MAKERUNNABLE      0x01400018
+#define MACH_STKHANDOFF                0x01400008
+
+#define EMPTYSTRING ""
+#define UNKNOWN "unknown"
+
+char tmpcommand[MAXCOMLEN];
+
+int total_threads = 0;
+int nthreads = 0;
+kd_threadmap *mapptr = 0;
+
+/* 
+   If NUMPARMS changes from the kernel, 
+   then PATHLENGTH will also reflect the change
+   This is for the vfslookup entries that
+   return pathnames
+*/
+#define NUMPARMS 23
+#define PATHLENGTH (NUMPARMS*sizeof(long))
+
+
+#define US_TO_SLEEP    50000
+#define BASE_EVENTS    500000
+
+
+double divisor;
+
+typedef struct {
+       uint32_t debugid;
+       char    *debug_string;
+} code_type_t;
+
+code_type_t * codesc = 0;
+
+
+typedef struct event *event_t;
+
+struct event {
+       event_t   ev_next;
+
+       uintptr_t ev_thread;
+       uint32_t  ev_debugid;
+       uint64_t  ev_timestamp;
+};
+
+typedef struct lookup *lookup_t;
+
+struct lookup {
+       lookup_t  lk_next;
+       
+       uintptr_t lk_thread;
+       uintptr_t lk_dvp;
+       long     *lk_pathptr;
+       long      lk_pathname[NUMPARMS + 1];
+};
+
+typedef struct threadmap *threadmap_t;
+
+struct threadmap {
+       threadmap_t     tm_next;
+       
+       uintptr_t       tm_thread;
+       uintptr_t       tm_pthread;
+       boolean_t       tm_deleteme;
+       char            tm_command[MAXCOMLEN + 1];
+};
+       
+
+#define HASH_SIZE      1024
+#define HASH_MASK      1023
+
+event_t                event_hash[HASH_SIZE];
+lookup_t       lookup_hash[HASH_SIZE];
+threadmap_t    threadmap_hash[HASH_SIZE];
+
+event_t                event_freelist;
+lookup_t       lookup_freelist;
+threadmap_t    threadmap_freelist;
+threadmap_t    threadmap_temp;
+
+
+#define                SBUFFER_SIZE    (128 * 4096)
+char           sbuffer[SBUFFER_SIZE];
+
+int secs_to_run = 0;
+
+
+kbufinfo_t bufinfo = {0, 0, 0, 0};
+
+int   codenum = 0;
+int   codeindx_cache = 0;
+char  codefile[] = "codes";
+char *cfile = (char *)0;
+
+// Forward declarations
+static void quit(char *);
+static int match_debugid(unsigned int, char *, int *);
+static void usage(int short_help);
+static int argtoi(int flag, char *req, char *str, int base);
+static int parse_codefile(char *filename);
+static int read_command_map(int, int);
+static void find_thread_command(kd_buf *, char **);
+static void create_map_entry(uintptr_t, char *);
+static void getdivisor();
+static unsigned long argtoul();
+
+
+#ifndef        KERN_KDWRITETR
+#define KERN_KDWRITETR 17
+#endif
+
+#ifndef        KERN_KDWRITEMAP
+#define KERN_KDWRITEMAP        18
+#endif
+
+#ifndef F_FLUSH_DATA
+#define F_FLUSH_DATA   40
+#endif
+
+#ifndef RAW_VERSION1
+typedef struct {
+        int             version_no;
+        int             thread_count;
+        uint64_t        TOD_secs;
+        uint32_t        TOD_usecs;
+} RAW_header;
+
+#define RAW_VERSION0   0x55aa0000
+#define RAW_VERSION1    0x55aa0101
+#endif
+
+
+RAW_header     raw_header;
+
+
+
+void set_enable(int val)
+{
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDENABLE;
+#ifdef KDEBUG_ENABLE_PPT
+       if (ppt_flag && val) {
+               mib[3] = KDEBUG_ENABLE_PPT;
+       } else {
+               mib[3] = val;
+       }
+#else
+       mib[3] = val;
+#endif
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KERN_KDENABLE\n");
+}
+
+void set_remove()
+{
+       extern int errno;
+    
+       errno = 0;
+    
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDREMOVE;
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
+       {
+               if (errno == EBUSY)
+                       quit("the trace facility is currently in use...\n          fs_usage, sc_usage, trace, and latency use this feature.\n\n");
+               else
+                       quit("trace facility failure, KERN_KDREMOVE\n");
+       }
+}
+
+void set_numbufs(int nbufs)
+{
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDSETBUF;
+       mib[3] = nbufs;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KERN_KDSETBUF\n");
+    
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDSETUP;
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KERN_KDSETUP\n");
+}
+
+void set_nowrap()
+{
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDEFLAGS;
+        mib[3] = KDBG_NOWRAP;
+        mib[4] = 0;
+        mib[5] = 0;            /* no flags */
+        if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KDBG_NOWRAP\n");
+
+}
+
+void set_pidcheck(int pid, int on_off_flag)
+{
+       kd_regtype kr;
+    
+       kr.type = KDBG_TYPENONE;
+       kr.value1 = pid;
+       kr.value2 = on_off_flag;
+       needed = sizeof(kd_regtype);
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDPIDTR;
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+       {
+               if (on_off_flag == 1)
+               {
+                       printf("trace facility failure, KERN_KDPIDTR,\n\tpid %d does not exist\n", pid);
+                       set_remove();
+                       exit(2);
+               }
+       }
+}
+
+void set_pidexclude(int pid, int on_off_flag)
+{
+       kd_regtype kr;
+    
+       kr.type = KDBG_TYPENONE;
+       kr.value1 = pid;
+       kr.value2 = on_off_flag;
+       needed = sizeof(kd_regtype);
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDPIDEX;
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+       {
+               if (on_off_flag == 1)
+               {
+                       printf ("pid %d does not exist\n", pid);
+                       set_remove();
+                       exit(2);
+               }
+       }
+}
+
+void set_freerun()
+{
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDEFLAGS;
+        mib[3] = KDBG_FREERUN;
+        mib[4] = 0;
+        mib[5] = 0;
+        if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KDBG_FREERUN\n");
+}
+
+void get_bufinfo(kbufinfo_t *val)
+{
+       needed = sizeof (*val);
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDGETBUF;
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+       if (sysctl(mib, 3, val, &needed, 0, 0) < 0)
+               quit("trace facility failure, KERN_KDGETBUF\n");
+}
+
+void set_init()
+{
+        kd_regtype kr;
+    
+        kr.type = KDBG_RANGETYPE;
+        kr.value1 = 0;
+        kr.value2 = -1;
+        needed = sizeof(kd_regtype);
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDSETREG;
+        mib[3] = 0;
+        mib[4] = 0;
+       mib[5] = 0;
+        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+            quit("trace facility failure, KERN_KDSETREG (rangetype)\n");
+    
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDSETUP;
+        mib[3] = 0;
+        mib[4] = 0;
+        mib[5] = 0;
+        if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0)
+            quit("trace facility failure, KERN_KDSETUP\n");
+}
+
+
+void set_class()
+{
+        kd_regtype kr;
+    
+        kr.type = KDBG_CLASSTYPE;
+        kr.value1 = class;
+        kr.value2 = class2;
+        needed = sizeof(kd_regtype);
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDSETREG;
+        mib[3] = 0;
+        mib[4] = 0;
+        mib[5] = 0;
+        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+            quit("trace facility failure, KERN_KDSETREG (classtype)\n");
+}
+
+void set_kval_list()
+{
+        kd_regtype kr;
+    
+        kr.type = KDBG_VALCHECK;
+        kr.value1 = value1;
+        kr.value2 = value2;
+        kr.value3 = value3;
+        kr.value4 = value4;
+        needed = sizeof(kd_regtype);
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDSETREG;
+        mib[3] = 0;
+        mib[4] = 0;
+        mib[5] = 0;
+        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+            quit("trace facility failure, KERN_KDSETREG (valcheck)\n");
+}
+
+void set_subclass()
+{
+        kd_regtype kr;
+    
+        kr.type = KDBG_SUBCLSTYPE;
+        kr.value1 = class;
+        kr.value2 = subclass;
+        needed = sizeof(kd_regtype);
+        mib[0] = CTL_KERN;
+        mib[1] = KERN_KDEBUG;
+        mib[2] = KERN_KDSETREG;
+        mib[3] = 0;
+        mib[4] = 0;
+        mib[5] = 0;
+        if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0)
+            quit("trace facility failure, KERN_KDSETREG (subclstype)\n");
+}
+
+
+void readtrace(char *buffer)
+{
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDREADTR;         
+       mib[3] = 0;
+       mib[4] = 0;
+       mib[5] = 0;
+
+       if (sysctl(mib, 3, buffer, &needed, NULL, 0) < 0)
+               quit("trace facility failure, KERN_KDREADTR\n");
+}
+
+
+int writetrace(int fd)
+{
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDWRITETR;
+       mib[3] = fd;
+       mib[4] = 0;
+       mib[5] = 0;
+
+       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               return 1;
+
+       return 0;
+}
+
+
+int write_command_map(int fd)
+{
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_KDEBUG;
+       mib[2] = KERN_KDWRITEMAP;
+       mib[3] = fd;
+       mib[4] = 0;
+       mib[5] = 0;
+
+       if (sysctl(mib, 4, NULL, &needed, NULL, 0) < 0)
+               return 1;
+
+       return 0;
+}
+
+
+static
+lookup_t handle_lookup_event(uintptr_t thread, int debugid, kd_buf *kdp)
+{
+       lookup_t        lkp;
+       int             hashid;
+       boolean_t       first_record = FALSE;
+
+       hashid = thread & HASH_MASK;
+
+       if (debugid & DBG_FUNC_START)
+               first_record = TRUE;
+
+       for (lkp = lookup_hash[hashid]; lkp; lkp = lkp->lk_next) {
+               if (lkp->lk_thread == thread)
+                       break;
+       }
+       if (lkp == NULL) {
+               if (first_record == FALSE)
+                       return (0);
+
+               if ((lkp = lookup_freelist))
+                       lookup_freelist = lkp->lk_next;
+               else
+                       lkp = (lookup_t)malloc(sizeof(struct lookup));
+
+               lkp->lk_thread = thread;
+
+               lkp->lk_next = lookup_hash[hashid];
+               lookup_hash[hashid] = lkp;
+       }
+
+       if (first_record == TRUE) {
+               lkp->lk_pathptr = lkp->lk_pathname;
+               lkp->lk_dvp = kdp->arg1;
+       } else {
+                if (lkp->lk_pathptr > &lkp->lk_pathname[NUMPARMS-4])
+                       return (lkp);
+
+               *lkp->lk_pathptr++ = kdp->arg1;
+       }
+       *lkp->lk_pathptr++ = kdp->arg2;
+       *lkp->lk_pathptr++ = kdp->arg3;
+       *lkp->lk_pathptr++ = kdp->arg4;
+       *lkp->lk_pathptr = 0;
+
+       return (lkp);
+}
+
+
+static
+void delete_lookup_event(uintptr_t thread, lookup_t lkp_to_delete)
+{
+       lookup_t        lkp;
+       lookup_t        lkp_prev;
+       int             hashid;
+
+       hashid = thread & HASH_MASK;
+
+       if ((lkp = lookup_hash[hashid])) {
+               if (lkp == lkp_to_delete)
+                       lookup_hash[hashid] = lkp->lk_next;
+               else {
+                       lkp_prev = lkp;
+
+                       for (lkp = lkp->lk_next; lkp; lkp = lkp->lk_next) {
+                               if (lkp == lkp_to_delete) {
+                                       lkp_prev->lk_next = lkp->lk_next;
+                                       break;
+                               }
+                               lkp_prev = lkp;
+                       }
+               }
+               if (lkp) {
+                       lkp->lk_next = lookup_freelist;
+                       lookup_freelist = lkp;
+               }
+       }
+}
+
+
+static
+void insert_start_event(uintptr_t thread, int debugid, uint64_t now)
+{
+       event_t         evp;
+       int             hashid;
+
+       hashid = thread & HASH_MASK;
+
+       for (evp = event_hash[hashid]; evp; evp = evp->ev_next) {
+               if (evp->ev_thread == thread && evp->ev_debugid == debugid)
+                       break;
+       }
+       if (evp == NULL) {
+               if ((evp = event_freelist))
+                       event_freelist = evp->ev_next;
+               else
+                       evp = (event_t)malloc(sizeof(struct event));
+
+               evp->ev_thread = thread;
+               evp->ev_debugid = debugid;
+
+               evp->ev_next = event_hash[hashid];
+               event_hash[hashid] = evp;
+       }
+       evp->ev_timestamp = now;
+}
+
+
+static
+uint64_t consume_start_event(uintptr_t thread, int debugid, uint64_t now)
+{
+       event_t         evp;
+       event_t         evp_prev;
+       int             hashid;
+       uint64_t        elapsed = 0;
+
+       hashid = thread & HASH_MASK;
+
+       if ((evp = event_hash[hashid])) {
+               if (evp->ev_thread == thread && evp->ev_debugid == debugid)
+                       event_hash[hashid] = evp->ev_next;
+               else {
+                       evp_prev = evp;
+
+                       for (evp = evp->ev_next; evp; evp = evp->ev_next) {
+                               
+                               if (evp->ev_thread == thread && evp->ev_debugid == debugid) {
+                                       evp_prev->ev_next = evp->ev_next;
+                                       break;
+                               }
+                               evp_prev = evp;
+                       }
+               }
+               if (evp) {
+                       elapsed = now - evp->ev_timestamp;
+                       
+                       evp->ev_next = event_freelist;
+                       event_freelist = evp;
+               }
+       }
+       return (elapsed);
+}
+
+
+log_trace()
+{
+        char           *buffer;
+       uint32_t        buffer_size;
+       int             fd;
+       int             size;
+       int             pad_size;
+       char            pad_buf[4096];
+
+
+       if ((fd = open(logfile, O_TRUNC|O_WRONLY|O_CREAT, 0777)) == -1) {
+               perror("Can't open logfile");
+               exit(1);
+       }
+       get_bufinfo(&bufinfo);
+
+       if (bufinfo.nolog != 1) {
+               reenable = 1;
+               set_enable(0);  /* disable logging*/
+       }
+       get_bufinfo(&bufinfo);
+
+       if (verbose_flag) {
+               if (bufinfo.flags & KDBG_WRAPPED)
+                       printf("Buffer has wrapped\n");
+               else
+                       printf("Buffer has not wrapped\n");
+       }
+       buffer_size = 1000000 * sizeof(kd_buf);
+       buffer = malloc(buffer_size);
+
+       if (buffer == (char *) 0)
+               quit("can't allocate memory for tracing info\n");
+
+       read_command_map(0, 0);
+
+       raw_header.version_no = RAW_VERSION1;
+       raw_header.thread_count = total_threads;
+       raw_header.TOD_secs = time((long *)0);
+       raw_header.TOD_usecs = 0;
+
+       write(fd, &raw_header, sizeof(RAW_header));
+
+       size = total_threads * sizeof(kd_threadmap);
+       write(fd, (char *)mapptr, size);
+
+       pad_size = 4096 - ((sizeof(RAW_header) + size) & 4095);
+       memset(pad_buf, 0, pad_size);
+                       
+       write(fd, pad_buf, pad_size);
+
+       for (;;) {
+               needed = buffer_size;
+
+               readtrace(buffer);
+
+               if (needed == 0)
+                       break;
+               write(fd, buffer, needed * sizeof(kd_buf));
+       }
+       close(fd);
+}
+
+
+
+Log_trace()
+{
+       int     size;
+       int     n;
+       kd_buf  kd_tmp;
+       size_t  len;
+       int     num_cpus;
+       int     try_writetrace = 1;
+       int     fd;
+        char           *buffer;
+        kd_buf         *kd;
+       uint64_t sample_window_abs;
+       uint64_t next_window_begins;
+       uint64_t current_abs;
+       uint64_t ending_abstime;
+       uint64_t last_time_written;
+       uint32_t us_to_sleep;
+       uint32_t us_to_adjust;
+       uint32_t ms_to_run;
+
+       memset(&kd_tmp, 0, sizeof(kd_tmp));
+
+       if ((fd = open(logfile, O_TRUNC|O_WRONLY|O_CREAT, 0777)) == -1) {
+               perror("Can't open logfile");
+               exit(1);
+       }
+       /*
+        * grab the number of cpus and scale the buffer size
+        */
+       mib[0] = CTL_HW;
+       mib[1] = HW_NCPU;
+       mib[2] = 0;
+       len = sizeof(num_cpus);
+
+       sysctl(mib, 2, &num_cpus, &len, NULL, 0);
+
+       if (!bufset_flag)
+               nbufs = BASE_EVENTS * num_cpus;
+
+       set_remove();
+       set_numbufs(nbufs);
+       set_init();
+
+       /* Get kernel buffer information */
+       get_bufinfo(&bufinfo);
+
+       buffer = malloc(bufinfo.nkdbufs * sizeof(kd_buf));
+       if (buffer == (char *) 0)
+               quit("can't allocate memory for tracing info\n");
+       memset(buffer, 0, bufinfo.nkdbufs * sizeof(kd_buf));
+
+       set_enable(1);
+
+       if (write_command_map(fd)) {
+               int  pad_size;
+               char pad_buf[4096];
+
+               read_command_map(0, 0);
+
+               raw_header.version_no = RAW_VERSION1;
+               raw_header.thread_count = total_threads;
+               raw_header.TOD_secs = time((long *)0);
+               raw_header.TOD_usecs = 0;
+
+               write(fd, &raw_header, sizeof(RAW_header));
+
+               size = total_threads * sizeof(kd_threadmap);
+               write(fd, (char *)mapptr, size);
+
+               pad_size = 4096 - ((sizeof(RAW_header) + size) & 4095);
+               memset(pad_buf, 0, pad_size);
+                       
+               write(fd, pad_buf, pad_size);
+       }
+       sample_window_abs = (uint64_t)((double)US_TO_SLEEP * divisor);
+
+       next_window_begins = mach_absolute_time() + sample_window_abs;
+
+       if (secs_to_run) {
+               ending_abstime = mach_absolute_time() + (uint64_t)((double)secs_to_run * (double)1000000 * divisor);
+               ms_to_run = secs_to_run * 1000;
+       } else
+               ms_to_run = 0;
+       last_time_written = mach_absolute_time();
+
+       while (LogRAW_flag) {
+               current_abs = mach_absolute_time();
+
+               if (try_writetrace) {
+                       needed = ms_to_run;
+                               
+                       if (writetrace(fd))
+                               try_writetrace = 0;
+                       else {
+                               if (needed) {
+                                       current_abs = mach_absolute_time();
+
+                                       printf("wrote %d events - elapsed time = %.1f secs\n",
+                                              (int)needed, ((double)(current_abs - last_time_written) / divisor) / 1000000);
+
+                                       last_time_written = current_abs;
+                               }
+                       }
+               }
+               if (try_writetrace == 0) {
+
+                       if (next_window_begins > current_abs)
+                               us_to_adjust = US_TO_SLEEP - (uint32_t)((double)(next_window_begins - current_abs) / divisor);
+                       else
+                               us_to_adjust = US_TO_SLEEP;
+                       
+                       next_window_begins = current_abs + sample_window_abs;
+
+                       us_to_sleep = US_TO_SLEEP - us_to_adjust;
+
+                       next_window_begins = current_abs + (uint64_t)((double)(us_to_sleep + US_TO_SLEEP) * divisor);
+
+                       if (us_to_sleep)
+                               usleep(us_to_sleep);
+
+                       get_bufinfo(&bufinfo);
+
+                       if (bufinfo.flags & KDBG_WRAPPED)
+                               printf("lost events\n");
+
+                       needed = bufinfo.nkdbufs * sizeof(kd_buf);
+
+                       readtrace(buffer);
+
+                       if (bufinfo.flags & KDBG_WRAPPED) {
+
+                               kd = (kd_buf *) buffer;
+
+                               kd_tmp.timestamp = kd[0].timestamp;
+                               kd_tmp.debugid = TRACE_LOST_EVENTS;
+
+                               write(fd, &kd_tmp, sizeof(kd_tmp));
+                       }
+                       write(fd, buffer, needed * sizeof(kd_buf));
+
+                       if (verbose_flag && needed > nbufs)
+                               printf("needed = %ld\n", needed);
+               }
+               if (secs_to_run) {
+                       current_abs = mach_absolute_time();
+
+                       if (current_abs > ending_abstime)
+                               break;
+                       ms_to_run = (ending_abstime - current_abs) / (1000 * 1000);
+                       
+                       if (ms_to_run == 0)
+                               break;
+               }
+       }
+       set_enable(0);
+       set_numbufs(0);
+       set_remove();
+
+       close(fd);
+}
+
+
+void read_trace()
+{
+        char           *buffer;
+       uint32_t        buffer_size;
+        kd_buf         *kd;
+       int             fd;
+       int             firsttime = 1;
+       int             lines = 0;
+       int             io_lines = 0;
+       uint64_t        bias = 0;
+       uint32_t        count_of_names;
+       double          last_event_time = 0.0;
+       time_t          trace_time;
+
+       if (!readRAW_flag) {
+               get_bufinfo(&bufinfo);
+
+               if (bufinfo.nolog != 1) {
+                       reenable = 1;
+                       set_enable(0);  /* disable logging*/
+               }
+               if (verbose_flag) {
+                       if (bufinfo.flags & KDBG_WRAPPED)
+                               printf("Buffer has wrapped\n");
+                       else
+                               printf("Buffer has not wrapped\n");
+               }
+               fd = 0;
+               count_of_names = 0;
+
+       } else {
+               struct  stat statb;
+
+               fd = open(RAW_file, O_RDONLY);
+
+               if (fd < 0) {
+                       perror("Can't open file");
+                       exit(1);
+               }
+               if (read(fd, &raw_header, sizeof(RAW_header)) != sizeof(RAW_header)) {
+                       perror("read failed");
+                       exit(2);
+               }
+               if (raw_header.version_no != RAW_VERSION1) {
+                       raw_header.version_no = RAW_VERSION0;
+                       raw_header.TOD_secs = time((long *)0);
+                       raw_header.TOD_usecs = 0;
+
+                       lseek(fd, (off_t)0, SEEK_SET);
+
+                       if (read(fd, &raw_header.thread_count, sizeof(int)) != sizeof(int)) {
+                               perror("read failed");
+                               exit(2);
+                       }
+               }
+               count_of_names = raw_header.thread_count;
+               trace_time = raw_header.TOD_secs;
+
+               printf("%s\n", ctime(&trace_time));
+       }
+       buffer_size = 1000000 * sizeof(kd_buf);
+       buffer = malloc(buffer_size);
+
+       if (buffer == (char *) 0)
+               quit("can't allocate memory for tracing info\n");
+
+       kd = (kd_buf *)buffer;
+
+       read_command_map(fd, count_of_names);
+
+       for (;;) {
+               uint32_t count;
+               uint64_t now = 0;
+               uint64_t prev;
+               uint64_t prevdelta;
+               uint32_t cpunum;
+               uintptr_t thread;
+               double  x = 0.0;
+               double  z = 0.0;
+               double  y = 0.0;
+               double  event_elapsed_time;
+               kd_buf *kdp;
+               lookup_t  lkp;
+               boolean_t ending_event;
+               int     i;
+               int     debugid;
+               int     debugid_base;
+               int     dmsgindex;
+               char    dbgmessge[80];
+               char    outbuf[32];
+               char    *command;
+
+               if (!readRAW_flag) {
+                       needed = buffer_size;
+
+                       mib[0] = CTL_KERN;
+                       mib[1] = KERN_KDEBUG;
+                       mib[2] = KERN_KDREADTR;         
+                       mib[3] = 0;
+                       mib[4] = 0;
+                       mib[5] = 0;
+                       if (sysctl(mib, 3, buffer, &needed, NULL, 0) < 0)
+                               quit("trace facility failure, KERN_KDREADTR\n");
+
+                       if (needed == 0)
+                               break;
+                       count = needed;
+
+               } else {
+                       uint32_t bytes_read;
+
+                       bytes_read = read(fd, buffer, buffer_size);
+
+                       if (bytes_read == -1) {
+                               perror("read failed");
+                               exit(2);
+                       }
+                       count = bytes_read / sizeof(kd_buf);
+
+                       if (count == 0)
+                               break;
+               }
+               for (kdp = &kd[0], i = 0; i < count; i++, kdp++) {
+
+                       prev = now;
+                       debugid = kdp->debugid;
+                       debugid_base = debugid & DBG_FUNC_MASK;
+                       now = kdp->timestamp & KDBG_TIMESTAMP_MASK;
+
+                       if (firsttime)
+                               bias = now;
+                       now -= bias;
+
+                       cpunum = kdbg_get_cpu(kdp); 
+                       thread = kdp->arg5;
+
+                       if (lines == 64 || firsttime)
+                       {
+                               prevdelta = now - prevdelta;
+
+                               if (firsttime)
+                                       firsttime = 0;
+                               else {
+                                       x = (double)prevdelta;
+                                       x /= divisor;
+
+                                       fprintf(output_file, "\n\nNumber of microsecs since in last page %8.1f\n", x);
+                               }
+                               prevdelta = now;
+           
+                               /* 
+                                * Output description row to output file (make sure to format correctly for 32-bit and 64-bit)
+                                */
+                               fprintf(output_file,
+#ifdef __LP64__
+                                       "   AbsTime(Us)      Delta            debugid                       arg1             arg2             arg3             arg4              thread         cpu#  command\n\n"
+#else
+                                       "   AbsTime(Us)      Delta            debugid                       arg1           arg2           arg3           arg4                thread   cpu#  command\n\n"
+#endif
+                                       );
+           
+                               lines = 0;
+                               
+                               if (io_lines > 15000) {
+                                       fcntl(output_fd, F_FLUSH_DATA, 0);
+
+                                       io_lines = 0;
+                               }
+                       }
+                       lkp = 0;
+
+                       if (debugid_base == VFS_LOOKUP) {
+                               lkp = handle_lookup_event(thread, debugid, kdp);
+
+                               if ( !lkp || !(debugid & DBG_FUNC_END))
+                                       continue;
+                       }
+                       x = (double)now;
+                       x /= divisor;
+
+                       if (last_event_time)
+                               y = x - last_event_time;
+                       else
+                               y = x;
+                       last_event_time = x;
+                       ending_event = FALSE;
+
+                       find_thread_command(kdp, &command);
+
+                       /*
+                        * The internal use TRACE points clutter the output.
+                        * Print them only if in verbose mode.
+                        */
+                       if (!verbose_flag)
+                       {
+                               /* Is this entry of Class DBG_TRACE */
+                               if ((debugid >> 24) == DBG_TRACE) {
+                                       if (((debugid >> 16) & 0xff) != DBG_TRACE_INFO)
+                                               continue;
+                               }
+                       }
+                       if ( !lkp) {
+                               int t_debugid;
+                               int t_thread;
+
+                               if ((debugid & DBG_FUNC_START) || debugid == MACH_MAKERUNNABLE) {
+
+                                       if (debugid_base != BSC_thread_terminate && debugid_base != BSC_exit) {
+
+                                               if (debugid == MACH_MAKERUNNABLE)
+                                                       t_thread = kdp->arg1;
+                                               else
+                                                       t_thread = thread;
+
+                                               insert_start_event(t_thread, debugid_base, now);
+                                       }
+
+                               } else if ((debugid & DBG_FUNC_END) || debugid == MACH_STKHANDOFF || debugid == MACH_SCHEDULED) {
+                                       
+                                       if (debugid == MACH_STKHANDOFF || debugid == MACH_SCHEDULED) {
+                                               t_debugid = MACH_MAKERUNNABLE;
+                                               t_thread = kdp->arg2;
+                                       } else {
+                                               t_debugid = debugid_base;
+                                               t_thread = thread;
+                                       }
+                                       event_elapsed_time = (double)consume_start_event(t_thread, t_debugid, now);
+                                       event_elapsed_time /= divisor;
+                                       ending_event = TRUE;
+
+                                       if (event_elapsed_time == 0 && (debugid == MACH_STKHANDOFF || debugid == MACH_SCHEDULED))
+                                               ending_event = FALSE;
+                               }
+                       }
+                       if (ending_event) {
+                               char *ch;
+
+                               sprintf(&outbuf[0], "(%-10.1f)", event_elapsed_time);
+                               /*
+                                * fix that right paren
+                                */
+                               ch = &outbuf[11];
+
+                               if (*ch != ')') {
+                                       ch = strchr (&outbuf[0], ')');
+                               }
+                               if (ch)
+                               {
+                                       *ch = ' ';
+                                       --ch;
+
+                                       while (ch != &outbuf[0])
+                                       {
+                                               if (*ch == ' ')
+                                                       --ch;
+                                               else
+                                               {
+                                                       *(++ch) = ')';
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       if (match_debugid(debugid_base, dbgmessge, &dmsgindex)) {
+                               if (ending_event)
+                                       fprintf(output_file, "%13.1f %10.1f%s %-28x  ", x, y, outbuf, debugid_base);
+                               else
+                                       fprintf(output_file, "%13.1f %10.1f             %-28x  ", x, y, debugid_base);
+                       } else {
+                               if (ending_event)
+                                       fprintf(output_file, "%13.1f %10.1f%s %-28.28s  ", x, y, outbuf, dbgmessge);
+                               else
+                                       fprintf(output_file, "%13.1f %10.1f             %-28.28s  ", x, y, dbgmessge);
+                       }
+                       if (lkp) {
+                               char *strptr;
+                               int     len;
+
+                               strptr = (char *)lkp->lk_pathname;
+
+                               /*
+                                * print the tail end of the pathname
+                                */
+                               len = strlen(strptr);
+                               if (len > 51)
+                                       len -= 51;
+                               else
+                                       len = 0;
+#ifdef __LP64__
+
+                               fprintf(output_file, "%-16lx %-51s %-16lx  %-2d %s\n", lkp->lk_dvp, &strptr[len], thread, cpunum, command);
+#else
+                               fprintf(output_file, "%-8x   %-51s   %-8lx   %-2d  %s\n", (unsigned int)lkp->lk_dvp, &strptr[len], thread, cpunum, command);
+#endif
+                               delete_lookup_event(thread, lkp);
+                       } else {
+#ifdef __LP64__
+                               fprintf(output_file, "%-16lx %-16lx %-16lx %-16lx  %-16lx  %-2d %s\n", kdp->arg1, kdp->arg2, kdp->arg3, kdp->arg4, thread, cpunum, command);
+#else
+                               fprintf(output_file, "%-8lx       %-8lx       %-8lx       %-8lx            %-8lx   %-2d  %s\n", kdp->arg1, kdp->arg2, kdp->arg3, kdp->arg4, thread, cpunum, command);
+#endif
+                       }
+                       lines++;
+                       io_lines++;
+               }
+       }
+       if (reenable == 1)
+               set_enable(1);  /* re-enable kernel logging */
+}
+
+
+
+void signal_handler(int sig) 
+{
+       ptrace(PT_KILL, pid, (caddr_t)0, 0);
+       /*
+        * child is gone; no need to disable the pid
+        */
+       exit(2);
+}
+
+
+void signal_handler_RAW(int sig)
+{
+       LogRAW_flag = 0;
+}
+
+
+
+int main(argc, argv, env)
+int argc;
+char **argv;
+char **env;
+{
+       extern char *optarg;
+       extern int optind;
+       int status;
+       int ch;
+       char *output_filename = NULL;
+
+       if (0 != reexec_to_match_kernel()) {
+               fprintf(stderr, "Could not re-execute: %d\n", errno);
+               exit(1);
+       }
+        if (setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_PASSIVE) < 0) {
+                printf("setiopolicy failed\n");
+                exit(1);
+        }
+       output_file = stdout;
+       output_fd = 1;
+
+       getdivisor();
+
+       while ((ch = getopt(argc, argv, "hedEk:irb:gc:p:s:tR:L:l:S:a:x:nfvo:P")) != EOF)
+       {
+               switch(ch)
+               {
+               case 'h': /* help */
+                       usage(LONG_HELP);
+                       break;
+               case 'S':
+                       secs_to_run = argtoi('S', "decimal number", optarg, 10);
+                       break;
+               case 'a': /* set tracing on a pid */
+                       pid_flag=1;
+                       pid = argtoi('a', "decimal number", optarg, 10);
+                       break;
+               case 'x': /* exclude a pid from tracing */
+                       pid_exflag=1;
+                       pid = argtoi('x', "decimal number", optarg, 10);
+                       break;
+               case 'v':
+                       verbose_flag=1;
+                       break;
+               case 'l':
+                       logRAW_flag = 1;
+                       logfile = optarg;
+                       break;
+               case 'L':
+                       LogRAW_flag = 1;
+                       logfile = optarg;
+                       signal(SIGINT, signal_handler_RAW);
+                       break;
+               case 'e':
+                       enable_flag = 1;
+                       break;
+               case 'i':
+                       init_flag = 1;
+                       break;
+               case 'E':
+                       execute_flag = 1;
+                       break;
+               case 'd':
+                       disable_flag = 1;
+                       break;
+               case 'k':
+                       if (kval_flag == 0)
+                               value1 = argtoul('k', "hex number", optarg, 16);
+                       else if (kval_flag == 1)
+                               value2 = argtoul('k', "hex number", optarg, 16);
+                       else if (kval_flag == 2)
+                               value3 = argtoul('k', "hex number", optarg, 16);
+                       else if (kval_flag == 3)
+                               value4 = argtoul('k', "hex number", optarg, 16);
+                       else
+                       {
+                               fprintf(stderr, "A maximum of four values can be specified with -k\n");
+                               usage(SHORT_HELP);
+                       }
+                       kval_flag++;
+                       break;
+               case 'r':
+                       remove_flag = 1;
+                       break;
+               case 'g':
+                       bufget_flag = 1;
+                       break;
+               case 't':
+                       trace_flag = 1;
+                       break;
+               case 'R':
+                       readRAW_flag = 1;
+                       RAW_file = optarg;
+                       break;
+               case 'n':
+                       nowrap_flag = 1;
+                       break;
+               case 'f':
+                       freerun_flag = 1;
+                       break;
+               case 'b':
+                       bufset_flag = 1;
+                       nbufs = argtoi('b', "decimal number", optarg, 10);
+                       break;
+               case 'c':
+                       class_flag = 1;
+                       class = argtoi('c', "decimal number", optarg, 10);
+                       class2 = class+1;
+                       break;
+               case 's':
+                       subclass_flag = 1;
+                       subclass = argtoi('s', "decimal number", optarg, 10);
+                       break;
+               case 'p':
+                       if (class_flag != 1)
+                       {       fprintf(stderr, "-p must follow -c\n");
+                               exit(1);
+                       }
+                       class2 = argtoi('p', "decimal number", optarg, 10);
+                       break;
+               case 'P':
+                       ppt_flag = 1;
+                       break;
+               case 'o':
+                       output_filename = optarg;
+                       break;
+               default:
+                       usage(SHORT_HELP);
+               }
+       }
+       argc -= optind;
+
+       if (argc)
+       {
+               if (!execute_flag)
+               {
+                       cfile = argv[optind];
+                       if (verbose_flag)
+                               printf("Code file is %s \n", cfile);
+                       if (parse_codefile(cfile) == -1)
+                               cfile = (char *)0;
+               }
+       }
+       else
+       {
+               if (execute_flag)
+               {
+                       printf("-E flag needs an executable to launch\n");
+                       exit(1);
+               }
+       }
+
+       if (pid_flag && pid_exflag)
+       {
+               fprintf(stderr, "Can't use both -a and -x flag together\n");
+               exit(1);
+       }
+
+       if (subclass_flag && !class_flag) {
+               fprintf(stderr,"Must define a class ('c') with the subclass ('s') option\n");
+               usage(SHORT_HELP);
+       }
+
+       if (kval_flag && (subclass_flag || class_flag))
+       {
+               fprintf(stderr,"Don't use class or subclass with the 'k' code options.\n");
+               usage(SHORT_HELP);
+       }
+
+       if (output_filename && !trace_flag && !readRAW_flag)
+       {
+               fprintf(stderr, "When using 'o' option, must use the 't' or 'R' option too\n");
+               usage(SHORT_HELP);
+       }
+
+       if (disable_flag)
+       {
+               if (pid_flag)
+               {
+                       set_pidcheck(pid, 0);   /* disable pid check for given pid */
+                       exit(1);
+               }
+               else if (pid_exflag)
+               {
+                       set_pidexclude(pid, 0);  /* disable pid exclusion for given pid */
+                       exit(1);
+               }
+               set_enable(0);
+               exit(1);
+       }
+
+       if (remove_flag)
+       {
+               set_remove();
+               exit(1);
+       }
+    
+       if (bufset_flag )
+       {
+               if (!init_flag && !LogRAW_flag)
+               {
+                       fprintf(stderr,"The -b flag must be used with the -i flag\n");
+                       exit(1);
+               }
+               set_numbufs(nbufs);
+       }
+    
+       if (nowrap_flag)
+               set_nowrap();
+
+       if (freerun_flag)
+               set_freerun();
+       if (bufget_flag)
+       {
+               get_bufinfo(&bufinfo);
+
+               printf("The kernel buffer settings are:\n");
+
+               if (bufinfo.flags & KDBG_BUFINIT)
+                       printf("\tKernel buffer is initialized\n");
+               else
+                       printf("\tKernel buffer is not initialized\n");
+
+               printf("\t  number of buf entries  = %d\n", bufinfo.nkdbufs);
+
+               if (verbose_flag)
+               {
+                       if (bufinfo.flags & KDBG_MAPINIT)
+                               printf("\tKernel thread map is initialized\n");
+                       else
+                               printf("\tKernel thread map is not initialized\n");
+                       printf("\t  number of thread entries  = %d\n", bufinfo.nkdthreads);
+               }
+
+               if (bufinfo.nolog)
+                       printf("\tBuffer logging is disabled\n");
+               else
+                       printf("\tBuffer logging is enabled\n");
+
+               if (verbose_flag)
+                       printf("\tkernel flags = 0x%x\n", bufinfo.flags);
+
+               if (bufinfo.flags & KDBG_NOWRAP)
+                       printf("\tKernel buffer wrap is disabled\n");
+               else
+                       printf("\tKernel buffer wrap is enabled\n");
+
+               if (bufinfo.flags & KDBG_RANGECHECK)
+                       printf("\tCollection within a range is enabled\n");
+               else
+                       printf("\tCollection within a range is disabled\n");
+
+               if (bufinfo.flags & KDBG_VALCHECK)
+                       printf("\tCollecting specific code values is enabled\n");
+               else    
+                       printf("\tCollecting specific code values is disabled\n");
+               
+               if (bufinfo.flags & KDBG_PIDCHECK)
+                       printf("\tCollection based on pid is enabled\n");
+               else
+                       printf("\tCollection based on pid is disabled\n");
+
+               if (bufinfo.flags & KDBG_PIDEXCLUDE)
+                       printf("\tCollection based on pid exclusion is enabled\n");
+               else
+                       printf("\tCollection based on pid exclusion is disabled\n");
+
+               if (bufinfo.bufid == -1)
+                       printf("\tKernel buffer is not controlled by any process.\n");
+               else
+                       printf("\tKernel buffer is controlled by proc id [%d]\n", bufinfo.bufid);
+       }
+
+       if (init_flag)
+               set_init();
+
+       if (class_flag)
+               set_class();
+
+       if (subclass_flag)
+               set_subclass();
+
+       if (kval_flag)
+               set_kval_list();
+
+       if (execute_flag)
+       {
+               fprintf(stderr, "Starting program: %s\n", argv[optind]);
+               fflush(stdout);
+               fflush(stderr);
+
+               switch ((pid = vfork()))
+               {
+               case -1:
+                       perror("vfork: ");
+                       exit(1);
+               case 0: /* child */
+                       setsid();
+                       ptrace(PT_TRACE_ME, 0, (caddr_t)0, 0);
+                       execve(argv[optind], &argv[optind], environ);
+                       perror("execve:");
+                       exit(1);
+               }
+               sleep(1);
+
+               signal(SIGINT, signal_handler);
+               set_pidcheck(pid, 1);
+               set_enable(1);
+               ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
+               waitpid(pid, &status, 0);
+               /* child is gone; no need to disable the pid */
+               exit(0);
+       }
+       else if (enable_flag)
+       {
+               if (pid_flag)
+                       set_pidcheck(pid, 1);
+               else if (pid_exflag)
+                       set_pidexclude(pid, 1);
+               set_enable(1);
+       }
+
+       if (output_filename)
+       {
+               if (((output_fd = open(output_filename, O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0644)) < 0 ) ||
+                   !(output_file = fdopen(output_fd, "w")))
+               {
+                       fprintf(stderr, "Cannot open file \"%s\" for writing.\n", output_filename);
+                       usage(SHORT_HELP);
+               }
+               setbuffer(output_file, &sbuffer[0], SBUFFER_SIZE);
+       
+               if (fcntl(output_fd, F_NOCACHE, 1) < 0)
+               {
+                       /* Not fatal */
+                       fprintf(stderr, "Warning: setting F_NOCACHE on %s, failed\n", output_filename);
+               }
+       }
+       if (!LogRAW_flag && !logRAW_flag)
+               setbuffer(output_file, &sbuffer[0], SBUFFER_SIZE);
+
+       if (trace_flag || readRAW_flag)
+               read_trace();
+       else if (LogRAW_flag)
+               Log_trace();
+       else if (logRAW_flag)
+               log_trace();
+
+       exit(0);
+
+} /* end main */
+
+
+void
+quit(char *s)
+{
+       if (reenable == 1)
+       {
+               reenable = 0;
+               set_enable(1);  /* re-enable kernel logging */
+       }
+
+       printf("trace: ");
+       if (s)
+               printf("%s ", s);
+       exit(1);
+}
+
+static void
+usage(int short_help)
+{
+
+       if (short_help)
+       {
+               (void)fprintf(stderr, "  usage: trace -h\n");
+               (void)fprintf(stderr, "  usage: trace -i [-b numbufs]\n");
+               (void)fprintf(stderr, "  usage: trace -g\n");
+               (void)fprintf(stderr, "  usage: trace -d [-a pid | -x pid ]\n");
+               (void)fprintf(stderr, "  usage: trace -r\n");
+               (void)fprintf(stderr, "  usage: trace -n\n");
+               (void)fprintf(stderr,
+                             "  usage: trace -e [ -c class [-p class] [-s subclass] ] [-a pid | -x pid] |\n");
+               (void)fprintf(stderr,
+                             "                  [-k code | -k code | -k code | -k code] [-P] \n\n");
+
+               (void)fprintf(stderr,
+                             "  usage: trace -E [ -c class [-p class] [-s subclass] ] |\n");
+               (void)fprintf(stderr,
+                             "                  [-k code | -k code | -k code | -k code] [-P]\n");
+               (void)fprintf(stderr,
+                             "                  executable_path [optional args to executable] \n\n");
+
+               (void)fprintf(stderr,
+                             "  usage: trace -t [-R rawfile] [-o OutputFilename] [CodeFilename]\n");
+               exit(1);
+       }
+
+
+       /* Only get here of printing long usage list */
+       (void)fprintf(stderr, "usage: trace -h\n");
+       (void)fprintf(stderr, "\tPrint this long command help.\n\n");
+
+       (void)fprintf(stderr, "usage: trace -i [-b numbufs]\n");
+       (void)fprintf(stderr, "\tInitialize the kernel trace buffer.\n\n");
+       (void)fprintf(stderr, "\t-b numbufs    The number of trace elements the kernel buffer\n");
+       (void)fprintf(stderr, "\t              can hold is set to numbufs.  Use with the -i flag.\n");
+       (void)fprintf(stderr, "\t              Enter a decimal value.\n\n");
+
+       (void)fprintf(stderr, "usage: trace -g\n");
+       (void)fprintf(stderr, "\tGet the kernel buffer settings.\n\n");
+
+       (void)fprintf(stderr, "usage: trace -d [-a pid | -x pid]\n");
+       (void)fprintf(stderr, "\tDisable/stop collection of kernel trace elements.\n\n");
+       (void)fprintf(stderr, "\t -a pid     Disable/stop collection for this process only.\n\n");
+       (void)fprintf(stderr, "\t -x pid     Disable/stop exclusion of this process only.\n\n");
+
+       (void)fprintf(stderr, "usage: trace -r\n");
+       (void)fprintf(stderr, "\tRemove the kernel trace buffer. Set controls to default.\n\n");
+
+       (void)fprintf(stderr, "usage: trace -n\n");
+       (void)fprintf(stderr, "\tDisables kernel buffer wrap around.\n\n");
+
+       (void)fprintf(stderr,
+                     "usage: trace -e [ -c class [-p class] [-s subclass] ] [-a pid | -x pid] |\n");
+       (void)fprintf(stderr,
+                     "             [-k code | -k code | -k code | -k code] \n\n");
+       (void)fprintf(stderr, "\tEnable/start collection of kernel trace elements.\n");
+       (void)fprintf(stderr, "\tEnter values in decimal notation unless otherwise noted..\n\n");
+       (void)fprintf(stderr, "\t -c class    Restrict trace collection to given class.\n\n");
+       (void)fprintf(stderr, "\t -p class    Restrict trace collection to given class range.\n");
+       (void)fprintf(stderr, "\t             Must provide class with -c first.\n\n");
+       (void)fprintf(stderr, "\t -s subclass    Restrict trace collection to given subclass.\n");
+       (void)fprintf(stderr, "\t                Must provide class with -c.\n\n");
+       (void)fprintf(stderr, "\t -a pid     Restrict trace collection to the given process.\n\n");
+       (void)fprintf(stderr, "\t -x pid     Exclude the given process from trace collection.\n\n");
+       (void)fprintf(stderr, "\t -k code    Restrict trace collection up to four specific codes.\n");
+       (void)fprintf(stderr, "\t            Enter codes in hex values.\n\n");
+       (void)fprintf(stderr, "\t -P         Enable restricted PPT trace points only.\n\n");
+
+       (void)fprintf(stderr,
+                     "usage: trace -E [ -c class [-p class] [-s subclass] ] |\n");
+       (void)fprintf(stderr,
+                     "             [-k code | -k code | -k code | -k code] \n");
+       (void)fprintf(stderr,
+                     "             executable_path [optional args to executable] \n\n");
+       (void)fprintf(stderr, "\tLaunch the given executable and enable/start\n");
+       (void)fprintf(stderr, "\tcollection of kernel trace elements for that process.\n");
+       (void)fprintf(stderr, "\tSee -e(enable) flag for option descriptions.\n\n");
+
+       (void)fprintf(stderr,
+                     "usage: trace -t [-R rawfile] [-o OutputFilename] [CodeFilename] \n");
+       (void)fprintf(stderr, "\t Collect the kernel buffer trace data and print it.\n\n");
+       (void)fprintf(stderr, "\t -R rawfile         Read raw trace file and print trace output to stdout.\n");
+       (void)fprintf(stderr, "\t -o OutputFilename  Print trace output to OutputFilename. Default is stdout.\n\n");
+
+       (void)fprintf(stderr,
+                     "usage: trace -L rawfile\n");
+       (void)fprintf(stderr, "\t Continuously collect the kernel buffer trace data in the raw format.\n\n");
+
+       (void)fprintf(stderr,
+                     "usage: trace -l rawfile\n");
+       (void)fprintf(stderr, "\t Collect the existing kernel buffer trace data in the raw format.\n\n");
+
+       exit(1);
+}
+
+
+static int
+argtoi(flag, req, str, base)
+int flag;
+char *req, *str;
+int base;
+{
+       char *cp;
+       int ret;
+
+       ret = (int)strtol(str, &cp, base);
+       if (cp == str || *cp)
+               errx(EINVAL, "-%c flag requires a %s", flag, req);
+       return (ret);
+}
+
+
+static unsigned long
+argtoul(flag, req, str, base)
+int flag;
+char *req, *str;
+int base;
+{
+       char *cp;
+       unsigned long ret;
+
+       ret = (int)strtoul(str, &cp, base);
+       if (cp == str || *cp)
+               errx(EINVAL, "-%c flag requires a %s", flag, req);
+       return (ret);
+}
+
+
+/*
+ * comparison function for qsort
+ * sort by debugid
+ */
+int debugid_compar(p1, p2)
+       code_type_t *p1;
+       code_type_t *p2;
+{
+       if (p1->debugid > p2->debugid)
+               return(1);
+       else if (p1->debugid == p2->debugid)
+               return(0);
+       else
+               return(-1);
+}
+
+
+/*
+ *  Find the debugid code in the list and return its index
+ */
+static int binary_search(list, lowbound, highbound, code)
+       code_type_t *list;
+       int lowbound, highbound;
+       unsigned int code;
+{
+       int low, high, mid;
+       int tries = 0;
+
+       low = lowbound;
+       high = highbound;
+
+       while (1)
+       {
+               mid = (low + high) / 2;
+
+               tries++;
+
+               if (low > high)
+                       return (-1); /* failed */
+               else if ( low + 1 >= high)
+               {
+                       /* We have a match */
+                       if (list[high].debugid == code)
+                               return(high);
+                       else if (list[low].debugid == code)
+                               return(low);
+                       else
+                               return(-1);  /* search failed */
+               }
+               else if (code < list[mid].debugid)
+                       high = mid;
+               else
+                       low = mid;
+       } 
+}
+
+
+static int
+parse_codefile(char *filename)
+{
+       int fd;
+       int i, j, count, line;
+       struct stat stat_buf;
+       unsigned long file_size;
+       char *file_addr, *endp; 
+
+       if ((fd = open(filename, O_RDONLY, 0)) == -1)
+       {
+               printf("Failed to open code description file %s\n",filename);   
+               return(-1);
+       }
+
+       if (fstat(fd, &stat_buf) == -1)
+       {
+               printf("Error: Can't fstat file: %s\n", filename);
+               return(-1);
+       }
+
+       /*
+        * For some reason mapping files with zero size fails
+        * so it has to be handled specially.
+        */
+       file_size = stat_buf.st_size;
+    
+       if (stat_buf.st_size != 0)
+       {
+               if ((file_addr = mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE, 
+                                     MAP_PRIVATE|MAP_FILE, fd, 0)) == (char*) -1)
+               {
+                       printf("Error: Can't map file: %s\n", filename);
+                       close(fd);
+                       return(-1);
+               }
+       }
+       else
+       {
+               printf("Error: Zero sized file: %s\n", filename);
+               close(fd);
+               return(-1);
+       }
+       close(fd);
+
+
+       /*
+        * If we get here, we have mapped the file
+        * and we are ready to parse it.  Count
+        * the newlines to get total number of codes.
+        */
+
+       for (count = 0, j=1; j < file_size; j++)
+       {
+               if (file_addr[j] == '\n')
+                       count++;
+       }
+
+       if (count == 0)
+       {
+               printf("Error: No codes in %s\n", filename);
+               return(-1);
+       }
+
+       /*
+        * Fudge the count to accomodate the last line in the file -
+        * in case it doesn't end in a newline.
+        */
+       count++;
+
+       if ((codesc = (code_type_t *)malloc(count * sizeof(code_type_t))) == 0 ) {
+               printf("Failed to allocate buffer for code descriptions\n");
+               return(-1);
+       }
+
+       bzero((char *)codesc, count * sizeof(code_type_t));
+       codenum = 0;
+
+       for (line = 1, i = 0, j = 0; j < file_size && i < count ; i++)
+       {
+               /* Skip blank lines */
+               while (file_addr[j] == '\n')
+               {
+                       j++;
+                       line++;
+               }
+       
+               /* Skip leading whitespace */
+               while (file_addr[j] == ' ' || file_addr[j] == '\t')
+                       j++;
+
+               /* Get the debugid code */
+               codesc[i].debugid = strtoul(file_addr + j, &endp, 16);
+               j = endp - file_addr;
+
+               if (codesc[i].debugid == 0)
+               {
+                       /* We didn't find a debugid code - skip this line */
+                       if (verbose_flag)
+                               printf("Error: while parsing line %d, skip\n", line);
+                       while (file_addr[j] != '\n' && j < file_size)
+                               j++;
+                       i--;
+                       line++;
+                       continue;
+               }
+
+               /* Skip whitespace */
+               while (file_addr[j] == ' ' || file_addr[j] == '\t')
+                       j++;
+
+               /* Get around old file that had count at the beginning */
+               if (file_addr[j] == '\n')
+               {
+                       /* missing debugid string - skip */
+                       if (verbose_flag)
+                               printf("Error: while parsing line %d, (0x%x) skip\n", line, codesc[i].debugid);
+           
+                       j++;
+                       i--;
+                       line++;
+                       continue;
+               }
+
+               /* Next is the debugid string terminated by a newline */
+               codesc[i].debug_string = &file_addr[j];
+
+               /* Null out the newline terminator */
+               while ((j < file_size) && (file_addr[j] != '\n'))
+                       j++;
+               file_addr[j] = '\0'; /* File must be read-write */
+               j++;
+               line++;
+               codenum++;      /*Index into codesc is 0 to codenum-1 */
+       }
+
+       if (verbose_flag)
+       {
+               printf("Parsed %d codes in %s\n", codenum, filename);
+               printf("[%6d] 0x%8x  %s\n", 0, codesc[0].debugid, codesc[0].debug_string);
+               printf("[%6d] 0x%8x %s\n\n", codenum-1, codesc[codenum-1].debugid, codesc[codenum-1].debug_string);
+       }
+
+       /* sort */
+       qsort((void *)codesc, codenum, sizeof(code_type_t), debugid_compar);
+
+       if (verbose_flag)
+       {
+               printf("Sorted %d codes in %s\n", codenum, filename);
+               printf("lowbound  [%6d]: 0x%8x %s\n", 0, codesc[0].debugid, codesc[0].debug_string);
+               printf("highbound [%6d]: 0x%8x %s\n\n", codenum-1, codesc[codenum-1].debugid, codesc[codenum-1].debug_string);
+       }
+
+#if 0
+       /* Dump the codefile */
+       for (i = 0; i < codenum; i++)
+               printf("[%d]  0x%x   %s\n",i+1, codesc[i].debugid, codesc[i].debug_string);
+#endif
+       return(0);
+}
+
+
+
+int match_debugid(unsigned int xx, char * debugstr, int * yy)
+{
+       int indx;
+
+       if (codenum == 0)
+               return(-1);
+
+       if (codesc[codeindx_cache].debugid != xx)
+               indx = binary_search(codesc, 0, (codenum-1), xx);
+       else
+               indx = codeindx_cache;
+
+       if (indx == -1)
+               return(indx);  /* match failed */
+       else {
+               bcopy(&codesc[indx].debug_string[0], debugstr,80);
+               *yy = indx;
+               codeindx_cache = indx;
+               return(0);   /* match success */
+       }
+}
+
+
+int
+read_command_map(int fd, int count)
+{
+       int i;
+       size_t size;
+       int mib[6];
+
+       if (readRAW_flag) {
+               total_threads = count;
+               size = count * sizeof(kd_threadmap);
+       } else {
+               get_bufinfo(&bufinfo);
+
+               total_threads = bufinfo.nkdthreads;
+               size = bufinfo.nkdthreads * sizeof(kd_threadmap);
+       }
+       mapptr = 0;
+       nthreads = total_threads * 2;
+
+       if (verbose_flag)
+               printf("Size of map table is %d, thus %d entries\n", (int)size, total_threads);
+
+       if (size) {
+               if ((mapptr = (kd_threadmap *) malloc(size)))
+                       bzero (mapptr, size);
+               else
+               {
+                       if (verbose_flag)
+                               printf("Thread map is not initialized -- this is not fatal\n");
+                       return(0);
+               }
+       }
+       if (readRAW_flag) {
+               off_t   offset;
+               
+               if (read(fd, mapptr, size) != size) {
+                       if (verbose_flag)
+                               printf("Can't read the thread map -- this is not fatal\n");
+                       free(mapptr);
+                       mapptr = 0;
+
+                       if (size < 0)
+                               size = 0;
+                       return(size);
+               }
+               if (raw_header.version_no != RAW_VERSION0) {
+                       offset = lseek(fd, (off_t)0, SEEK_CUR);
+                       offset = (offset + (4095)) & ~4095;
+               
+                       lseek(fd, offset, SEEK_SET);
+               }
+       } else {
+               /* Now read the threadmap */
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_KDEBUG;
+               mib[2] = KERN_KDTHRMAP;
+               mib[3] = 0;
+               mib[4] = 0;
+               mib[5] = 0;             /* no flags */
+               if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
+               {
+                       /* This is not fatal -- just means I cant map command strings */
+                       if (verbose_flag)
+                               printf("Can't read the thread map -- this is not fatal\n");
+                       free(mapptr);
+                       mapptr = 0;
+                       return(0);
+               }
+       }
+       for (i = 0; i < total_threads; i++)
+               create_map_entry(mapptr[i].thread, &mapptr[i].command[0]);
+
+       if (verbose_flag) {
+               /* Dump the initial map */
+               
+               printf("Size of maptable returned is %ld, thus %ld entries\n", size, (size/sizeof(kd_threadmap)));
+
+               printf("Thread    Command\n");
+               for (i = 0; i < total_threads; i++)
+               {
+                       printf ("0x%lx    %s\n",
+                               mapptr[i].thread,
+                               mapptr[i].command);
+               }
+       }
+       return(size);
+}
+
+
+void create_map_entry(uintptr_t thread, char *command)
+{
+       threadmap_t     tme;
+       int             hashid;
+
+       if ((tme = threadmap_freelist))
+               threadmap_freelist = tme->tm_next;
+       else
+               tme = (threadmap_t)malloc(sizeof(struct threadmap));
+
+       tme->tm_thread = thread;
+       tme->tm_deleteme = FALSE;
+
+       (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+       tme->tm_command[MAXCOMLEN] = '\0';
+
+       hashid = thread & HASH_MASK;
+
+       tme->tm_next = threadmap_hash[hashid];
+       threadmap_hash[hashid] = tme;
+}
+
+
+void delete_thread_entry(uintptr_t thread)
+{
+       threadmap_t     tme = 0;
+       threadmap_t     tme_prev;
+       int             hashid;
+
+       hashid = thread & HASH_MASK;
+
+       if ((tme = threadmap_hash[hashid])) {
+               if (tme->tm_thread == thread)
+                       threadmap_hash[hashid] = tme->tm_next;
+               else {
+                       tme_prev = tme;
+
+                       for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+                               if (tme->tm_thread == thread) {
+                                       tme_prev->tm_next = tme->tm_next;
+                                       break;
+                               }
+                               tme_prev = tme;
+                       }
+               }
+               if (tme) {
+                       tme->tm_next = threadmap_freelist;
+                       threadmap_freelist = tme;
+               }
+       }
+}
+
+
+find_and_insert_tmp_map_entry(uintptr_t pthread, char *command)
+{
+       threadmap_t     tme = 0;
+       threadmap_t     tme_prev;
+       int             hashid;
+
+       if ((tme = threadmap_temp)) {
+               if (tme->tm_pthread == pthread)
+                       threadmap_temp = tme->tm_next;
+               else {
+                       tme_prev = tme;
+
+                       for (tme = tme->tm_next; tme; tme = tme->tm_next) {
+                               if (tme->tm_pthread == pthread) {
+                                       tme_prev->tm_next = tme->tm_next;
+                                       break;
+                               }
+                               tme_prev = tme;
+                       }
+               }
+               if (tme) {
+                       (void)strncpy (tme->tm_command, command, MAXCOMLEN);
+                       tme->tm_command[MAXCOMLEN] = '\0';
+
+                       delete_thread_entry(tme->tm_thread);
+
+                       hashid = tme->tm_thread & HASH_MASK;
+
+                       tme->tm_next = threadmap_hash[hashid];
+                       threadmap_hash[hashid] = tme;
+               }
+       }
+}
+
+
+void create_tmp_map_entry(uintptr_t thread, uintptr_t pthread)
+{
+       threadmap_t     tme;
+
+       if ((tme = threadmap_freelist))
+               threadmap_freelist = tme->tm_next;
+       else
+               tme = (threadmap_t)malloc(sizeof(struct threadmap));
+
+       tme->tm_thread = thread;
+       tme->tm_pthread = pthread;
+       tme->tm_deleteme = FALSE;
+       tme->tm_command[0] = '\0';
+
+       tme->tm_next = threadmap_temp;
+       threadmap_temp = tme;
+}
+
+
+threadmap_t
+find_thread_entry(uintptr_t thread)
+{
+       threadmap_t     tme;
+       int     hashid;
+
+       hashid = thread & HASH_MASK;
+
+       for (tme = threadmap_hash[hashid]; tme; tme = tme->tm_next) {
+               if (tme->tm_thread == thread)
+                       return (tme);
+       }
+       return (0);
+}
+
+
+void find_thread_name(uintptr_t thread, char **command, boolean_t deleteme)
+{
+       threadmap_t     tme;
+
+       if ((tme = find_thread_entry(thread))) {
+               *command = tme->tm_command;
+
+               if (deleteme == TRUE)
+                       tme->tm_deleteme = deleteme;
+       } else
+               *command = EMPTYSTRING;
+}
+
+
+void find_thread_command(kd_buf *kbufp, char **command)
+{
+       uintptr_t       thread;
+       threadmap_t     tme;
+       int             debugid_base;
+
+       thread = kbufp->arg5;
+       debugid_base = kbufp->debugid & DBG_FUNC_MASK;
+
+       if (debugid_base == BSC_exit || debugid_base == MACH_STKHANDOFF) {
+               /*
+                * Mark entry as invalid and return temp command pointer
+                */
+               if ((tme = find_thread_entry(thread))) {
+
+                       strncpy(tmpcommand, tme->tm_command, MAXCOMLEN);
+                       *command = tmpcommand;
+
+                       if (debugid_base == BSC_exit || tme->tm_deleteme == TRUE)
+                               delete_thread_entry(thread);
+               } else
+                       *command = EMPTYSTRING;
+       }
+       else if (debugid_base == TRACE_DATA_NEWTHREAD) {
+               /*
+                * Save the create thread data
+                */
+               create_tmp_map_entry(kbufp->arg1, kbufp->arg5);
+       }
+       else if (debugid_base == TRACE_STRING_NEWTHREAD) {
+               /*
+                * process new map entry
+                */
+               find_and_insert_tmp_map_entry(kbufp->arg5, (char *)&kbufp->arg1);
+       }
+       else if (debugid_base == TRACE_STRING_EXEC) {
+
+               delete_thread_entry(kbufp->arg5);
+
+               create_map_entry(kbufp->arg5, (char *)&kbufp->arg1);
+       }
+       else
+               find_thread_name(thread, command, (debugid_base == BSC_thread_terminate));
+}
+
+
+static
+void getdivisor()
+{
+       mach_timebase_info_data_t info;
+
+       (void) mach_timebase_info (&info);
+
+       divisor = ( (double)info.denom / (double)info.numer) * 1000;
+
+       if (verbose_flag)
+               printf("divisor = %g\n", divisor);
+}
index 231d3844f2529df7d8c5065bba53244778352b84..c7736c3e14bdce0e48e0d41ffcd240c9d703cb51 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = vifs.c
 MANPAGES = vifs.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 2f5516d7d89bbaf3adf512d75a82d486f7d5d90c..d6ca8dc4f1e42d85407ae1a97a97bfd5ccaa56a8 100644 (file)
@@ -5,7 +5,7 @@ HFILES = pw_util.h
 CFILES = pw_util.c vipw.c
 MANPAGES = vipw.8
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 14aef47594422dade07fbc9f61f5e20f896c50cc..8b253a105e325684c4997eba755bb55a70a69eba 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = vm_stat.c
 MANPAGES = vm_stat.1
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 332520fba0bb39f449673310b9016a6b70a75882..b4fab3de5d2ac523659b9919948e5fb7ff202bb7 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/sbin
 CFILES = zdump.c
 MANPAGES = zdump.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 04a05f7a8eb00731a1f73d5efd09fedb318cb052..78263b4ffd5631874895bf3ef6ce08958efd70bf 100644 (file)
@@ -5,7 +5,7 @@ HFILES = private.h
 CFILES = ialloc.c scheck.c zic.c
 MANPAGES = zic.8
 
-Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_CC_Flags = -Wall -Werror
 Extra_LD_Flags = -dead_strip
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 508fdcfcd208b8184d0aeec1e8ef96a4b76e9591..8c6407410ef48bf10230e61a462c688360b4ed73 100644 (file)
@@ -4,7 +4,7 @@ Install_Dir = /usr/bin
 CFILES = zprint.c
 MANPAGES = zprint.1
 
-Extra_CC_Flags = -mdynamic-no-pic
+Extra_CC_Flags =
 Extra_LD_Flags = -dead_strip -lutil
 
 include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 398066f9a30eaa5d659e72580ab11d8f9446f4d8..3acaae73cf476e8d29ebbe666734eb977be86047 100644 (file)
@@ -1,9 +1,9 @@
-.TH ZPRINT 1 27/02/87
+.TH ZPRINT 1 02/12/09
 .CM 4
 .SH NAME
 zprint \- show information about kernel zones
 .SH SYNOPSIS
-\fBzprint\fP [\fB-w\fP] [\fB-s\fP] [\fB-c\fP] [\fB-h\fP] [name]
+\fBzprint\fP [\fB-w\fP] [\fB-s\fP] [\fB-c\fP] [\fB-h\fP] [\fB-t\fP] [\fB-d\fP] [\fB-p <pid>\fP][name]
 .SH DESCRIPTION
 \fIzprint(1)\fR displays data about Mach zones.  By default,
 \fIzprint\fR will print out information about all Mach zones.  If the
@@ -30,12 +30,28 @@ It may be useful to override this option when sorting by column.
 .\" ==========
 .TP 8
 .B \-s
-\fIzprint\fR sorts the zones, showing the wasting the most memory first.
+\fIzprint\fR sorts the zones, showing the zone wasting the most memory first.
 .\" ==========
 .TP 8
 .B \-w
 For each zone, \fIzprint\fR calculates how much space is allocated but
 not currently in use, the space wasted by the zone.
+.TP 8
+.B \-t
+For each zone, \fIzprint\fR calculates the total size of allocations from
+the zone over the life of the zone.
+.TP 8
+.B \-d
+Display deltas over time, showing any zones that have achieved a new maximum
+current allocation size during the interval.  If the total allocation sizes are
+being displayed for the zones in question, it will also display the deltas if the
+total allocations have doubled.
+.B \-p <pid>
+Display zone usage related to the specified process id.  Each zone will display
+standard columns and the amount of memory from that zone associated with a given
+process.  The letter "A" in the flags column indicates that this total is being
+accounted to the process.  Otherwise, the total is an indication of the influence
+the process has on the kernel, but the memory is being accounted to the kernel proper.
 .PP
 Any option (including default options) can be overridden
 by specifying the option in upper-case; for example, -C overrides
index e637a454175785772a20803a5846243fe070f44c..c374d0fd310ea500dfe8d1816d4774829770d388 100644 (file)
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
 /*
  * @OSF_COPYRIGHT@
  */
 #define streql(a, b)           (strcmp((a), (b)) == 0)
 #define strneql(a, b, n)       (strncmp((a), (b), (n)) == 0)
 
-static void printzone();
-static void colprintzone();
-static void colprintzoneheader();
-static void printk();
-static int strnlen();
-static boolean_t substr();
+static void usage(void);
+static void printzone(mach_zone_name_t *, task_zone_info_t *);
+static void colprintzone(mach_zone_name_t *, task_zone_info_t *);
+static int  find_deltas(mach_zone_name_t *, task_zone_info_t *, task_zone_info_t *, char *, int, int);
+static void colprintzoneheader(void);
+static void printk(const char *, int);
+static boolean_t substr(const char *a, int alen, const char *b, int blen);
 
 static char *program;
 
+static pid_t pid = 0;
+static task_t task = TASK_NULL;
+static boolean_t ShowPid = FALSE;
+
+static boolean_t ShowDeltas = FALSE;
 static boolean_t ShowWasted = FALSE;
+static boolean_t ShowTotal = FALSE;
 static boolean_t SortZones = FALSE;
 static boolean_t ColFormat = TRUE;
 static boolean_t PrintHeader = TRUE;
 
-static unsigned int totalsize = 0;
-static unsigned int totalused = 0;
+static unsigned long long totalsize = 0;
+static unsigned long long totalused = 0;
+static unsigned long long totalsum = 0;
+static unsigned long long pidsum = 0;
+
+static int last_time = 0;
+
+static char    *zname = NULL;
+static int     znamelen = 0;
+
+static void
+sigintr(__unused int signum)
+{
+       last_time = 1;
+}
 
 static void
-usage()
+usage(void)
 {
-       fprintf(stderr, "usage: %s [-w] [-s] [-c] [-h] [name]\n", program);
+       fprintf(stderr, "usage: %s [-w] [-s] [-c] [-h] [-t] [-d] [-p <pid>] [name]\n", program);
        exit(1);
 }
 
 int
-main(argc, argv)
-       int     argc;
-       char    *argv[];
+main(int argc, char **argv)
 {
-       zone_name_t name_buf[1024];
-       zone_name_t *name = name_buf;
-       unsigned int nameCnt = sizeof name_buf/sizeof name_buf[0];
-       zone_info_t info_buf[1024];
-       zone_info_t *info = info_buf;
-       unsigned int infoCnt = sizeof info_buf/sizeof info_buf[0];
+       mach_zone_name_t *name = NULL;
+       unsigned int nameCnt = 0;
+       task_zone_info_t *info = NULL;
+       unsigned int infoCnt = 0;
 
-       char            *zname = NULL;
-       int             znamelen = 0;
+       task_zone_info_t *max_info = NULL;
+       char            *deltas = NULL;
 
        kern_return_t   kr;
        int             i, j;
+       int             first_time = 1;
+       int             must_print = 1;
+       int             interval = 1;
 
-       if (0 != reexec_to_match_kernel()) {
-               fprintf(stderr, "Could not re-execute: %d\n", errno);
-               exit(1);
-       }
+       signal(SIGINT, sigintr);
 
        program = strrchr(argv[0], '/');
        if (program == NULL)
@@ -104,7 +147,13 @@ main(argc, argv)
                program++;
 
        for (i = 1; i < argc; i++) {
-               if (streql(argv[i], "-w"))
+               if (streql(argv[i], "-d"))
+                       ShowDeltas = TRUE;
+               else if (streql(argv[i], "-t"))
+                       ShowTotal = TRUE;
+               else if (streql(argv[i], "-T"))
+                       ShowTotal = FALSE;
+               else if (streql(argv[i], "-w"))
                        ShowWasted = TRUE;
                else if (streql(argv[i], "-W"))
                        ShowWasted = FALSE;
@@ -118,7 +167,14 @@ main(argc, argv)
                        ColFormat = FALSE;
                else if (streql(argv[i], "-H"))
                        PrintHeader = FALSE;
-               else if (streql(argv[i], "--")) {
+               else if (streql(argv[i], "-p")) {
+                       ShowPid = TRUE;
+                       if (i < argc - 1) {
+                               pid = atoi(argv[i+1]);
+                               i++;
+                       } else
+                               usage();
+               } else if (streql(argv[i], "--")) {
                        i++;
                        break;
                } else if (argv[i][0] == '-')
@@ -142,34 +198,87 @@ main(argc, argv)
                usage();
        }
 
-       kr = host_zone_info(mach_host_self(),
-                           &name, &nameCnt, &info, &infoCnt);
-       if (kr != KERN_SUCCESS) {
-               fprintf(stderr, "%s: host_zone_info: %s\n",
-                    program, mach_error_string(kr));
+       if (ShowDeltas) {
+               SortZones = FALSE;
+               ColFormat = TRUE;
+               PrintHeader = TRUE;
+       }
+
+       if (ShowPid) {
+               kr = task_for_pid(mach_task_self(), pid, &task);
+               if (kr != KERN_SUCCESS) {
+                       fprintf(stderr, "%s: task_for_pid(%d) failed: %s (try running as root)\n", 
+                               program, pid, mach_error_string(kr));
+                       exit(1);
+               }
+       }
+
+    for (;;) {
+        if (ShowPid) {
+           kr = task_zone_info(task, &name, &nameCnt, &info, &infoCnt);
+           if (kr != KERN_SUCCESS) {
+               fprintf(stderr, "%s: task_zone_info: %s\n",
+                       program, mach_error_string(kr));
                exit(1);
+           }
+       } else {
+           mach_zone_info_t *zinfo = NULL;
+
+           kr = mach_zone_info(mach_host_self(),
+                               &name, &nameCnt, &zinfo, &infoCnt);
+           if (kr != KERN_SUCCESS) {
+               fprintf(stderr, "%s: mach_zone_info: %s\n",
+                       program, mach_error_string(kr));
+               exit(1);
+           }
+           kr = vm_allocate(mach_task_self(), (vm_address_t *)&info,
+                            infoCnt * sizeof *info, VM_FLAGS_ANYWHERE);
+           if (kr != KERN_SUCCESS) {
+                   fprintf(stderr, "%s vm_allocate: %s\n",
+                           program, mach_error_string(kr));
+                   exit(1);
+           }
+           for (i = 0; i < infoCnt; i++) {
+                   *(mach_zone_info_t *)(info + i) = zinfo[i];
+                   info[i].tzi_caller_acct = 0;
+                   info[i].tzi_task_alloc = 0;
+                   info[i].tzi_task_free = 0;
+           }
+           kr = vm_deallocate(mach_task_self(), (vm_address_t) zinfo,
+                              (vm_size_t) (infoCnt * sizeof *zinfo));
+           if (kr != KERN_SUCCESS) {
+                   fprintf(stderr, "%s: vm_deallocate: %s\n",
+                           program, mach_error_string(kr));
+                   exit(1);
+           }
        }
-       else if (nameCnt != infoCnt) {
-               fprintf(stderr, "%s: host_zone_info: counts not equal?\n",
+
+       if (nameCnt != infoCnt) {
+               fprintf(stderr, "%s: mach/task_zone_info: counts not equal?\n",
                        program);
                exit(1);
        }
 
+       if (first_time) {
+               deltas = (char *)malloc(infoCnt);
+               max_info = (task_zone_info_t *)malloc((infoCnt * sizeof *info));
+       }
+
        if (SortZones) {
                for (i = 0; i < nameCnt-1; i++)
                        for (j = i+1; j < nameCnt; j++) {
                                int wastei, wastej;
 
-                               wastei = (info[i].zi_cur_size -
-                                         (info[i].zi_elem_size *
-                                          info[i].zi_count));
-                               wastej = (info[j].zi_cur_size -
-                                         (info[j].zi_elem_size *
-                                          info[j].zi_count));
+                               wastei = (info[i].tzi_cur_size -
+                                         (info[i].tzi_elem_size *
+                                          info[i].tzi_count));
+                               wastej = (info[j].tzi_cur_size -
+                                         (info[j].tzi_elem_size *
+                                          info[j].tzi_count));
 
                                if (wastej > wastei) {
-                                       zone_info_t tinfo;
-                                       zone_name_t tname;
+                                       task_zone_info_t tinfo;
+                                       mach_zone_name_t tname;
 
                                        tinfo = info[i];
                                        info[i] = info[j];
@@ -182,18 +291,26 @@ main(argc, argv)
                        }
        }
 
-       if (ColFormat) {
-               colprintzoneheader();
+       must_print = find_deltas(name, info, max_info, deltas, infoCnt, first_time);
+       if (must_print) {
+               if (ColFormat) {
+                       if (!first_time)
+                               printf("\n");
+                       colprintzoneheader();
+               }
+               for (i = 0; i < nameCnt; i++) {
+                       if (deltas[i]) {
+                               if (ColFormat)
+                                       colprintzone(&name[i], &info[i]);
+                               else
+                                       printzone(&name[i], &info[i]);
+                       }
+               }
        }
-       for (i = 0; i < nameCnt; i++)
-               if (substr(zname, znamelen, name[i].zn_name,
-                          strnlen(name[i].zn_name, sizeof name[i].zn_name)))
-                       if (ColFormat)
-                               colprintzone(&name[i], &info[i]);
-                       else
-                               printzone(&name[i], &info[i]);
-
-       if ((name != name_buf) && (nameCnt != 0)) {
+
+       first_time = 0;
+
+       if ((name != NULL) && (nameCnt != 0)) {
                kr = vm_deallocate(mach_task_self(), (vm_address_t) name,
                                   (vm_size_t) (nameCnt * sizeof *name));
                if (kr != KERN_SUCCESS) {
@@ -203,7 +320,7 @@ main(argc, argv)
                }
        }
 
-       if ((info != info_buf) && (infoCnt != 0)) {
+       if ((info != NULL) && (infoCnt != 0)) {
                kr = vm_deallocate(mach_task_self(), (vm_address_t) info,
                                   (vm_size_t) (infoCnt * sizeof *info));
                if (kr != KERN_SUCCESS) {
@@ -213,34 +330,25 @@ main(argc, argv)
                }
        }
 
-       if (ShowWasted && PrintHeader) {
-               printf("TOTAL SIZE   = %u\n", totalsize);
-               printf("TOTAL USED   = %u\n", totalused);
-               printf("TOTAL WASTED = %d\n", totalsize - totalused);
+       if ((ShowWasted||ShowTotal) && PrintHeader && !ShowDeltas) {
+               printf("TOTAL SIZE   = %llu\n", totalsize);
+               printf("TOTAL USED   = %llu\n", totalused);
+               if (ShowWasted)
+                       printf("TOTAL WASTED = %llu\n", totalsize - totalused);
+               if (ShowTotal)
+                       printf("TOTAL ALLOCS = %llu\n", totalsum);
        }
 
-       exit(0);
-}
-
-static int
-strnlen(s, n)
-       char *s;
-       int n;
-{
-       int len = 0;
-
-       while ((len < n) && (*s++ != '\0'))
-               len++;
+       if (ShowDeltas == FALSE || last_time)
+               break;
 
-       return len;
+       sleep(interval);
+    }
+    exit(0);
 }
 
 static boolean_t
-substr(a, alen, b, blen)
-       char *a;
-       int alen;
-       char *b;
-       int blen;
+substr(const char *a, int alen, const char *b, int blen)
 {
        int i;
 
@@ -252,58 +360,69 @@ substr(a, alen, b, blen)
 }
 
 static void
-printzone(name, info)
-       zone_name_t *name;
-       zone_info_t *info;
+printzone(mach_zone_name_t *name, task_zone_info_t *info)
 {
-       unsigned int used, size;
-
-       printf("%.*s zone:\n", (int)sizeof name->zn_name, name->zn_name);
-       printf("\tcur_size:    %dK bytes (%d elements)\n",
-              info->zi_cur_size/1024,
-              info->zi_cur_size/info->zi_elem_size);
-       printf("\tmax_size:    %dK bytes (%d elements)\n",
-              info->zi_max_size/1024,
-              info->zi_max_size/info->zi_elem_size);
-       printf("\telem_size:   %d bytes\n",
-              info->zi_elem_size);
-       printf("\t# of elems:  %d\n",
-              info->zi_count);
-       printf("\talloc_size:  %dK bytes (%d elements)\n",
-              info->zi_alloc_size/1024,
-              info->zi_alloc_size/info->zi_elem_size);
-       if (info->zi_pageable)
-               printf("\tPAGEABLE\n");
-       if (info->zi_collectable)
+       unsigned long long used, size;
+
+       printf("%.*s zone:\n", (int)sizeof name->mzn_name, name->mzn_name);
+       printf("\tcur_size:    %lluK bytes (%llu elements)\n",
+              info->tzi_cur_size/1024,
+              (info->tzi_elem_size == 0) ? 0 :
+              info->tzi_cur_size/info->tzi_elem_size);
+       printf("\tmax_size:    %lluK bytes (%llu elements)\n",
+              info->tzi_max_size/1024,
+              (info->tzi_elem_size == 0) ? 0 :
+              info->tzi_max_size/info->tzi_elem_size);
+       printf("\telem_size:   %llu bytes\n",
+              info->tzi_elem_size);
+       printf("\t# of elems:  %llu\n",
+              info->tzi_count);
+       printf("\talloc_size:  %lluK bytes (%llu elements)\n",
+              info->tzi_alloc_size/1024,
+              (info->tzi_elem_size == 0) ? 0 :
+              info->tzi_alloc_size/info->tzi_elem_size);
+       if (info->tzi_exhaustible)
+               printf("\tEXHAUSTIBLE\n");
+       if (info->tzi_collectable)
                printf("\tCOLLECTABLE\n");
-
+       if (ShowPid && info->tzi_caller_acct)
+               printf("\tCALLER ACCOUNTED\n");
+       if (ShowPid) {
+               pidsum += info->tzi_task_alloc - info->tzi_task_free;
+               printf("\tproc_alloc_size: %8dK bytes (%llu elements)\n",
+                      (int)((info->tzi_task_alloc - info->tzi_task_free)/1024),
+                      (info->tzi_elem_size == 0) ? 0 :
+                      (info->tzi_task_alloc - info->tzi_task_free)/info->tzi_elem_size);
+       }
        if (ShowWasted) {
-               totalused += used = info->zi_elem_size * info->zi_count;
-               totalsize += size = info->zi_cur_size;
-               printf("\t\t\t\t\tWASTED: %d\n", size - used);
+               totalused += used = info->tzi_elem_size * info->tzi_count;
+               totalsize += size = info->tzi_cur_size;
+               printf("\t\t\t\t\tWASTED: %llu\n", size - used);
+       }
+       if (ShowTotal) {
+               totalsum += info->tzi_sum_size;
+               printf("\t\t\t\t\tTOTAL: %llu\n", totalsum);
+               if (ShowPid)
+                       printf("\t\t\t\t\tPID TOTAL: %llu\n", pidsum);
        }
 }
 
 static void
-printk(fmt, i)
-       char *fmt;
-       int i;
+printk(const char *fmt, int i)
 {
        printf(fmt, i / 1024);
        putchar('K');
 }
 
 static void
-colprintzone(zone_name, info)
-       zone_name_t *zone_name;
-       zone_info_t *info;
+colprintzone(mach_zone_name_t *zone_name, task_zone_info_t *info)
 {
-       char *name = zone_name->zn_name;
+       char *name = zone_name->mzn_name;
        int j, namewidth;
-       unsigned int used, size;
+       unsigned long long used, size;
 
        namewidth = 25;
-       if (ShowWasted) {
+       if (ShowWasted || ShowTotal) {
                namewidth -= 7;
        }
        for (j = 0; j < namewidth - 1 && name[j]; j++) {
@@ -324,51 +443,96 @@ colprintzone(zone_name, info)
                        putchar(' ');
                }
        }
-       printf("%5d", info->zi_elem_size);
-       printk("%6d", info->zi_cur_size);
-       if (info->zi_max_size >= 99999 * 1024) {
-               printf("   ----");
+       printf("%5llu", info->tzi_elem_size);
+       printk("%8llu", info->tzi_cur_size);
+       if (info->tzi_max_size / 1024 > 9999999) {
+               printf("   ------");
        } else {
-               printk("%6d", info->zi_max_size);
+               printk("%8llu", info->tzi_max_size);
        }
-       printf("%7d", info->zi_cur_size / info->zi_elem_size);
-       if (info->zi_max_size >= 99999 * 1024) {
-               printf("   ----");
+       printf("%10llu", info->tzi_cur_size / info->tzi_elem_size);
+       if (info->tzi_max_size / 1024 >= 999999999) {
+               printf(" ---------");
        } else {
-               printf("%7d", info->zi_max_size / info->zi_elem_size);
+               printf("%10llu", info->tzi_max_size / info->tzi_elem_size);
        }
-       printf("%6d", info->zi_count);
-       printk("%5d", info->zi_alloc_size);
-       printf("%6d", info->zi_alloc_size / info->zi_elem_size);
-
-       totalused += used = info->zi_elem_size * info->zi_count;
-       totalsize += size = info->zi_cur_size;
+       printf("%10llu", info->tzi_count);
+       printk("%5llu", info->tzi_alloc_size);
+       printf("%6llu", info->tzi_alloc_size / info->tzi_elem_size);
+
+       totalused += used = info->tzi_elem_size * info->tzi_count;
+       totalsize += size = info->tzi_cur_size;
+       totalsum += info->tzi_sum_size;
+
+       printf(" %c%c%c",
+              (info->tzi_exhaustible ? 'X' : ' '),
+              (info->tzi_caller_acct ? 'A' : ' '),
+              (info->tzi_collectable ? 'C' : ' '));
        if (ShowWasted) {
-               printf("%7d", size - used);
+               printk("%8llu", size - used);
        }
-
-       printf("%c%c\n",
-              (info->zi_pageable ? 'P' : ' '),
-              (info->zi_collectable ? 'C' : ' '));
+       if (ShowPid) {
+               printf("%8dK", (int)((info->tzi_task_alloc - info->tzi_task_free)/1024));
+       }
+       if (ShowTotal) {
+               if (info->tzi_sum_size < 1024)
+                       printf("%16lluB", info->tzi_sum_size);
+               else
+                       printf("%16lluK", info->tzi_sum_size/1024);
+       }
+       printf("\n");
 }
 
 static void
-colprintzoneheader()
+colprintzoneheader(void)
 {
        if (! PrintHeader) {
                return;
        }
-       if (ShowWasted) {
-               printf("                   elem    cur    max    cur    max%s",
-                      "   cur alloc alloc\n");
-               printf("zone name          size   size   size  #elts  #elts%s",
-                      " inuse  size count wasted\n");
-       } else {
-               printf("                          elem    cur    max    cur%s",
-                      "    max   cur alloc alloc\n");
-               printf("zone name                 size   size   size  #elts%s",
-                      "  #elts inuse  size count\n");
-       }
-       printf("-----------------------------------------------%s",
-              "--------------------------------\n");
+       printf("%s                   elem      cur      max       cur       max"
+              "       cur alloc alloc          %s\n", 
+              (ShowWasted||ShowTotal)? "" : "       ", (ShowPid) ? "PID" : "" );
+       printf("zone name%s          size     size     size     #elts     #elts"
+              "     inuse  size count   ", (ShowWasted||ShowTotal)? "" : "       " );
+       if (ShowWasted)
+               printf("   wasted");
+       if (ShowPid)
+               printf("    Allocs");
+       if (ShowTotal)
+               printf("     Total Allocs");
+       printf("\n%s------------------------------------------"
+              "--------------------------------------------",
+              (ShowWasted||ShowTotal)? "" : "-------");
+       if (ShowWasted)
+               printf("---------");
+       if (ShowPid)
+               printf("----------");
+       if (ShowTotal)
+               printf("-----------------");
+       printf("\n");
+}
+
+int
+find_deltas(mach_zone_name_t *name, task_zone_info_t *info, task_zone_info_t *max_info,
+           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->tzi_cur_size > max_info->tzi_cur_size ||
+                          (ShowTotal && ((info->tzi_sum_size >> 1) > max_info->tzi_sum_size))) {
+                              max_info->tzi_cur_size = info->tzi_cur_size;
+                              max_info->tzi_sum_size = info->tzi_sum_size;
+                              deltas[i] = 1;
+                              found_one = 1;
+                      }
+              }
+              info++;
+              max_info++;
+       }
+       return(found_one);
 }