loader: make thirdparty code use allocation callbacks

Use TLS to keep instance pointer and use this for cJSON alloc/free
callback.
diff --git a/loader/dirent_on_windows.c b/loader/dirent_on_windows.c
index 3564a26..5efec82 100644
--- a/loader/dirent_on_windows.c
+++ b/loader/dirent_on_windows.c
@@ -13,7 +13,7 @@
 #include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
 #include <stdlib.h>
 #include <string.h>
-
+#include "loader.h"
 #ifdef __cplusplus
 extern "C"
 {
@@ -39,8 +39,8 @@
         const char *all = /* search pattern must end with suitable wildcard */
             strchr("/\\", name[base_length - 1]) ? "*" : "/*";
 
-        if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
-           (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
+        if((dir = (DIR *) loader_tls_heap_alloc(sizeof *dir)) != 0 &&
+           (dir->name = (char *) loader_tls_heap_alloc(base_length + strlen(all) + 1)) != 0)
         {
             strcat(strcpy(dir->name, name), all);
 
@@ -51,14 +51,14 @@
             }
             else /* rollback */
             {
-                free(dir->name);
-                free(dir);
+                loader_tls_heap_free(dir->name);
+                loader_tls_heap_free(dir);
                 dir = 0;
             }
         }
         else /* rollback */
         {
-            free(dir);
+            loader_tls_heap_free(dir);
             dir   = 0;
             errno = ENOMEM;
         }
diff --git a/loader/loader.c b/loader/loader.c
index f509f31..13e3d02 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -58,6 +58,8 @@
         struct loader_layer_properties *layer_prop);
 
 struct loader_struct loader = {0};
+// TLS for instance for alloc/free callbacks
+THREAD_LOCAL_DECL struct loader_instance *tls_instance;
 
 static PFN_vkVoidFunction VKAPI loader_GetInstanceProcAddr(
         VkInstance instance,
@@ -173,6 +175,16 @@
     return realloc(pMem, size);
 }
 
+void *loader_tls_heap_alloc(size_t size)
+{
+    return loader_heap_alloc(tls_instance, size, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+}
+
+void loader_tls_heap_free(void *pMem)
+{
+    return loader_heap_free(tls_instance, pMem);
+}
+
 static void loader_log(VkFlags msg_type, int32_t msg_code,
     const char *format, ...)
 {
@@ -1172,6 +1184,13 @@
 
     // initialize logging
     loader_debug_init();
+
+    // initial cJSON to use alloc callbacks
+    cJSON_Hooks alloc_fns = {
+        .malloc_fn = loader_tls_heap_alloc,
+        .free_fn = loader_tls_heap_free,
+    };
+    cJSON_InitHooks(&alloc_fns);
 }
 
 struct loader_manifest_files {
@@ -1384,7 +1403,7 @@
                filename, file_vers);
     if (strcmp(file_vers, "\"0.9.0\"") != 0)
         loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 0.9.0), may cause errors");
-    free(file_vers);
+    loader_tls_heap_free(file_vers);
 
     layer_node = cJSON_GetObjectItem(json, "layer");
     if (layer_node == NULL) {
@@ -1411,7 +1430,7 @@
         temp[strlen(temp) - 1] = '\0';                \
         var = loader_stack_alloc(strlen(temp) + 1);   \
         strcpy(var, &temp[1]);                        \
-        free(temp);                                   \
+        loader_tls_heap_free(temp);                   \
         }
         GET_JSON_ITEM(layer_node, name)
         GET_JSON_ITEM(layer_node, type)
@@ -1504,7 +1523,7 @@
         temp[strlen(temp) - 1] = '\0';                \
         var = loader_stack_alloc(strlen(temp) + 1);   \
         strcpy(var, &temp[1]);                        \
-        free(temp);                                   \
+        loader_tls_heap_free(temp);                   \
         }
 
         cJSON *instance_extensions, *device_extensions, *functions, *enable_environment;
@@ -1798,7 +1817,7 @@
                    file_str, file_vers);
         if (strcmp(file_vers, "\"1.0.0\"") != 0)
             loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 1.0.0), may cause errors");
-        free(file_vers);
+        loader_tls_heap_free(file_vers);
         item = cJSON_GetObjectItem(json, "ICD");
         if (item != NULL) {
             item = cJSON_GetObjectItem(item, "library_path");
@@ -1806,7 +1825,7 @@
                 char *temp= cJSON_Print(item);
                 if (!temp || strlen(temp) == 0) {
                     loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str);
-                    free(temp);
+                    loader_tls_heap_free(temp);
                     loader_heap_free(inst, file_str);
                     cJSON_Delete(json);
                     continue;
@@ -1815,7 +1834,7 @@
                 temp[strlen(temp) - 1] = '\0';
                 char *library_path = loader_stack_alloc(strlen(temp) + 1);
                 strcpy(library_path, &temp[1]);
-                free(temp);
+                loader_tls_heap_free(temp);
                 if (!library_path || strlen(library_path) == 0) {
                     loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str);
                     loader_heap_free(inst, file_str);
@@ -3075,6 +3094,7 @@
     struct loader_icd_libs icd_libs;
     uint32_t copy_size;
 
+    tls_instance = NULL;
     if (pCount == NULL) {
         return VK_ERROR_INVALID_POINTER;
     }
@@ -3141,6 +3161,7 @@
 {
 
     struct loader_layer_list instance_layer_list;
+    tls_instance = NULL;
 
     loader_platform_thread_once(&once_init, loader_initialize);
 
diff --git a/loader/loader.h b/loader/loader.h
index 60b38c8..d719640 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -242,6 +242,7 @@
 
 /* global variables used across files */
 extern struct loader_struct loader;
+extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
 extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
 extern loader_platform_thread_mutex loader_lock;
 extern const VkLayerInstanceDispatchTable instance_disp;
@@ -406,4 +407,8 @@
 void loader_heap_free(
         const struct loader_instance *instance,
         void                         *pMem);
+
+void *loader_tls_heap_alloc(size_t size);
+
+void loader_tls_heap_free(void *pMem);
 #endif /* LOADER_H */
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 5d14104..f2926b7 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -63,6 +63,7 @@
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
 
+    tls_instance = ptr_instance;
     loader_platform_thread_lock_mutex(&loader_lock);
     memset(ptr_instance, 0, sizeof(struct loader_instance));
 
@@ -195,7 +196,6 @@
     loader_deactivate_instance_layers(ptr_instance);
     loader_heap_free(ptr_instance, ptr_instance->disp);
     loader_heap_free(ptr_instance, ptr_instance);
-
     loader_platform_thread_unlock_mutex(&loader_lock);
 
     return res;
diff --git a/loader/vk_loader_platform.h b/loader/vk_loader_platform.h
index 9207154..5001fe9 100644
--- a/loader/vk_loader_platform.h
+++ b/loader/vk_loader_platform.h
@@ -149,6 +149,7 @@
 
 // Threads:
 typedef pthread_t loader_platform_thread;
+#define THREAD_LOCAL_DECL __thread
 #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
     pthread_once_t var = PTHREAD_ONCE_INIT;
 #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \
@@ -333,6 +334,7 @@
 
 // Threads:
 typedef HANDLE loader_platform_thread;
+#define THREAD_LOCAL_DECL __declspec(thread)
 #define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) \
     INIT_ONCE var = INIT_ONCE_STATIC_INIT;
 #define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) \