Loading...
libkern/libclosure/runtime.cpp xnu-12377.101.15 xnu-6153.41.3
--- xnu/xnu-12377.101.15/libkern/libclosure/runtime.cpp
+++ xnu/xnu-6153.41.3/libkern/libclosure/runtime.cpp
@@ -15,45 +15,14 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <os/assumes.h>
-#include <TargetConditionals.h>
 
 #else /* !KERNEL */
-#define TARGET_OS_WIN32 0
 
 #include <libkern/Block_private.h>
-__BEGIN_DECLS
-#include <kern/kalloc.h>
-__END_DECLS
-
-/* void * is a bit of a lie, but that will have to do */
-KALLOC_TYPE_VAR_DEFINE(KT_BLOCK_LAYOUT, struct Block_layout, void *, KT_DEFAULT);
-KALLOC_TYPE_VAR_DEFINE(KT_BLOCK_BYREF, struct Block_byref, void *, KT_DEFAULT);
-
-static inline struct Block_layout *
-block_layout_alloc(size_t size)
-{
-	return (struct Block_layout *)kalloc_type_var_impl(KT_BLOCK_LAYOUT,
-	           size, Z_WAITOK_ZERO_NOFAIL, NULL);
-}
-
-static inline void
-block_layout_free(Block_layout *ptr, size_t size)
-{
-	kfree_type_var_impl(KT_BLOCK_LAYOUT, ptr, size);
-}
-
-static inline struct Block_byref *
-block_byref_alloc(size_t size)
-{
-	return (struct Block_byref *)kalloc_type_var_impl(KT_BLOCK_BYREF,
-	           size, Z_WAITOK_ZERO_NOFAIL, NULL);
-}
-
-static inline void
-block_byref_free(Block_byref *ptr, size_t size)
-{
-	kfree_type_var_impl(KT_BLOCK_BYREF, ptr, size);
-}
+#include <libkern/OSRuntime.h>
+
+#define malloc(s)  kern_os_malloc((s))
+#define free(a)    kern_os_free((a))
 
 #endif /* KERNEL */
 
@@ -161,23 +130,6 @@
 #if !TARGET_OS_WIN32
 #pragma mark Framework Callback Routines
 #endif
-#if KERNEL
-static inline void
-_Block_retain_object(const void *ptr __unused)
-{
-}
-
-static inline void
-_Block_release_object(const void *ptr __unused)
-{
-}
-
-static inline void
-_Block_destructInstance(const void *aBlock __unused)
-{
-}
-
-#else
 
 static void
 _Block_retain_object_default(const void *ptr __unused)
@@ -210,42 +162,36 @@
 	_Block_release_object = callbacks->release;
 	_Block_destructInstance = callbacks->destructInstance;
 }
-#endif // !KERNEL
 
 /****************************************************************************
  *  Accessors for block descriptor fields
  *****************************************************************************/
-
-#if BLOCK_SMALL_DESCRIPTOR_SUPPORTED
-template <class T>
-static T *
-unwrap_relative_pointer(int32_t &offset)
-{
-	if (offset == 0) {
-		return nullptr;
-	}
-
-	uintptr_t base = (uintptr_t)&offset;
-	uintptr_t extendedOffset = (uintptr_t)(intptr_t)offset;
-	uintptr_t pointer = base + extendedOffset;
-	return (T *)pointer;
-}
-#endif
-
 #if 0
+static struct Block_descriptor_1 *
+_Block_descriptor_1(struct Block_layout *aBlock)
+{
+	return aBlock->descriptor;
+}
+#endif
+
 static struct Block_descriptor_2 *
 _Block_descriptor_2(struct Block_layout *aBlock)
 {
-	uint8_t *desc = (uint8_t *)_Block_get_descriptor(aBlock);
+	if (!(aBlock->flags & BLOCK_HAS_COPY_DISPOSE)) {
+		return NULL;
+	}
+	uint8_t *desc = (uint8_t *)aBlock->descriptor;
 	desc += sizeof(struct Block_descriptor_1);
 	return __IGNORE_WCASTALIGN((struct Block_descriptor_2 *)desc);
 }
