Procházet zdrojové kódy

LibELF: Reorganize TLS-related variables in DynamicLinker.cpp

Sönke Holz před 1 rokem
rodič
revize
8f0ebce404
1 změnil soubory, kde provedl 14 přidání a 10 odebrání
  1. 14 10
      Userland/Libraries/LibELF/DynamicLinker.cpp

+ 14 - 10
Userland/Libraries/LibELF/DynamicLinker.cpp

@@ -52,9 +52,12 @@ using CallFiniFunctionsFunction = void (*)();
 
 
 extern "C" [[noreturn]] void _invoke_entry(int argc, char** argv, char** envp, EntryPointFunction entry);
 extern "C" [[noreturn]] void _invoke_entry(int argc, char** argv, char** envp, EntryPointFunction entry);
 
 
-static size_t s_current_tls_offset = 0;
-static size_t s_total_tls_size = 0;
-static size_t s_allocated_tls_block_size = 0;
+struct TLSData {
+    size_t total_tls_size { 0 };
+    size_t tls_template_size { 0 };
+};
+static TLSData s_tls_data;
+
 static char** s_envp = nullptr;
 static char** s_envp = nullptr;
 static __pthread_mutex_t s_loader_lock = __PTHREAD_MUTEX_INITIALIZER;
 static __pthread_mutex_t s_loader_lock = __PTHREAD_MUTEX_INITIALIZER;
 static ByteString s_cwd;
 static ByteString s_cwd;
@@ -123,6 +126,8 @@ static Result<NonnullRefPtr<DynamicLoader>, DlErrorMessage> map_library(ByteStri
 
 
     s_loaders.set(filepath, *loader);
     s_loaders.set(filepath, *loader);
 
 
+    static size_t s_current_tls_offset = 0;
+
     s_current_tls_offset -= loader->tls_size_of_current_object();
     s_current_tls_offset -= loader->tls_size_of_current_object();
     if (loader->tls_alignment_of_current_object())
     if (loader->tls_alignment_of_current_object())
         s_current_tls_offset = align_down_to(s_current_tls_offset, loader->tls_alignment_of_current_object());
         s_current_tls_offset = align_down_to(s_current_tls_offset, loader->tls_alignment_of_current_object());
@@ -231,16 +236,15 @@ static Result<void, DlErrorMessage> map_dependencies(ByteString const& path)
 
 
 static void allocate_tls()
 static void allocate_tls()
 {
 {
-    s_total_tls_size = 0;
     for (auto const& data : s_loaders) {
     for (auto const& data : s_loaders) {
         dbgln_if(DYNAMIC_LOAD_DEBUG, "{}: TLS Size: {}, TLS Alignment: {}", data.key, data.value->tls_size_of_current_object(), data.value->tls_alignment_of_current_object());
         dbgln_if(DYNAMIC_LOAD_DEBUG, "{}: TLS Size: {}, TLS Alignment: {}", data.key, data.value->tls_size_of_current_object(), data.value->tls_alignment_of_current_object());
-        s_total_tls_size += data.value->tls_size_of_current_object() + data.value->tls_alignment_of_current_object();
+        s_tls_data.total_tls_size += data.value->tls_size_of_current_object() + data.value->tls_alignment_of_current_object();
     }
     }
 
 
-    if (!s_total_tls_size)
+    if (s_tls_data.total_tls_size == 0)
         return;
         return;
 
 
-    auto page_aligned_size = align_up_to(s_total_tls_size, PAGE_SIZE);
+    auto page_aligned_size = align_up_to(s_tls_data.total_tls_size, PAGE_SIZE);
     auto initial_tls_data_result = ByteBuffer::create_zeroed(page_aligned_size);
     auto initial_tls_data_result = ByteBuffer::create_zeroed(page_aligned_size);
     if (initial_tls_data_result.is_error()) {
     if (initial_tls_data_result.is_error()) {
         dbgln("Failed to allocate initial TLS data");
         dbgln("Failed to allocate initial TLS data");
@@ -258,7 +262,7 @@ static void allocate_tls()
     VERIFY(master_tls != (void*)-1);
     VERIFY(master_tls != (void*)-1);
     dbgln_if(DYNAMIC_LOAD_DEBUG, "from userspace, master_tls: {:p}", master_tls);
     dbgln_if(DYNAMIC_LOAD_DEBUG, "from userspace, master_tls: {:p}", master_tls);
 
 
-    s_allocated_tls_block_size = initial_tls_data.size();
+    s_tls_data.tls_template_size = initial_tls_data.size();
 }
 }
 
 
 static int __dl_iterate_phdr(DlIteratePhdrCallbackFunction callback, void* data)
 static int __dl_iterate_phdr(DlIteratePhdrCallbackFunction callback, void* data)
@@ -431,7 +435,7 @@ static Optional<DlErrorMessage> verify_tls_for_dlopen(DynamicLoader const& loade
     if (loader.tls_size_of_current_object() == 0)
     if (loader.tls_size_of_current_object() == 0)
         return {};
         return {};
 
 
-    if (s_total_tls_size + loader.tls_size_of_current_object() + loader.tls_alignment_of_current_object() > s_allocated_tls_block_size)
+    if (s_tls_data.total_tls_size + loader.tls_size_of_current_object() + loader.tls_alignment_of_current_object() > s_tls_data.tls_template_size)
         return DlErrorMessage("TLS size too large");
         return DlErrorMessage("TLS size too large");
 
 
     bool tls_data_is_all_zero = true;
     bool tls_data_is_all_zero = true;
@@ -492,7 +496,7 @@ static Result<void*, DlErrorMessage> __dlopen(char const* filename, int flags)
 
 
     TRY(link_main_library(loader->filepath(), flags));
     TRY(link_main_library(loader->filepath(), flags));
 
 
-    s_total_tls_size += loader->tls_size_of_current_object() + loader->tls_alignment_of_current_object();
+    s_tls_data.total_tls_size += loader->tls_size_of_current_object() + loader->tls_alignment_of_current_object();
 
 
     auto object = s_global_objects.get(library_path.value());
     auto object = s_global_objects.get(library_path.value());
     if (!object.has_value())
     if (!object.has_value())