Loading...
--- 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()
{