-#endif
 
 static struct Block_descriptor_3 *
 _Block_descriptor_3(struct Block_layout *aBlock)
 {
-	uint8_t *desc = (uint8_t *)_Block_get_descriptor(aBlock);
+	if (!(aBlock->flags & BLOCK_HAS_SIGNATURE)) {
+		return NULL;
+	}
+	uint8_t *desc = (uint8_t *)aBlock->descriptor;
 	desc += sizeof(struct Block_descriptor_1);
 	if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE) {
 		desc += sizeof(struct Block_descriptor_2);
@@ -256,17 +202,23 @@
 static void
 _Block_call_copy_helper(void *result, struct Block_layout *aBlock)
 {
-	if (auto *pFn = _Block_get_copy_function(aBlock)) {
-		pFn(result, aBlock);
-	}
+	struct Block_descriptor_2 *desc = _Block_descriptor_2(aBlock);
+	if (!desc) {
+		return;
+	}
+
+	(*desc->copy)(result, aBlock); // do fixup
 }
 
 static void
 _Block_call_dispose_helper(struct Block_layout *aBlock)
 {
-	if (auto *pFn = _Block_get_dispose_function(aBlock)) {
-		pFn(aBlock);
-	}
+	struct Block_descriptor_2 *desc = _Block_descriptor_2(aBlock);
+	if (!desc) {
+		return;
+	}
+
+	(*desc->dispose)(aBlock);
 }
 
 /*******************************************************************************
@@ -297,27 +249,15 @@
 		return aBlock;
 	} else {
 		// Its a stack block.  Make a copy.
-		size_t size = Block_size(aBlock);
-		struct Block_layout *result = block_layout_alloc(size);
-		memmove(result, aBlock, size); // bitcopy first
+		struct Block_layout *result = (typeof(result))malloc(aBlock->descriptor->size);
+		if (!result) {
+			return NULL;
+		}
+		memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
 #if __has_feature(ptrauth_calls)
 		// Resign the invoke pointer as it uses address authentication.
 		result->invoke = aBlock->invoke;
-
-#if __has_feature(ptrauth_signed_block_descriptors)
-		uintptr_t oldDesc =
-		    ptrauth_blend_discriminator(
-			&aBlock->descriptor, _Block_descriptor_ptrauth_discriminator);
-		uintptr_t newDesc =
-		    ptrauth_blend_discriminator(
-			&result->descriptor, _Block_descriptor_ptrauth_discriminator);
-
-		result->descriptor =
-		    ptrauth_auth_and_resign(aBlock->descriptor, ptrauth_key_asda, oldDesc,
-		    ptrauth_key_asda, newDesc);
-#endif
-#endif
-
+#endif
 		// reset refcount
 		result->flags &= ~(BLOCK_REFCOUNT_MASK | BLOCK_DEALLOCATING); // XXX not needed
 		result->flags |= BLOCK_NEEDS_FREE | 2; // logical refcount 1
@@ -342,7 +282,7 @@
 
 	if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {
 		// src points to stack
-		struct Block_byref *copy = block_byref_alloc(src->size);
+		struct Block_byref *copy = (struct Block_byref *)malloc(src->size);
 		copy->isa = NULL;
 		// byref value 4 is logical refcount of 2: one for caller, one for stack
 		copy->flags = src->flags | BLOCK_BYREF_NEEDS_FREE | 4;
@@ -395,7 +335,7 @@
 				struct Block_byref_2 *byref2 = (struct Block_byref_2 *)(byref + 1);
 				(*byref2->byref_destroy)(byref);
 			}
-			block_byref_free(byref, byref->size);
+			free(byref);
 		}
 	}
 }
@@ -431,7 +371,7 @@
 	if (latching_decr_int_should_deallocate(&aBlock->flags)) {
 		_Block_call_dispose_helper(aBlock);
 		_Block_destructInstance(aBlock);
-		block_layout_free(aBlock, Block_size(aBlock));
+		free(aBlock);
 	}
 }
 
@@ -459,14 +399,7 @@
 size_t
 Block_size(void *aBlock)
 {
-	auto *layout = (Block_layout *)aBlock;
-	void *desc = _Block_get_descriptor(layout);
-#if BLOCK_SMALL_DESCRIPTOR_SUPPORTED
-	if (layout->flags & BLOCK_SMALL_DESCRIPTOR) {
-		return ((Block_descriptor_small *)desc)->size;
-	}
-#endif
-	return ((Block_descriptor_1 *)desc)->size;
+	return ((struct Block_layout *)aBlock)->descriptor->size;
 }
 
 bool
@@ -488,19 +421,11 @@
 const char *
 _Block_signature(void *aBlock)
 {
-	struct Block_layout *layout = (struct Block_layout *)aBlock;
-	if (!(layout->flags & BLOCK_HAS_SIGNATURE)) {
-		return nullptr;
-	}
-
-#if BLOCK_SMALL_DESCRIPTOR_SUPPORTED
-	if (layout->flags & BLOCK_SMALL_DESCRIPTOR) {
-		auto *bds = (Block_descriptor_small *)_Block_get_descriptor(layout);
-		return unwrap_relative_pointer<const char>(bds->signature);
-	}
-#endif
-
-	struct Block_descriptor_3 *desc3 = _Block_descriptor_3(layout);
+	struct Block_descriptor_3 *desc3 = _Block_descriptor_3((struct Block_layout *)aBlock);
+	if (!desc3) {
+		return NULL;
+	}
+
 	return desc3->signature;
 }
 
@@ -508,55 +433,40 @@
 _Block_layout(void *aBlock)
 {
 	// Don't return extended layout to callers expecting old GC layout
-	Block_layout *layout = (Block_layout *)aBlock;
-	if ((layout->flags & BLOCK_HAS_EXTENDED_LAYOUT) ||
-	    !(layout->flags & BLOCK_HAS_SIGNATURE)) {
-		return nullptr;
-	}
-
-#if BLOCK_SMALL_DESCRIPTOR_SUPPORTED
-	if (layout->flags & BLOCK_SMALL_DESCRIPTOR) {
-		auto *bds = (Block_descriptor_small *)_Block_get_descriptor(layout);
-		return unwrap_relative_pointer<const char>(bds->layout);
-	}
-#endif
-
-	Block_descriptor_3 *desc = _Block_descriptor_3(layout);
-	return desc->layout;
+	struct Block_layout *layout = (struct Block_layout *)aBlock;
+	if (layout->flags & BLOCK_HAS_EXTENDED_LAYOUT) {
+		return NULL;
+	}
+
+	struct Block_descriptor_3 *desc3 = _Block_descriptor_3((struct Block_layout *)aBlock);
+	if (!desc3) {
+		return NULL;
+	}
+
+	return desc3->layout;
 }
 
 const char *
 _Block_extended_layout(void *aBlock)
 {
 	// Don't return old GC layout to callers expecting extended layout
-	Block_layout *layout = (Block_layout *)aBlock;
-	if (!(layout->flags & BLOCK_HAS_EXTENDED_LAYOUT) ||
-	    !(layout->flags & BLOCK_HAS_SIGNATURE)) {
-		return nullptr;
-	}
-
-	const char *extLayout;
-#if BLOCK_SMALL_DESCRIPTOR_SUPPORTED
-	if (layout->flags & BLOCK_SMALL_DESCRIPTOR) {
-		auto *bds = (Block_descriptor_small *)_Block_get_descriptor(layout);
-		if (layout->flags & BLOCK_INLINE_LAYOUT_STRING) {
-			extLayout = (const char *)(uintptr_t)bds->layout;
-		} else {
-			extLayout = unwrap_relative_pointer<const char>(bds->layout);
-		}
-	} else
-#endif
-	{
-		Block_descriptor_3 *desc3 = _Block_descriptor_3(layout);
-		extLayout = desc3->layout;
+	struct Block_layout *layout = (struct Block_layout *)aBlock;
+	if (!(layout->flags & BLOCK_HAS_EXTENDED_LAYOUT)) {
+		return NULL;
+	}
+
+	struct Block_descriptor_3 *desc3 = _Block_descriptor_3((struct Block_layout *)aBlock);
+	if (!desc3) {
+		return NULL;
 	}
 
 	// Return empty string (all non-object bytes) instead of NULL
 	// so callers can distinguish "empty layout" from "no layout".
-	if (!extLayout) {
-		extLayout = "";
-	}
-	return extLayout;
+	if (!desc3->layout) {
+		return "";
+	} else {
+		return desc3->layout;
+	}
 }
 
 #if !TARGET_OS_WIN32
@@ -702,3 +612,6 @@
 // Workaround for <rdar://26015603> dylib with no __DATA segment fails to rebase
 __attribute__((used))
 static int let_there_be_data = 42;
+
+#undef malloc
+#undef free