]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_malloc.c
xnu-3248.30.4.tar.gz
[apple/xnu.git] / bsd / kern / kern_malloc.c
index c1700ee51a7e6c5f8dfbdf2db15021932b49fb55..d1adaabece24eb1e8deca7afd26a1a4c0f0d56b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
 #include <sys/socketvar.h>
 
 #include <net/route.h>
+#include <net/necp.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/in_pcb.h>
+#include <netinet/flow_divert.h>
 
 #include <sys/event.h>
 #include <sys/eventvar.h>
 #include <kern/zalloc.h>
 #include <kern/kalloc.h>
 
-void kmeminit(void) __attribute__((section("__TEXT, initcode")));
+void kmeminit(void);
 
 /* Strings corresponding to types of memory.
  * Must be in synch with the #defines is sys/malloc.h 
@@ -162,7 +164,7 @@ const char *memname[] = {
 #else
        "",                             /* 27 M_DQUOT */ 
 #endif
-       "",                             /* 28 M_UFSMNT */ 
+       "proc uuid policy",             /* 28 M_PROC_UUID_POLICY */ 
 #if (SYSV_SEM || SYSV_MSG || SYSV_SHM)
        "shm",                  /* 29 M_SHM */ 
 #else
@@ -234,8 +236,8 @@ const char *memname[] = {
        "",                             /* 76 M_HFSNODE */ 
        "",                             /* 77 M_HFSFORK */ 
 #endif
-       "ZFS mount",    /* 78 M_ZFSFSMNT */ 
-       "ZFS node",     /* 79 M_ZFSNODE */ 
+       "",     /* 78 unused */
+       "",     /* 79 unused */ 
        "temp",                 /* 80 M_TEMP */ 
        "key mgmt",             /* 81 M_SECA */ 
        "DEVFS",                /* 82 M_DEVFS */ 
@@ -273,16 +275,12 @@ const char *memname[] = {
        "fileglob",             /* 99 M_FILEGLOB */ 
        "kauth",                /* 100 M_KAUTH */ 
        "dummynet",             /* 101 M_DUMMYNET */ 
-#ifndef __LP64__
-       "unsafe_fsnode",        /* 102 M_UNSAFEFS */ 
-#else
        "",                     /* 102 M_UNSAFEFS */ 
-#endif /* __LP64__ */
        "macpipelabel", /* 103 M_MACPIPELABEL */
        "mactemp",      /* 104 M_MACTEMP */
        "sbuf",         /* 105 M_SBUF */
        "extattr",      /* 106 M_EXTATTR */
-       "lctx",         /* 107 M_LCTX */
+       "select",       /* 107 M_SELECT */
 #if TRAFFIC_MGT
        "traffic_mgt",   /* 108 M_TRAFFIC_MGT */
 #else
@@ -298,6 +296,29 @@ const char *memname[] = {
        "in6mfilter",   /* 112 M_IN6MFILTER */
        "ip6mopts",     /* 113 M_IP6MOPTS */
        "ip6msource",   /* 114 M_IP6MSOURCE */
+#if FLOW_DIVERT
+       "flow_divert_pcb",      /* 115 M_FLOW_DIVERT_PCB */
+       "flow_divert_group",    /* 116 M_FLOW_DIVERT_GROUP */
+#else
+       "",                                     /* 115 M_FLOW_DIVERT_PCB */
+       "",                                     /* 116 M_FLOW_DIVERT_GROUP */
+#endif
+       "ip6cga",       /* 117 M_IP6CGA */
+#if NECP
+       "necp",                                 /* 118 M_NECP */
+       "necp_session_policy",  /* 119 M_NECP_SESSION_POLICY */
+       "necp_socket_policy",   /* 120 M_NECP_SOCKET_POLICY */
+       "necp_ip_policy",               /* 121 M_NECP_IP_POLICY */
+#else
+       "",                                             /* 118 M_NECP */
+       "",                                             /* 119 M_NECP_SESSION_POLICY */
+       "",                                             /* 120 M_NECP_SOCKET_POLICY */
+       "",                                             /* 121 M_NECP_IP_POLICY */
+#endif
+       "fdvnodedata"   /* 122 M_FD_VN_DATA */
+       "fddirbuf",     /* 123 M_FD_DIRBUF */
+       "netagent",     /* 124 M_NETAGENT */
+       ""
 };
 
 /* for use with kmzones.kz_zalloczone */
@@ -352,7 +373,7 @@ struct kmzones {
 #else
        { 0,            KMZ_MALLOC, FALSE },            /* 27 M_DQUOT */
 #endif
-       { 0,            KMZ_MALLOC, FALSE },            /* 28 M_UFSMNT */
+       { 0,            KMZ_MALLOC, FALSE },            /* 28 M_PROC_UUID_POLICY */
        { 0,            KMZ_MALLOC, FALSE },            /* 29 M_SHM */
        { SOS(plimit),  KMZ_CREATEZONE, TRUE },         /* 30 M_PLIMIT */
        { SOS(sigacts), KMZ_CREATEZONE_ACCT, TRUE },    /* 31 M_SIGACTS */
@@ -426,8 +447,8 @@ struct kmzones {
        { 0,            KMZ_MALLOC, FALSE },            /* 76 M_HFSNODE */
        { 0,            KMZ_MALLOC, FALSE },            /* 77 M_HFSFORK */
 #endif
-       { 0,            KMZ_MALLOC, FALSE },            /* 78 M_ZFSMNT */
-       { 0,            KMZ_MALLOC, FALSE },            /* 79 M_ZFSNODE */
+       { 0,            KMZ_MALLOC, FALSE },            /* 78 unused */
+       { 0,            KMZ_MALLOC, FALSE },            /* 79 unused */
        { 0,            KMZ_MALLOC, FALSE },            /* 80 M_TEMP */
        { 0,            KMZ_MALLOC, FALSE },            /* 81 M_SECA */
        { 0,            KMZ_MALLOC, FALSE },            /* 82 M_DEVFS */
@@ -459,16 +480,12 @@ struct kmzones {
        { SOS(fileglob),        KMZ_CREATEZONE, TRUE }, /* 99 M_FILEGLOB */
        { 0,            KMZ_MALLOC, FALSE },            /* 100 M_KAUTH */
        { 0,            KMZ_MALLOC, FALSE },            /* 101 M_DUMMYNET */
-#ifndef __LP64__
-       { SOS(unsafe_fsnode),KMZ_CREATEZONE, TRUE },    /* 102 M_UNSAFEFS */
-#else 
        { 0,            KMZ_MALLOC, FALSE },            /* 102 M_UNSAFEFS */
-#endif /* __LP64__ */
        { 0,            KMZ_MALLOC, FALSE },            /* 103 M_MACPIPELABEL */
        { 0,            KMZ_MALLOC, FALSE },            /* 104 M_MACTEMP */
        { 0,            KMZ_MALLOC, FALSE },            /* 105 M_SBUF */
        { 0,            KMZ_MALLOC, FALSE },            /* 106 M_HFS_EXTATTR */
-       { 0,            KMZ_MALLOC, FALSE },            /* 107 M_LCTX */
+       { 0,            KMZ_MALLOC, FALSE },            /* 107 M_SELECT */
        { 0,            KMZ_MALLOC, FALSE },            /* 108 M_TRAFFIC_MGT */
 #if HFS_COMPRESSION
        { SOS(decmpfs_cnode),KMZ_CREATEZONE , FALSE},   /* 109 M_DECMPFS_CNODE */
@@ -480,6 +497,27 @@ struct kmzones {
        { 0,            KMZ_MALLOC, FALSE },            /* 112 M_IN6MFILTER */
        { 0,            KMZ_MALLOC, FALSE },            /* 113 M_IP6MOPTS */
        { 0,            KMZ_MALLOC, FALSE },            /* 114 M_IP6MSOURCE */
+#if FLOW_DIVERT
+       { SOS(flow_divert_pcb),         KMZ_CREATEZONE, TRUE }, /* 115 M_FLOW_DIVERT_PCB */
+       { SOS(flow_divert_group),       KMZ_CREATEZONE, TRUE }, /* 116 M_FLOW_DIVERT_GROUP */
+#else
+       { 0,            KMZ_MALLOC, FALSE },            /* 115 M_FLOW_DIVERT_PCB */
+       { 0,            KMZ_MALLOC, FALSE },            /* 116 M_FLOW_DIVERT_GROUP */
+#endif /* FLOW_DIVERT */
+       { 0,            KMZ_MALLOC, FALSE },            /* 117 M_IP6CGA */
+       { 0,            KMZ_MALLOC, FALSE },            /* 118 M_NECP */
+#if NECP
+       { SOS(necp_session_policy),     KMZ_CREATEZONE, TRUE }, /* 119 M_NECP_SESSION_POLICY */
+       { SOS(necp_kernel_socket_policy),       KMZ_CREATEZONE, TRUE }, /* 120 M_NECP_SOCKET_POLICY */
+       { SOS(necp_kernel_ip_output_policy),    KMZ_CREATEZONE, TRUE }, /* 121 M_NECP_IP_POLICY */
+#else
+       { 0,            KMZ_MALLOC, FALSE },            /* 119 M_NECP_SESSION_POLICY */
+       { 0,            KMZ_MALLOC, FALSE },            /* 120 M_NECP_SOCKET_POLICY */
+       { 0,            KMZ_MALLOC, FALSE },            /* 121 M_NECP_IP_POLICY */
+#endif /* NECP */
+       { 0,            KMZ_MALLOC, FALSE },            /* 122 M_FD_VN_DATA */
+       { 0,            KMZ_MALLOC, FALSE },            /* 123 M_FD_DIRBUF */
+       { 0,            KMZ_MALLOC, FALSE },            /* 124 M_NETAGENT */
 #undef SOS
 #undef SOX
 };
@@ -546,13 +584,30 @@ struct _mhead {
        char    dat[0];
 };
 
+
 void *
-_MALLOC(
+_MALLOC_external(
+       size_t          size,
+       int             type,
+       int             flags);
+void *
+_MALLOC_external(
        size_t          size,
        int             type,
        int             flags)
 {
-       struct _mhead   *hdr;
+    static vm_allocation_site_t site = { VM_KERN_MEMORY_KALLOC, VM_TAG_BT };
+    return (__MALLOC(size, type, flags, &site));
+}
+
+void *
+__MALLOC(
+       size_t          size,
+       int             type,
+       int             flags,
+       vm_allocation_site_t *site)
+{
+       struct _mhead   *hdr = NULL;
        size_t          memsize = sizeof (*hdr) + size;
 
        if (type >= M_LAST)
@@ -562,11 +617,23 @@ _MALLOC(
                return (NULL);
 
        if (flags & M_NOWAIT) {
-               hdr = (void *)kalloc_noblock(memsize);
+               if (size > memsize)   /* overflow detected */
+                       return (NULL);
+               else
+                       hdr = (void *)kalloc_canblock(memsize, FALSE, site); 
        } else {
-               hdr = (void *)kalloc(memsize);
-
-               if (hdr == NULL) {
+               if (size > memsize) {
+                       /*
+                        * We get here when the caller told us to block, waiting for memory but an overflow
+                        * has been detected.  The caller isn't expecting a NULL return code so we panic
+                        * with a descriptive message.
+                        */
+                       panic("_MALLOC: overflow detected, size %llu ", (uint64_t) size);
+               }
+               else
+                       hdr = (void *)kalloc_canblock(memsize, TRUE, site);
+
+              if (hdr == NULL) {
 
                        /*
                         * We get here when the caller told us to block waiting for memory, but
@@ -610,11 +677,12 @@ _FREE(
 }
 
 void *
-_REALLOC(
+__REALLOC(
        void            *addr,
        size_t          size,
        int             type,
-       int             flags)
+       int             flags,
+       vm_allocation_site_t *site)
 {
        struct _mhead   *hdr;
        void            *newaddr;
@@ -622,10 +690,10 @@ _REALLOC(
 
        /* realloc(NULL, ...) is equivalent to malloc(...) */
        if (addr == NULL)
-               return (_MALLOC(size, type, flags));
+               return (__MALLOC(size, type, flags, site));
 
        /* Allocate a new, bigger (or smaller) block */
-       if ((newaddr = _MALLOC(size, type, flags)) == NULL)
+       if ((newaddr = __MALLOC(size, type, flags, site)) == NULL)
                return (NULL);
 
        hdr = addr;
@@ -640,10 +708,25 @@ _REALLOC(
 }
 
 void *
-_MALLOC_ZONE(
+_MALLOC_ZONE_external(
+       size_t          size,
+       int             type,
+       int             flags);
+void *
+_MALLOC_ZONE_external(
        size_t          size,
        int             type,
        int             flags)
+{
+    return (__MALLOC_ZONE(size, type, flags, NULL));
+}
+
+void *
+__MALLOC_ZONE(
+       size_t          size,
+       int             type,
+       int             flags,
+       vm_allocation_site_t *site)
 {
        struct kmzones  *kmz;
        void            *elem;
@@ -667,9 +750,9 @@ _MALLOC_ZONE(
                }
        else
                if (flags & M_NOWAIT) {
-                       elem = (void *)kalloc_noblock(size);
+                       elem = (void *)kalloc_canblock(size, FALSE, site);
                } else {
-                       elem = (void *)kalloc(size);
+                       elem = (void *)kalloc_canblock(size, TRUE, site);
                }
 
        return (elem);