Loading...
--- 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