Loading...
src/threadLocalVariables.c dyld-421.1 dyld-195.5
--- dyld/dyld-421.1/src/threadLocalVariables.c
+++ dyld/dyld-195.5/src/threadLocalVariables.c
@@ -73,12 +73,7 @@
 	#define MH_HAS_TLV_DESCRIPTORS 0x800000
 #endif
 
-
-typedef void (*TermFunc)(void*);
-
-
-
-#if __has_feature(tls) || __arm64__ || __arm__
+#if __i386__ || __x86_64__
 
 typedef struct TLVHandler {
 	struct TLVHandler *next;
@@ -170,12 +165,9 @@
 void* tlv_allocate_and_initialize_for_key(pthread_key_t key)
 {
 	const struct mach_header* mh = tlv_get_image_for_key(key);
-	if ( mh == NULL )
-		return NULL;	// if data structures are screwed up, don't crash
-	
 	// first pass, find size and template
 	uint8_t*		start = NULL;
-	unsigned long	size = 0;
+	unsigned long	size;
 	intptr_t		slide = 0;
 	bool			slideComputed = false;
 	bool			hasInitializers = false;
@@ -237,9 +229,9 @@
 					if ( (sect->flags & SECTION_TYPE) == S_THREAD_LOCAL_INIT_FUNCTION_POINTERS ) {
 						typedef void (*InitFunc)(void);
 						InitFunc* funcs = (InitFunc*)(sect->addr + slide);
-						const size_t count = sect->size / sizeof(uintptr_t);
-						for (size_t j=count; j > 0; --j) {
-							InitFunc func = funcs[j-1];
+						const uint32_t count = sect->size / sizeof(uintptr_t);
+						for (uint32_t i=count; i > 0; --i) {
+							InitFunc func = funcs[i-1];
 							func();
 						}
 					}
@@ -305,13 +297,17 @@
 	}
 }
 
-
-void tlv_load_notification(const struct mach_header* mh, intptr_t slide)
-{
-	// This is called on all images, even those without TLVs. So we want this to be fast.
-	// The linker sets MH_HAS_TLV_DESCRIPTORS so we don't have to search images just to find the don't have TLVs.
-	if ( mh->flags & MH_HAS_TLV_DESCRIPTORS )
-		tlv_initialize_descriptors(mh);
+// called by dyld when a image is loaded
+static const char* tlv_load_notification(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[])
+{
+	// this is called on all images, even those without TLVs, so we want
+	// this to be fast.  The linker sets MH_HAS_TLV_DESCRIPTORS so we don't
+	// have to search images just to find the don't have TLVs.
+	for (uint32_t i=0; i < infoCount; ++i) {
+		if ( info[i].imageLoadAddress->flags & MH_HAS_TLV_DESCRIPTORS )
+			tlv_initialize_descriptors(info[i].imageLoadAddress);
+	}
+	return NULL;
 }
 
 
@@ -364,6 +360,7 @@
 // destructor key to come before the deallocation key.
 //
 
+typedef void (*TermFunc)(void*);
 struct TLVTerminatorListEntry
 {
     TermFunc    termFunc;
@@ -397,7 +394,7 @@
         if ( list->allocCount == list->allocCount ) {
             // handle resizing allocation 
             uint32_t newAllocCount = list->allocCount * 2;
-            size_t newAllocSize = offsetof(struct TLVTerminatorList, entries[newAllocCount]);
+            uint32_t newAllocSize = offsetof(struct TLVTerminatorList, entries[newAllocCount]);
             struct TLVTerminatorList* newlist = (struct TLVTerminatorList*)malloc(newAllocSize);
             newlist->allocCount = newAllocCount;
             newlist->useCount = list->useCount;
@@ -414,29 +411,18 @@
     }
 }
 
-// called by pthreads when the current thread is going away and 
+// called by pthreads when the current thread is going way and 
 // _tlv_atexit() has been called on the thread.
 static void tlv_finalize(void* storage)
 {
     struct TLVTerminatorList* list = (struct TLVTerminatorList*)storage;
-    // destroy in reverse order of construction
-    for(uint32_t i=list->useCount; i > 0 ; --i) {
-        struct TLVTerminatorListEntry* entry = &list->entries[i-1];
+    for(uint32_t i=0; i < list->useCount; ++i) {
+        struct TLVTerminatorListEntry* entry = &list->entries[i];
         if ( entry->termFunc != NULL ) {
             (*entry->termFunc)(entry->objAddr);
         }
     }
     free(storage);
-}
-
-// <rdar://problem/13741816>
-// called by exit() before it calls cxa_finalize() so that thread_local
-// objects are destroyed before global objects.
-void _tlv_exit()
-{
-	void* termFuncs = pthread_getspecific(tlv_terminators_key);
-	if ( termFuncs != NULL )
-		tlv_finalize(termFuncs);
 }
 
 
@@ -449,8 +435,7 @@
     (void)pthread_key_create(&tlv_terminators_key, &tlv_finalize);
        
     // register with dyld for notification when images are loaded
-	_dyld_register_func_for_add_image(tlv_load_notification);
-
+    dyld_register_image_state_change_handler(dyld_image_state_bound, true, tlv_load_notification);
 }
 
 
@@ -461,9 +446,9 @@
 }
 
 
-
+// __i386__ || __x86_64__
 #else
-
+// !(__i386__ || __x86_64__)
 
 
 void dyld_register_tlv_state_change_handler(enum dyld_tlv_states state, dyld_tlv_state_change_handler handler)
@@ -471,14 +456,6 @@
 }
 
 void dyld_enumerate_tlv_storage(dyld_tlv_state_change_handler handler)
-{
-}
-
-void _tlv_exit()
-{
-}
-
-void _tlv_atexit(TermFunc func, void* objAddr)
 {
 }
 
@@ -488,7 +465,7 @@
 }
 
 
-
-#endif // __has_feature(tls)
-
-
+// !(__i386__ || __x86_64__)
+#endif
+
+