Loading...
libkern/c++/OSObject.cpp xnu-7195.141.2 xnu-8792.61.2
--- xnu/xnu-7195.141.2/libkern/c++/OSObject.cpp
+++ xnu/xnu-8792.61.2/libkern/c++/OSObject.cpp
@@ -280,6 +280,17 @@
 	return ok;
 }
 
+/*
+ * Ignore -Wxnu-typed-allocators for the operator new/delete implementations
+ */
+__typed_allocators_ignore_push
+
+/*
+ * Given that all OSObjects have been transitioned to use
+ * OSObject_typed_operator_new/OSObject_typed_operator_delete, this should
+ * only be called from kexts that havent recompiled to use the new
+ * definitions.
+ */
 void *
 OSObject::operator new(size_t size)
 {
@@ -289,14 +300,49 @@
 	}
 #endif
 
-	void *mem = kheap_alloc_tag_bt(KHEAP_DEFAULT, size,
-	    (zalloc_flags_t) (Z_WAITOK | Z_ZERO), VM_KERN_MEMORY_LIBKERN);
+	void *mem = kheap_alloc(KHEAP_DEFAULT, size,
+	    Z_VM_TAG_BT(Z_WAITOK_ZERO, VM_KERN_MEMORY_LIBKERN));
 	assert(mem);
 	OSIVAR_ACCUMSIZE(size);
 
 	return (void *) mem;
 }
 
+void *
+OSObject_typed_operator_new(kalloc_type_view_t ktv, vm_size_t size)
+{
+#if IOTRACKING
+	if (kIOTracking & gIOKitDebug) {
+		return OSMetaClass::trackedNew(size);
+	}
+#endif
+
+	/*
+	 * Some classes in kexts that subclass from iokit classes
+	 * don't use OSDeclare/OSDefine to declare/define structors.
+	 * When operator new is called on such objects they end up
+	 * using the parent's operator new/delete. If we detect such
+	 * a case we default to using kalloc rather than kalloc_type
+	 */
+	void *mem = NULL;
+	if (size <= kalloc_type_get_size(ktv->kt_size)) {
+		/*
+		 * OSObject_typed_operator_new can be called from kexts,
+		 * use the external symbol for kalloc_type_impl as
+		 * kalloc_type_views generated at some external callsites
+		 * many not have been processed during boot.
+		 */
+		mem = kalloc_type_impl_external(ktv, Z_WAITOK_ZERO);
+	} else {
+		mem = kheap_alloc(KHEAP_DEFAULT, size,
+		    Z_VM_TAG_BT(Z_WAITOK_ZERO, VM_KERN_MEMORY_LIBKERN));
+	}
+	assert(mem);
+	OSIVAR_ACCUMSIZE(size);
+
+	return (void *) mem;
+}
+
 void
 OSObject::operator delete(void * mem, size_t size)
 {
@@ -310,32 +356,13 @@
 	}
 #endif
 
-	kern_os_kfree(mem, size);
+	kheap_free(KHEAP_DEFAULT, mem, size);
 	OSIVAR_ACCUMSIZE(-size);
 }
 
-__BEGIN_DECLS
-void *OSObject_operator_new_external(size_t size);
-void *
-OSObject_operator_new_external(size_t size)
-{
-  #if IOTRACKING
-	if (kIOTracking & gIOKitDebug) {
-		return OSMetaClass::trackedNew(size);
-	}
-#endif
-
-	void * mem = kheap_alloc_tag_bt(KHEAP_KEXT, size,
-	    (zalloc_flags_t) (Z_WAITOK | Z_ZERO), VM_KERN_MEMORY_LIBKERN);
-	assert(mem);
-	OSIVAR_ACCUMSIZE(size);
-
-	return (void *) mem;
-}
-
-void OSObject_operator_delete_external(void * mem, size_t size);
-void
-OSObject_operator_delete_external(void * mem, size_t size)
+void
+OSObject_typed_operator_delete(kalloc_type_view_t ktv, void * mem,
+    vm_size_t size)
 {
 	if (!mem) {
 		return;
@@ -347,10 +374,16 @@
 	}
 #endif
 
-	kheap_free(KHEAP_KEXT, mem, size);
+	if (size <= kalloc_type_get_size(ktv->kt_size)) {
+		kern_os_typed_free(ktv, mem, size);
+	} else {
+		kheap_free(KHEAP_DEFAULT, mem, size);
+	}
 	OSIVAR_ACCUMSIZE(-size);
 }
-__END_DECLS
+
+__typed_allocators_ignore_pop
+
 bool
 OSObject::init()
 {