]> git.saurik.com Git - apple/dyld.git/blobdiff - src/threadLocalVariables.c
dyld-635.2.tar.gz
[apple/dyld.git] / src / threadLocalVariables.c
index b5fcd6d7815505b2d2bbdef34bcf6275b4b6dac0..a0b36615ab08c37f9987566bcdd91107bec0ab9a 100644 (file)
@@ -78,7 +78,7 @@ typedef void (*TermFunc)(void*);
 
 
 
-#if __has_feature(tls)
+#if __has_feature(tls) || __arm64__ || __arm__
 
 typedef struct TLVHandler {
        struct TLVHandler *next;
@@ -214,6 +214,9 @@ void* tlv_allocate_and_initialize_for_key(pthread_key_t key)
                }
                cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
        }
+    // no thread local storage in image: should never happen
+    if ( size == 0 )
+        return NULL;
        
        // allocate buffer and fill with template
        void* buffer = malloc(size);
@@ -237,9 +240,9 @@ void* tlv_allocate_and_initialize_for_key(pthread_key_t key)
                                        if ( (sect->flags & SECTION_TYPE) == S_THREAD_LOCAL_INIT_FUNCTION_POINTERS ) {
                                                typedef void (*InitFunc)(void);
                                                InitFunc* funcs = (InitFunc*)(sect->addr + slide);
-                                               const uint32_t count = sect->size / sizeof(uintptr_t);
-                                               for (uint32_t i=count; i > 0; --i) {
-                                                       InitFunc func = funcs[i-1];
+                                               const size_t count = sect->size / sizeof(uintptr_t);
+                                               for (size_t j=count; j > 0; --j) {
+                                                       InitFunc func = funcs[j-1];
                                                        func();
                                                }
                                        }
@@ -305,17 +308,13 @@ static void tlv_initialize_descriptors(const struct mach_header* 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[])
+
+static 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.
-       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;
+       // 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);
 }
 
 
@@ -398,10 +397,10 @@ void _tlv_atexit(TermFunc func, void* objAddr)
         pthread_setspecific(tlv_terminators_key, list);
     }
     else {
-        if ( list->allocCount == list->allocCount ) {
+        if ( list->useCount == list->allocCount ) {
             // handle resizing allocation 
             uint32_t newAllocCount = list->allocCount * 2;
-            uint32_t newAllocSize = offsetof(struct TLVTerminatorList, entries[newAllocCount]);
+            size_t newAllocSize = offsetof(struct TLVTerminatorList, entries[newAllocCount]);
             struct TLVTerminatorList* newlist = (struct TLVTerminatorList*)malloc(newAllocSize);
             newlist->allocCount = newAllocCount;
             newlist->useCount = list->useCount;
@@ -453,7 +452,8 @@ void tlv_initializer()
     (void)pthread_key_create(&tlv_terminators_key, &tlv_finalize);
        
     // register with dyld for notification when images are loaded
-    dyld_register_image_state_change_handler(dyld_image_state_bound, true, tlv_load_notification);
+       _dyld_register_func_for_add_image(tlv_load_notification);
+
 }