Loading...
--- xnu/xnu-12377.101.15/iokit/Kernel/IOKitDebug.cpp
+++ xnu/xnu-6153.11.26/iokit/Kernel/IOKitDebug.cpp
@@ -26,9 +26,10 @@
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
+
#include <sys/sysctl.h>
extern "C" {
-#include <vm/vm_kern_xnu.h>
+#include <vm/vm_kern.h>
#include <kern/task.h>
#include <kern/debug.h>
}
@@ -37,7 +38,6 @@
#include <libkern/OSDebug.h>
#include <libkern/c++/OSCPPDebug.h>
#include <kern/backtrace.h>
-#include <kern/btlog.h>
#include <IOKit/IOKitDebug.h>
#include <IOKit/IOLib.h>
@@ -47,8 +47,14 @@
#include "IOKitKernelInternal.h"
-TUNABLE_WRITEABLE(SInt64, gIOKitDebug, "io", DEBUG_INIT_VALUE);
-TUNABLE_DEV_WRITEABLE(SInt64, gIOKitTrace, "iotrace", 0);
+#ifdef IOKITDEBUG
+#define DEBUG_INIT_VALUE IOKITDEBUG
+#else
+#define DEBUG_INIT_VALUE 0
+#endif
+
+SInt64 gIOKitDebug = DEBUG_INIT_VALUE;
+SInt64 gIOKitTrace = 0;
#if DEVELOPMENT || DEBUG
#define IODEBUG_CTLFLAGS CTLFLAG_RW
@@ -56,7 +62,7 @@
#define IODEBUG_CTLFLAGS CTLFLAG_RD
#endif
-SYSCTL_QUAD(_debug, OID_AUTO, iotrace, IODEBUG_CTLFLAGS | CTLFLAG_LOCKED, &gIOKitTrace, "trace io");
+SYSCTL_QUAD(_debug, OID_AUTO, iotrace, CTLFLAG_RW | CTLFLAG_LOCKED, &gIOKitTrace, "trace io");
static int
sysctl_debug_iokit
@@ -71,16 +77,14 @@
}
SYSCTL_PROC(_debug, OID_AUTO, iokit,
- CTLTYPE_QUAD | IODEBUG_CTLFLAGS | CTLFLAG_KERN | CTLFLAG_LOCKED,
+ CTLTYPE_QUAD | IODEBUG_CTLFLAGS | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
&gIOKitDebug, 0, sysctl_debug_iokit, "Q", "boot_arg io");
-void (*gIOTrackingLeakScanCallback)(uint32_t notification) = NULL;
-
-size_t debug_malloc_size;
-size_t debug_iomalloc_size;
+int debug_malloc_size;
+int debug_iomalloc_size;
vm_size_t debug_iomallocpageable_size;
-size_t debug_container_malloc_size;
+int debug_container_malloc_size;
// int debug_ivars_size; // in OSObject.cpp
extern "C" {
@@ -96,6 +100,7 @@
IORegistryEntry * next;
IORegistryIterator * iter;
OSOrderedSet * all;
+ char format[] = "%xxxs";
IOService * service;
iter = IORegistryIterator::iterateOver( plane );
@@ -110,7 +115,9 @@
iter->reset();
while ((next = iter->getNextObjectRecursive())) {
- DEBG( "%*s\033[33m%s", 2 * next->getDepth( plane ), "", next->getName( plane ));
+ snprintf(format + 1, sizeof(format) - 1, "%ds", 2 * next->getDepth( plane ));
+ DEBG( format, "");
+ DEBG( "\033[33m%s", next->getName( plane ));
if ((next->getLocation( plane ))) {
DEBG("@%s", next->getLocation( plane ));
}
@@ -122,8 +129,6 @@
// IOSleep(250);
}
iter->release();
-
-#undef IOPrintPlaneFormat
}
void
@@ -142,10 +147,10 @@
// OSMetaClass::printInstanceCounts();
IOLog("\n"
- "ivar kalloc() 0x%08lx\n"
- "malloc() 0x%08lx\n"
- "containers kalloc() 0x%08lx\n"
- "IOMalloc() 0x%08lx\n"
+ "ivar kalloc() 0x%08x\n"
+ "malloc() 0x%08x\n"
+ "containers kalloc() 0x%08x\n"
+ "IOMalloc() 0x%08x\n"
"----------------------------------------\n",
debug_ivars_size,
debug_malloc_size,
@@ -254,38 +259,19 @@
queue_head_t sites[];
};
-
-struct IOTrackingCallSiteUser {
- pid_t pid;
- uint8_t user32;
- uint8_t userCount;
- uintptr_t bt[kIOTrackingCallSiteBTs];
-};
-
struct IOTrackingCallSite {
queue_chain_t link;
+ IOTrackingQueue * queue;
+ uint32_t crc;
+
+ vm_tag_t tag;
+ uint32_t count;
+ size_t size[2];
+ uintptr_t bt[kIOTrackingCallSiteBTs];
+
queue_head_t instances;
- IOTrackingQueue * queue;
- IOTracking ** addresses;
- size_t size[2];
- uint32_t crc;
- uint32_t count;
-
- vm_tag_t tag;
- uint8_t user32;
- uint8_t userCount;
- pid_t btPID;
-
- uintptr_t bt[kIOTrackingCallSiteBTs];
- IOTrackingCallSiteUser user[0];
+ IOTracking * addresses;
};
-
-struct IOTrackingCallSiteWithUser {
- struct IOTrackingCallSite site;
- struct IOTrackingCallSiteUser user;
-};
-
-static void IOTrackingFreeCallSite(uint32_t type, IOTrackingCallSite ** site);
struct IOTrackingLeaksRef {
uintptr_t * instances;
@@ -357,7 +343,9 @@
if (!numSiteQs) {
numSiteQs = 1;
}
- queue = kalloc_type(IOTrackingQueue, queue_head_t, numSiteQs, Z_WAITOK_ZERO);
+ queue = (typeof(queue))kalloc(sizeof(IOTrackingQueue) + numSiteQs * sizeof(queue->sites[0]));
+ bzero(queue, sizeof(IOTrackingQueue));
+
queue->name = name;
queue->btEntry = btEntry;
queue->allocSize = allocSize;
@@ -380,13 +368,6 @@
return queue;
};
-void
-IOTrackingQueueCollectUser(IOTrackingQueue * queue)
-{
- assert(0 == queue->siteCount);
- queue->type |= kIOTrackingQueueTypeUser;
-}
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
@@ -399,7 +380,7 @@
lck_mtx_free(queue->lock.mutex, IOLockGroup);
- kfree_type(IOTrackingQueue, queue_head_t, queue->numSiteQs, queue);
+ kfree(queue, sizeof(IOTrackingQueue) + queue->numSiteQs * sizeof(queue->sites[0]));
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -487,7 +468,7 @@
// residue, which shall retain information from both the higher
// and lower parts of hashcode.
uint64_t h = fasthash64(buf, len, seed);
- return (uint32_t) (h - (h >> 32));
+ return h - (h >> 32);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -496,7 +477,7 @@
IOTrackingAddUser(IOTrackingQueue * queue, IOTrackingUser * mem, vm_size_t size)
{
uint32_t num;
- int pid;
+ proc_t self;
if (!queue->captureOn) {
return;
@@ -507,18 +488,18 @@
assert(!mem->link.next);
- num = backtrace(&mem->bt[0], kIOTrackingCallSiteBTs, NULL, NULL);
+ num = backtrace(&mem->bt[0], kIOTrackingCallSiteBTs, NULL);
num = 0;
- if ((kernel_task != current_task()) && (pid = proc_selfpid())) {
- struct backtrace_user_info btinfo = BTUINFO_INIT;
- mem->btPID = pid;
- num = backtrace_user(&mem->btUser[0], kIOTrackingCallSiteBTs - 1,
- NULL, &btinfo);
- mem->user32 = !(btinfo.btui_info & BTI_64_BIT);
+ if ((kernel_task != current_task()) && (self = proc_self())) {
+ bool user_64 = false;
+ mem->btPID = proc_pid(self);
+ (void)backtrace_user(&mem->btUser[0], kIOTrackingCallSiteBTs - 1, &num,
+ &user_64, NULL);
+ mem->user32 = !user_64;
+ proc_rele(self);
}
assert(num <= kIOTrackingCallSiteBTs);
- static_assert(kIOTrackingCallSiteBTs <= UINT8_MAX);
- mem->userCount = ((uint8_t) num);
+ mem->userCount = num;
IOTRecursiveLockLock(&queue->lock);
queue_enter/*last*/ (&queue->sites[0], mem, IOTrackingUser *, link);
@@ -550,11 +531,7 @@
IOTrackingCallSite * site;
uint32_t crc, num;
uintptr_t bt[kIOTrackingCallSiteBTs + 1];
- uintptr_t btUser[kIOTrackingCallSiteBTs];
queue_head_t * que;
- bool user;
- int pid;
- int userCount;
if (mem->site) {
return;
@@ -566,30 +543,14 @@
return;
}
- user = (0 != (kIOTrackingQueueTypeUser & queue->type));
-
assert(!mem->link.next);
- num = backtrace(&bt[0], kIOTrackingCallSiteBTs + 1, NULL, NULL);
+ num = backtrace(&bt[0], kIOTrackingCallSiteBTs + 1, NULL);
if (!num) {
return;
}
num--;
crc = fasthash32(&bt[1], num * sizeof(bt[0]), 0x04C11DB7);
-
- userCount = 0;
- pid = 0;
- backtrace_info_t btinfo = BTI_NONE;
- if (user) {
- if ((kernel_task != current_task()) && (pid = proc_selfpid())) {
- struct backtrace_user_info btuinfo = BTUINFO_INIT;
- userCount = backtrace_user(&btUser[0], kIOTrackingCallSiteBTs,
- NULL, &btuinfo);
- assert(userCount <= kIOTrackingCallSiteBTs);
- btinfo = btuinfo.btui_info;
- crc = fasthash32(&btUser[0], userCount * sizeof(bt[0]), crc);
- }
- }
IOTRecursiveLockLock(&queue->lock);
que = &queue->sites[crc % queue->numSiteQs];
@@ -598,25 +559,16 @@
if (tag != site->tag) {
continue;
}
- if (user && (pid != site->user[0].pid)) {
- continue;
- }
if (crc == site->crc) {
break;
}
}
if (queue_end(que, (queue_entry_t) site)) {
- if (user) {
- site = &kalloc_type(IOTrackingCallSiteWithUser,
- Z_WAITOK_ZERO_NOFAIL)->site;
- } else {
- site = kalloc_type(IOTrackingCallSite,
- Z_WAITOK_ZERO_NOFAIL);
- }
+ site = (typeof(site))kalloc(sizeof(IOTrackingCallSite));
queue_init(&site->instances);
- site->addresses = NULL;
+ site->addresses = (IOTracking *) &site->instances;
site->queue = queue;
site->crc = crc;
site->count = 0;
@@ -625,36 +577,16 @@
bcopy(&bt[1], &site->bt[0], num * sizeof(site->bt[0]));
assert(num <= kIOTrackingCallSiteBTs);
bzero(&site->bt[num], (kIOTrackingCallSiteBTs - num) * sizeof(site->bt[0]));
- if (user) {
- bcopy(&btUser[0], &site->user[0].bt[0], userCount * sizeof(site->user[0].bt[0]));
- assert(userCount <= kIOTrackingCallSiteBTs);
- bzero(&site->user[0].bt[userCount], (kIOTrackingCallSiteBTs - userCount) * sizeof(site->user[0].bt[0]));
- site->user[0].pid = pid;
- site->user[0].user32 = !(btinfo & BTI_64_BIT);
- static_assert(kIOTrackingCallSiteBTs <= UINT8_MAX);
- site->user[0].userCount = ((uint8_t) userCount);
- }
+
queue_enter_first(que, site, IOTrackingCallSite *, link);
queue->siteCount++;
}
if (address) {
- IOTrackingAddress * memAddr = (typeof(memAddr))mem;
- uint32_t hashIdx;
-
- if (NULL == site->addresses) {
- site->addresses = kalloc_type(IOTracking *, queue->numSiteQs, Z_WAITOK_ZERO_NOFAIL);
- for (hashIdx = 0; hashIdx < queue->numSiteQs; hashIdx++) {
- site->addresses[hashIdx] = (IOTracking *) &site->instances;
- }
- }
- hashIdx = atop(memAddr->address) % queue->numSiteQs;
- if (queue_end(&site->instances, (queue_entry_t)site->addresses[hashIdx])) {
- queue_enter/*last*/ (&site->instances, mem, IOTracking *, link);
- } else {
- queue_insert_before(&site->instances, mem, site->addresses[hashIdx], IOTracking *, link);
- }
- site->addresses[hashIdx] = mem;
+ queue_enter/*last*/ (&site->instances, mem, IOTracking *, link);
+ if (queue_end(&site->instances, (queue_entry_t)site->addresses)) {
+ site->addresses = mem;
+ }
} else {
queue_enter_first(&site->instances, mem, IOTracking *, link);
}
@@ -668,12 +600,9 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-static void
-IOTrackingRemoveInternal(IOTrackingQueue * queue, IOTracking * mem, size_t size, uint32_t addressIdx)
-{
- IOTrackingCallSite * site;
- IOTrackingAddress * nextAddress;
-
+void
+IOTrackingRemove(IOTrackingQueue * queue, IOTracking * mem, size_t size)
+{
if (!mem->link.next) {
return;
}
@@ -681,57 +610,29 @@
IOTRecursiveLockLock(&queue->lock);
if (mem->link.next) {
assert(mem->site);
- site = mem->site;
-
- if ((-1U != addressIdx) && (mem == site->addresses[addressIdx])) {
- nextAddress = (IOTrackingAddress *) queue_next(&mem->link);
- if (!queue_end(&site->instances, &nextAddress->tracking.link)
- && (addressIdx != (atop(nextAddress->address) % queue->numSiteQs))) {
- nextAddress = (IOTrackingAddress *) &site->instances;
- }
- site->addresses[addressIdx] = &nextAddress->tracking;
- }
-
+
+ if (mem == mem->site->addresses) {
+ mem->site->addresses = (IOTracking *) queue_next(&mem->link);
+ }
remque(&mem->link);
- assert(site->count);
- site->count--;
- assert(site->size[0] >= size);
- site->size[0] -= size;
- if (!site->count) {
- assert(queue_empty(&site->instances));
- assert(!site->size[0]);
- assert(!site->size[1]);
-
- remque(&site->link);
+
+ assert(mem->site->count);
+ mem->site->count--;
+ assert(mem->site->size[0] >= size);
+ mem->site->size[0] -= size;
+ if (!mem->site->count) {
+ assert(queue_empty(&mem->site->instances));
+ assert(!mem->site->size[0]);
+ assert(!mem->site->size[1]);
+
+ remque(&mem->site->link);
assert(queue->siteCount);
queue->siteCount--;
- IOTrackingFreeCallSite(queue->type, &site);
+ kfree(mem->site, sizeof(IOTrackingCallSite));
}
mem->site = NULL;
}
IOTRecursiveLockUnlock(&queue->lock);
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-void
-IOTrackingRemove(IOTrackingQueue * queue, IOTracking * mem, size_t size)
-{
- return IOTrackingRemoveInternal(queue, mem, size, -1U);
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-void
-IOTrackingRemoveAddress(IOTrackingQueue * queue, IOTrackingAddress * mem, size_t size)
-{
- uint32_t addressIdx;
- uint64_t address;
-
- address = mem->address;
- addressIdx = atop(address) % queue->numSiteQs;
-
- return IOTrackingRemoveInternal(queue, &mem->tracking, size, addressIdx);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -749,7 +650,8 @@
}
address = ~address;
- tracking = kalloc_type(IOTrackingAddress, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ tracking = (typeof(tracking))kalloc(sizeof(IOTrackingAddress));
+ bzero(tracking, sizeof(IOTrackingAddress));
IOTrackingAddressFlags(tracking) |= kTrackingAddressFlagAllocated;
tracking->address = address;
tracking->size = size;
@@ -764,38 +666,24 @@
{
IOTrackingCallSite * site;
IOTrackingAddress * tracking;
- IOTrackingAddress * nextAddress;
- uint32_t idx, hashIdx;
+ uint32_t idx;
bool done;
address = ~address;
IOTRecursiveLockLock(&queue->lock);
-
- hashIdx = atop(address) % queue->numSiteQs;
-
done = false;
for (idx = 0; idx < queue->numSiteQs; idx++) {
queue_iterate(&queue->sites[idx], site, IOTrackingCallSite *, link)
{
- if (!site->addresses) {
- continue;
- }
- tracking = (IOTrackingAddress *) site->addresses[hashIdx];
+ tracking = (IOTrackingAddress *) site->addresses;
while (!queue_end(&site->instances, &tracking->tracking.link)) {
- nextAddress = (IOTrackingAddress *) queue_next(&tracking->tracking.link);
- if (!queue_end(&site->instances, &nextAddress->tracking.link)
- && (hashIdx != (atop(nextAddress->address) % queue->numSiteQs))) {
- nextAddress = (IOTrackingAddress *) &site->instances;
+ if ((done = (address == tracking->address))) {
+ IOTrackingRemove(queue, &tracking->tracking, size);
+ kfree(tracking, sizeof(IOTrackingAddress));
+ break;
+ } else {
+ tracking = (IOTrackingAddress *) queue_next(&tracking->tracking.link);
}
- if ((done = (address == tracking->address))) {
- if (tracking == (IOTrackingAddress *) site->addresses[hashIdx]) {
- site->addresses[hashIdx] = &nextAddress->tracking;
- }
- IOTrackingRemoveInternal(queue, &tracking->tracking, size, -1U);
- kfree_type(IOTrackingAddress, tracking);
- break;
- }
- tracking = nextAddress;
}
if (done) {
break;
@@ -806,23 +694,6 @@
}
}
IOTRecursiveLockUnlock(&queue->lock);
-}
-
-static void
-IOTrackingFreeCallSite(uint32_t type, IOTrackingCallSite ** pSite)
-{
- IOTrackingCallSite * site;
- void ** ptr;
-
- site = *pSite;
- kfree_type(IOTracking *, site->queue->numSiteQs, site->addresses);
-
- ptr = reinterpret_cast<void **>(pSite);
- if (kIOTrackingQueueTypeUser & type) {
- kfree_type(IOTrackingCallSiteWithUser, *ptr);
- } else {
- kfree_type(IOTrackingCallSite, *ptr);
- }
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -849,7 +720,7 @@
IOTrackingUser * user;
IOTracking * tracking;
IOTrackingAddress * trackingAddress;
- uint32_t idx, hashIdx;
+ uint32_t idx;
bool addresses;
IOTRecursiveLockLock(&queue->lock);
@@ -863,21 +734,17 @@
addresses = false;
while (!queue_empty(&site->instances)) {
queue_remove_first(&site->instances, tracking, IOTracking *, link);
- if (site->addresses) {
- for (hashIdx = 0; !addresses && (hashIdx < queue->numSiteQs); hashIdx++) {
- if (tracking == site->addresses[hashIdx]) {
- addresses = true;
- }
- }
+ if (tracking == site->addresses) {
+ addresses = true;
}
if (addresses) {
trackingAddress = (typeof(trackingAddress))tracking;
if (kTrackingAddressFlagAllocated & IOTrackingAddressFlags(trackingAddress)) {
- kfree_type(IOTrackingAddress, trackingAddress);
+ kfree(tracking, sizeof(IOTrackingAddress));
}
}
}
- IOTrackingFreeCallSite(queue->type, &site);
+ kfree(site, sizeof(IOTrackingCallSite));
}
}
}
@@ -944,7 +811,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
-CopyOutBacktraces(IOTrackingCallSite * site, IOTrackingCallSiteInfo * siteInfo)
+CopyOutKernelBacktrace(IOTrackingCallSite * site, IOTrackingCallSiteInfo * siteInfo)
{
uint32_t j;
mach_vm_address_t bt, btEntry;
@@ -958,22 +825,6 @@
btEntry = 0;
}
siteInfo->bt[0][j] = VM_KERNEL_UNSLIDE(bt);
- }
-
- siteInfo->btPID = 0;
- if (kIOTrackingQueueTypeUser & site->queue->type) {
- siteInfo->btPID = site->user[0].pid;
- uint32_t * bt32 = (typeof(bt32))((void *) &site->user[0].bt[0]);
- uint64_t * bt64 = (typeof(bt64))((void *) &site->user[0].bt[0]);
- for (uint32_t j = 0; j < kIOTrackingCallSiteBTs; j++) {
- if (j >= site->user[0].userCount) {
- siteInfo->bt[1][j] = 0;
- } else if (site->user[0].user32) {
- siteInfo->bt[1][j] = bt32[j];
- } else {
- siteInfo->bt[1][j] = bt64[j];
- }
- }
}
}
@@ -997,21 +848,11 @@
count = ref->count;
size = origsize = ref->zoneSize;
- if (gIOTrackingLeakScanCallback) {
- gIOTrackingLeakScanCallback(kIOTrackingLeakScanStart);
- }
-
for (deadline = 0, vaddr = VM_MIN_KERNEL_AND_KEXT_ADDRESS;
;
vaddr += vincr) {
if ((mach_absolute_time() > deadline) || (vaddr >= VM_MAX_KERNEL_ADDRESS)) {
if (deadline) {
-#if SCHED_HYGIENE_DEBUG
- if (is) {
- // Reset the interrupt timeout to avoid panics
- ml_spin_debug_clear_self();
- }
-#endif /* SCHED_HYGIENE_DEBUG */
ml_set_interrupts_enabled(is);
IODelay(10);
}
@@ -1021,6 +862,7 @@
is = ml_set_interrupts_enabled(false);
clock_interval_to_deadline(10, kMillisecondScale, &deadline);
}
+
ppn = kernel_pmap_present_mapping(vaddr, &vincr, &vphysaddr);
// check noencrypt to avoid VM structs (map entries) with pointers
if (ppn && (!pmap_valid_page(ppn) || (!ref->zoneSize && pmap_is_noencrypt(ppn)))) {
@@ -1030,13 +872,8 @@
continue;
}
- vm_memtag_disable_checking();
for (ptrIdx = 0; ptrIdx < (page_size / sizeof(uintptr_t)); ptrIdx++) {
ptr = ((uintptr_t *)vphysaddr)[ptrIdx];
-#if defined(HAS_APPLE_PAC)
- // strip possible ptrauth signature from candidate data pointer
- ptr = (uintptr_t)ptrauth_strip((void*)ptr, ptrauth_key_process_independent_data);
-#endif /* defined(HAS_APPLE_PAC) */
for (lim = count, baseIdx = 0; lim; lim >>= 1) {
inst = instances[baseIdx + (lim >> 1)];
@@ -1076,12 +913,7 @@
// else move left
}
}
- vm_memtag_enable_checking();
ref->bytes += page_size;
- }
-
- if (gIOTrackingLeakScanCallback) {
- gIOTrackingLeakScanCallback(kIOTrackingLeakScanEnd);
}
}
@@ -1113,6 +945,30 @@
*found = ref.found;
}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static void
+ZoneSiteProc(void * refCon, uint32_t siteCount, uint32_t zoneSize,
+ uintptr_t * backtrace, uint32_t btCount)
+{
+ IOTrackingCallSiteInfo siteInfo;
+ OSData * leakData;
+ uint32_t idx;
+
+ leakData = (typeof(leakData))refCon;
+
+ bzero(&siteInfo, sizeof(siteInfo));
+ siteInfo.count = siteCount;
+ siteInfo.size[0] = zoneSize * siteCount;
+
+ for (idx = 0; (idx < btCount) && (idx < kIOTrackingCallSiteBTs); idx++) {
+ siteInfo.bt[0][idx] = VM_KERNEL_UNSLIDE(backtrace[idx]);
+ }
+
+ leakData->appendBytes(&siteInfo, sizeof(siteInfo));
+}
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1128,11 +984,7 @@
uintptr_t inst;
uint32_t count, idx, numSites, dups, siteCount;
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
instances = (typeof(instances))data->getBytesNoCopy();
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
count = (data->getLength() / sizeof(*instances));
qsort(instances, count, sizeof(*instances), &IOTrackingAddressCompare);
@@ -1149,11 +1001,7 @@
}
}
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
leakData = OSData::withCapacity(128 * sizeof(IOTrackingCallSiteInfo));
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
for (numSites = 0, idx = 0; idx < count; idx++) {
inst = instances[idx];
@@ -1178,16 +1026,11 @@
instances[dups] = 0;
}
}
- // leak byte size is reported as:
- // (total bytes allocated by the callsite * number of leaked instances)
- // divided by (number of allocations by callsite)
siteInfo.count = siteCount;
- siteInfo.size[0] = (site->size[0] * siteCount) / site->count;
- siteInfo.size[1] = (site->size[1] * siteCount) / site->count;
- CopyOutBacktraces(site, &siteInfo);
- __typed_allocators_ignore_push
+ siteInfo.size[0] = (site->size[0] * site->count) / siteCount;
+ siteInfo.size[1] = (site->size[1] * site->count) / siteCount;;
+ CopyOutKernelBacktrace(site, &siteInfo);
leakData->appendBytes(&siteInfo, sizeof(siteInfo));
- __typed_allocators_ignore_pop
}
data->release();
@@ -1265,7 +1108,7 @@
proc = NULL;
if (kIOTrackingGetMappings == selector) {
if (value != -1ULL) {
- proc = proc_find((pid_t) value);
+ proc = proc_find(value);
if (!proc) {
return kIOReturnNotFound;
}
@@ -1314,11 +1157,7 @@
}
if (!data) {
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
data = OSData::withCapacity(1024 * sizeof(uintptr_t));
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
}
IOTRecursiveLockLock(&queue->lock);
@@ -1328,18 +1167,14 @@
addresses = false;
queue_iterate(&site->instances, instance, IOTracking *, link)
{
- if (site->addresses) {
- for (uint32_t hashIdx = 0; !addresses && (hashIdx < queue->numSiteQs); hashIdx++) {
- if (instance == site->addresses[hashIdx]) {
- addresses = true;
- }
- }
+ if (instance == site->addresses) {
+ addresses = true;
}
instFlags = (typeof(instFlags))instance;
if (addresses) {
instFlags |= kInstanceFlagAddress;
}
- data->appendValue(instFlags);
+ data->appendBytes(&instFlags, sizeof(instFlags));
}
}
}
@@ -1356,11 +1191,7 @@
}
if (!data) {
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
data = OSData::withCapacity(128 * sizeof(IOTrackingCallSiteInfo));
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
}
IOTRecursiveLockLock(&queue->lock);
@@ -1388,12 +1219,8 @@
tsize[0] = tsize[1] = 0;
queue_iterate(&site->instances, instance, IOTracking *, link)
{
- if (site->addresses) {
- for (uint32_t hashIdx = 0; !addresses && (hashIdx < queue->numSiteQs); hashIdx++) {
- if (instance == site->addresses[hashIdx]) {
- addresses = true;
- }
- }
+ if (instance == site->addresses) {
+ addresses = true;
}
if (addresses) {
@@ -1430,13 +1257,13 @@
if (size && ((tsize[0] + tsize[1]) < size)) {
continue;
}
+
siteInfo.count = count;
siteInfo.size[0] = tsize[0];
siteInfo.size[1] = tsize[1];
- CopyOutBacktraces(site, &siteInfo);
- __typed_allocators_ignore_push
+
+ CopyOutKernelBacktrace(site, &siteInfo);
data->appendBytes(&siteInfo, sizeof(siteInfo));
- __typed_allocators_ignore_pop
}
}
assert(idx == num);
@@ -1451,7 +1278,7 @@
break;
}
if (!data) {
- data = OSData::withCapacity((unsigned int) page_size);
+ data = OSData::withCapacity(page_size);
}
IOTRecursiveLockLock(&queue->lock);
@@ -1494,9 +1321,7 @@
siteInfo.bt[1][j] = bt64[j];
}
}
- __typed_allocators_ignore_push
data->appendBytes(&siteInfo, sizeof(siteInfo));
- __typed_allocators_ignore_pop
}
}
assert(idx == num);
@@ -1530,36 +1355,22 @@
if ((kIOTrackingLeaks == selector) && namesLen && names) {
const char * scan;
const char * next;
- uint8_t sLen;
+ size_t sLen;
if (!data) {
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
data = OSData::withCapacity(4096 * sizeof(uintptr_t));
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
}
// <len><name>...<len><name><0>
scan = names;
do{
- sLen = ((uint8_t) scan[0]);
+ sLen = scan[0];
scan++;
next = scan + sLen;
if (next >= (names + namesLen)) {
break;
}
- kr = zone_leaks(scan, sLen, ^(uint32_t count, uint32_t eSize, btref_t ref) {
- IOTrackingCallSiteInfo siteInfo = {
- .count = count,
- .size[0] = eSize * count,
- };
-
- btref_decode_unslide(ref, siteInfo.bt[0]);
- __typed_allocators_ignore_push
- data->appendBytes(&siteInfo, sizeof(siteInfo));
- __typed_allocators_ignore_pop
- });
+ kr = zone_leaks(scan, sLen, &ZoneSiteProc, data);
if (KERN_SUCCESS == kr) {
ret = kIOReturnSuccess;
} else if (KERN_INVALID_NAME != kr) {
@@ -1576,11 +1387,7 @@
case kIOTrackingGetMappings:
{
IOTrackingCallSiteInfo * siteInfos;
- /* BEGIN IGNORE CODESTYLE */
- __typed_allocators_ignore_push
siteInfos = (typeof(siteInfos))data->getBytesNoCopy();
- __typed_allocators_ignore_pop
- /* END IGNORE CODESTYLE */
num = (data->getLength() / sizeof(*siteInfos));
qsort(siteInfos, num, sizeof(*siteInfos), &IOTrackingCallSiteInfoCompare);
break;
@@ -1606,15 +1413,14 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#undef super
-#define super IOUserClient2022
-
-OSDefineMetaClassAndStructors(IOKitDiagnosticsClient, IOUserClient2022)
+#define super IOUserClient
+
+OSDefineMetaClassAndStructors(IOKitDiagnosticsClient, IOUserClient)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
IOUserClient * IOKitDiagnosticsClient::withTask(task_t owningTask)
{
-#if IOTRACKING
IOKitDiagnosticsClient * inst;
inst = new IOKitDiagnosticsClient;
@@ -1623,16 +1429,7 @@
inst = NULL;
}
- inst->setProperty(kIOUserClientDefaultLockingKey, kOSBooleanTrue);
- inst->setProperty(kIOUserClientDefaultLockingSetPropertiesKey, kOSBooleanTrue);
- inst->setProperty(kIOUserClientDefaultLockingSingleThreadExternalMethodKey, kOSBooleanTrue);
-
- inst->setProperty(kIOUserClientEntitlementsKey, kOSBooleanFalse);
-
return inst;
-#else
- return NULL;
-#endif
}
IOReturn
@@ -1649,10 +1446,9 @@
return kr;
}
-
IOReturn
-IOTrackingMethodDispatched(OSObject * target, void * reference,
- IOExternalMethodArguments * args)
+IOKitDiagnosticsClient::externalMethod(uint32_t selector, IOExternalMethodArguments * args,
+ IOExternalMethodDispatch * dispatch, OSObject * target, void * reference)
{
IOReturn ret = kIOReturnBadArgument;
const IOKitDiagnosticsParameters * params;
@@ -1674,85 +1470,15 @@
names = (typeof(names))(params + 1);
}
- ret = IOTrackingDebug(args->selector, params->options, params->value, params->tag, params->zsize, names, namesLen, params->size, &result);
+ ret = IOTrackingDebug(selector, params->options, params->value, params->tag, params->zsize, names, namesLen, params->size, &result);
+
if ((kIOReturnSuccess == ret) && args->structureVariableOutputData) {
*args->structureVariableOutputData = result;
} else if (result) {
result->release();
}
+
return ret;
}
-IOReturn
-IOKitDiagnosticsClient::externalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque * args)
-{
- static const IOExternalMethodDispatch2022 dispatchArray[] = {
- [kIOTrackingGetTracking] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingGetMappings] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingResetTracking] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingStartCapture] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingStopCapture] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingSetMinCaptureSize] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- [kIOTrackingLeaks] = {
- .function = &IOTrackingMethodDispatched,
- .checkScalarInputCount = 0,
- .checkStructureInputSize = kIOUCVariableStructureSize,
- .checkScalarOutputCount = 0,
- .checkStructureOutputSize = 0,
- .allowAsync = false,
- .checkEntitlement = NULL,
- },
- };
-
- return dispatchExternalMethod(selector, args, dispatchArray, sizeof(dispatchArray) / sizeof(dispatchArray[0]), this, NULL);
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */