[Lldb-commits] [lldb] [lldb][Windows] Support TLS variables with PDB (PR #229894)

via lldb-commits lldb-commits at lists.llvm.org
Sun Oct 11 13:10:38 PDT 2026


https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/229894

>From 0462222d7b2dfadab35963a7ca097e53ae887ab4 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 7 Oct 2026 22:03:18 +0200
Subject: [PATCH 1/4] [lldb][Windows] Support TLS variables with PDB

---
 .../Windows-DYLD/DynamicLoaderWindowsDYLD.cpp | 93 +++++++++++++++++++
 .../Windows-DYLD/DynamicLoaderWindowsDYLD.h   |  4 +
 lldb/test/API/lang/c/tls_globals/Makefile     |  9 +-
 .../API/lang/c/tls_globals/TestTlsGlobals.py  | 23 +++--
 lldb/test/API/lang/c/tls_globals/a.c          | 15 +--
 lldb/test/API/lang/c/tls_globals/main.c       | 63 ++++++++-----
 6 files changed, 168 insertions(+), 39 deletions(-)

diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index fb0619364dcb9..1ef91456445cd 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -247,3 +247,96 @@ DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
   return ThreadPlanSP(new ThreadPlanStepInstruction(
       thread, false, false, eVoteNoOpinion, eVoteNoOpinion));
 }
+
+lldb::addr_t
+DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
+                                             lldb::ThreadSP thread,
+                                             lldb::addr_t tls_file_addr) {
+  Log *log = GetLog(LLDBLog::DynamicLoader);
+  std::string object_name;
+  if (log) {
+    ObjectFile *obj = module->GetObjectFile();
+    if (obj)
+      object_name = obj->GetObjectName();
+  }
+
+  StructuredData::ObjectSP extended_info = thread->GetExtendedInfo();
+  if (!extended_info) {
+    LLDB_LOG(log, "missing extended info of thread");
+    return LLDB_INVALID_ADDRESS;
+  }
+  StructuredData::Dictionary *dict = extended_info->GetAsDictionary();
+  if (!dict) {
+    LLDB_LOG(log, "extended info of thread is not a dictionary");
+    return LLDB_INVALID_ADDRESS;
+  }
+  addr_t teb_base = 0;
+  if (!dict->GetValueForKeyAsInteger("teb_address", teb_base) || !teb_base ||
+      teb_base == LLDB_INVALID_ADDRESS) {
+    LLDB_LOG(log, "missing 'teb_address' in extended thread info");
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  ProcessSP process = thread->GetProcess();
+  if (!process) {
+    LLDB_LOG(log, "missing process");
+    return LLDB_INVALID_ADDRESS;
+  }
+  uint32_t addr_byte_size = process->GetAddressByteSize();
+  addr_t tls_array_addr = teb_base + 11 * addr_byte_size;
+  llvm::Expected<addr_t> tls_array =
+      process->ReadPointerFromMemory(tls_array_addr);
+  if (!tls_array || *tls_array == LLDB_INVALID_ADDRESS) {
+    LLDB_LOG_ERROR(log, tls_array.takeError(),
+                   "failed to read TLS array from {1:x16}: {0}",
+                   tls_array_addr);
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  Symtab *symtab = module->GetSymtab();
+  if (!symtab) {
+    LLDB_LOG(log, "missing symtab for {0}", object_name);
+    return LLDB_INVALID_ADDRESS;
+  }
+  Symbol *tls_index_sym = symtab->FindFirstSymbolWithNameAndType(
+      ConstString("_tls_index"), eSymbolTypeAny, Symtab::eDebugAny,
+      Symtab::eVisibilityAny);
+  if (!tls_index_sym) {
+    LLDB_LOG(log, "missing '_tls_index' symbol in {0}", object_name);
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  Target &target = process->GetTarget();
+  addr_t tls_index_load_addr =
+      tls_index_sym->GetAddress().GetLoadAddress(&target);
+  if (tls_index_load_addr == LLDB_INVALID_ADDRESS) {
+    LLDB_LOG(log, "failed to resolve load address of '_tls_index' in {0}",
+             object_name);
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  Status error;
+  uint64_t tls_index =
+      process->ReadUnsignedIntegerFromMemory(tls_index_load_addr, 4, 0, error);
+  if (error.Fail()) {
+    LLDB_LOG_ERROR(log, error.takeError(),
+                   "failed to read '_tls_index' in {1} from {2:x8}: {0}",
+                   object_name, tls_index_load_addr);
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  addr_t tls_index_item = *tls_array + tls_index * addr_byte_size;
+  LLDB_LOG(log, "tls base address for {0} is at {1:x8} + {2:x8} * {3} = {4:x8}",
+           object_name, *tls_array, tls_index, addr_byte_size, tls_index_item);
+
+  llvm::Expected<addr_t> tls_base =
+      process->ReadPointerFromMemory(tls_index_item);
+  if (!tls_base || *tls_base == LLDB_INVALID_ADDRESS || *tls_base == 0) {
+    LLDB_LOG_ERROR(log, error.takeError(),
+                   "failed to read tls array in {1} at index {2} ({3:x8}): {0}",
+                   object_name, tls_index, tls_index_item);
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  return *tls_base + tls_file_addr;
+}
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index eebb5117b30c5..6784fed45242d 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -39,6 +39,10 @@ class DynamicLoaderWindowsDYLD : public DynamicLoader {
 
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 
+  lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+                                  const lldb::ThreadSP thread,
+                                  lldb::addr_t tls_file_addr) override;
+
 protected:
   /// Returns the load address for the given executable module.
   ///
diff --git a/lldb/test/API/lang/c/tls_globals/Makefile b/lldb/test/API/lang/c/tls_globals/Makefile
index b26ce5c8b1449..e4bee9c3cd192 100644
--- a/lldb/test/API/lang/c/tls_globals/Makefile
+++ b/lldb/test/API/lang/c/tls_globals/Makefile
@@ -1,8 +1,15 @@
 C_SOURCES := main.c
 
-DYLIB_NAME := a
+DYLIB_NAME := a_dylib
 DYLIB_C_SOURCES := a.c
 
 ENABLE_THREADS := YES
 
+ifeq "$(OS)" "Windows_NT"
+	ifneq "$(MAKE_PDB)" "YES"
+		# Embed a symbol table in the executable.
+		LD_EXTRAS := -Wl,/debug:symtab
+	endif
+endif
+
 include Makefile.rules
diff --git a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
index a7f117e1749a6..9e20a62f23630 100644
--- a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
+++ b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
@@ -11,6 +11,9 @@
 @requireThreadSupport
 @skipIfTargetDoesNotSupportSharedLibraries()
 class TlsGlobalTestCase(TestBase):
+    TEST_WITH_PDB_DEBUG_INFO = True
+    SHARED_BUILD_TESTCASE = False
+
     def setUp(self):
         TestBase.setUp(self)
 
@@ -37,18 +40,20 @@ def setUp(self):
                 lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath)
             )
 
-    # TLS works differently on Windows, this would need to be implemented
-    # separately.
-    @skipIfWindows
     @skipIf(oslist=["linux"], archs=["aarch64"])
-    @skipIf(oslist=no_match([lldbplatformutil.getDarwinOSTriples(), "linux"]))
+    @skipIf(
+        oslist=["windows"], debug_info=["dwarf"], bugnumber="https://llvm.org/PR196083"
+    )
+    @skipIf(
+        oslist=no_match([lldbplatformutil.getDarwinOSTriples(), "linux", "windows"])
+    )
     @expectedFailureIf(lldbplatformutil.xcode15LinkerBug())
     def test(self):
         """Test thread-local storage."""
         self.build()
         exe = self.getBuildArtifact("a.out")
         target = self.dbg.CreateTarget(exe)
-        env = self.registerSharedLibrariesWithTarget(target, ["a"])
+        env = self.registerSharedLibrariesWithTarget(target, ["a_dylib"])
 
         line1 = line_number("main.c", "// thread breakpoint")
         lldbutil.run_break_set_by_file_and_line(
@@ -66,7 +71,13 @@ def test(self):
 
         # BUG: sometimes lldb doesn't change threads to the stopped thread.
         # (unrelated to this test).
-        self.runCmd("thread select 2", "Change thread")
+        is_second_thread = lambda thread: "fn_static" in (
+            thread.GetFrameAtIndex(0).GetFunctionName() or ""
+        )
+        if not is_second_thread(self.thread()):
+            for thread in self.process():
+                if is_second_thread(thread):
+                    self.runCmd(f"thread select {thread.GetIndexID()}", "Change thread")
 
         # Check that TLS evaluates correctly within the thread.
         self.expect(
diff --git a/lldb/test/API/lang/c/tls_globals/a.c b/lldb/test/API/lang/c/tls_globals/a.c
index f63108d8cceb1..e6ef878b89674 100644
--- a/lldb/test/API/lang/c/tls_globals/a.c
+++ b/lldb/test/API/lang/c/tls_globals/a.c
@@ -1,15 +1,10 @@
-#include <unistd.h>
+#include <stdio.h>
 
 __thread int var_shared = 33;
 
-int
-touch_shared()
-{
-    return var_shared;
-}
+int LLDB_DYLIB_EXPORT touch_shared() { return var_shared; }
 
-void shared_check()
-{
-	var_shared *= 2;
-	usleep(1); // shared thread breakpoint
+void LLDB_DYLIB_EXPORT shared_check() {
+  var_shared *= 2;
+  printf(""); // shared thread breakpoint
 }
diff --git a/lldb/test/API/lang/c/tls_globals/main.c b/lldb/test/API/lang/c/tls_globals/main.c
index fac760b350ab2..000376128b4c4 100644
--- a/lldb/test/API/lang/c/tls_globals/main.c
+++ b/lldb/test/API/lang/c/tls_globals/main.c
@@ -1,36 +1,55 @@
 #include <stdio.h>
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#else
 #include <pthread.h>
 #include <unistd.h>
+#endif
 
-void shared_check();
+#ifdef _WIN32
+typedef DWORD ThreadReturn;
+
+static void do_sleep(int msec) { Sleep(msec); }
+static void run_thread(ThreadReturn (*fn)(void *)) {
+  CreateThread(NULL, 0, fn, NULL, 0, NULL);
+}
+#else
+typedef void *ThreadReturn;
+
+static void do_sleep(int msec) { usleep(msec * 1000); }
+static void run_thread(ThreadReturn (*fn)(void *)) {
+  pthread_t handle;
+  pthread_create(&handle, NULL, fn, NULL);
+}
+#endif
+
+void LLDB_DYLIB_IMPORT shared_check();
 // On some OS's (darwin) you must actually access a thread local variable
 // before you can read it
-int
-touch_shared();
+int LLDB_DYLIB_IMPORT touch_shared();
 
 // Create some TLS storage within the static executable.
 __thread int var_static = 44;
 __thread int var_static2 = 22;
 
-void *fn_static(void *param)
-{
-	var_static *= 2;
-	var_static2 *= 3;
-	shared_check();
-	usleep(1); // thread breakpoint
-	for(;;)
-		usleep(1);
+static ThreadReturn fn_static(void *param) {
+  var_static *= 2;
+  var_static2 *= 3;
+  shared_check();
+  do_sleep(1); // thread breakpoint
+  for (;;)
+    do_sleep(1);
+
+  return 0;
 }
 
-int main (int argc, char const *argv[])
-{
-	pthread_t handle;
-	pthread_create(&handle, NULL, &fn_static, NULL);
-        touch_shared();
-        for (; var_static;)
-        {
-            usleep(1); // main breakpoint
-        }
-
-        return 0;
+int main(int argc, char const *argv[]) {
+  run_thread(&fn_static);
+  touch_shared();
+  for (; var_static;) {
+    printf(""); // main breakpoint
+  }
+
+  return 0;
 }

>From 49e6d8316fd606ba3d1c696733b8f16a38ce6f2b Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Thu, 8 Oct 2026 20:44:08 +0200
Subject: [PATCH 2/4] fix: apply suggestions from review

---
 .../Windows-DYLD/DynamicLoaderWindowsDYLD.cpp | 62 +++++++++++++------
 .../Windows-DYLD/DynamicLoaderWindowsDYLD.h   |  4 ++
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp    | 13 ++++
 .../ObjectFile/PECOFF/ObjectFilePECOFF.h      |  2 +
 .../API/lang/c/tls_globals/TestTlsGlobals.py  |  6 +-
 5 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 1ef91456445cd..38914ff208934 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -9,6 +9,7 @@
 #include "DynamicLoaderWindowsDYLD.h"
 
 #include "MSVCRTCFrameRecognizer.h"
+#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -68,8 +69,8 @@ void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
   // Resolve the module unless we already have one.
   if (!module_sp) {
     Status error;
-    module_sp = m_process->GetTarget().GetOrCreateModule(module_spec, 
-                                             true /* notify */, &error);
+    module_sp = m_process->GetTarget().GetOrCreateModule(
+        module_spec, true /* notify */, &error);
     if (error.Fail())
       return;
   }
@@ -253,12 +254,14 @@ DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
                                              lldb::ThreadSP thread,
                                              lldb::addr_t tls_file_addr) {
   Log *log = GetLog(LLDBLog::DynamicLoader);
-  std::string object_name;
-  if (log) {
-    ObjectFile *obj = module->GetObjectFile();
-    if (obj)
-      object_name = obj->GetObjectName();
+  ObjectFile *obj = module->GetObjectFile();
+  if (!obj) {
+    LLDB_LOG(log, "no object file for module");
+    return LLDB_INVALID_ADDRESS;
   }
+  std::string object_name;
+  if (log)
+    object_name = obj->GetObjectName();
 
   StructuredData::ObjectSP extended_info = thread->GetExtendedInfo();
   if (!extended_info) {
@@ -293,22 +296,14 @@ DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
     return LLDB_INVALID_ADDRESS;
   }
 
-  Symtab *symtab = module->GetSymtab();
-  if (!symtab) {
-    LLDB_LOG(log, "missing symtab for {0}", object_name);
-    return LLDB_INVALID_ADDRESS;
-  }
-  Symbol *tls_index_sym = symtab->FindFirstSymbolWithNameAndType(
-      ConstString("_tls_index"), eSymbolTypeAny, Symtab::eDebugAny,
-      Symtab::eVisibilityAny);
-  if (!tls_index_sym) {
-    LLDB_LOG(log, "missing '_tls_index' symbol in {0}", object_name);
+  Address tls_index_addr;
+  if (!GetTlsIndexAddressForModule(module, tls_index_addr)) {
+    LLDB_LOG(log, "failed to resolve tls index for {0}", object_name);
     return LLDB_INVALID_ADDRESS;
   }
 
   Target &target = process->GetTarget();
-  addr_t tls_index_load_addr =
-      tls_index_sym->GetAddress().GetLoadAddress(&target);
+  addr_t tls_index_load_addr = tls_index_addr.GetLoadAddress(&target);
   if (tls_index_load_addr == LLDB_INVALID_ADDRESS) {
     LLDB_LOG(log, "failed to resolve load address of '_tls_index' in {0}",
              object_name);
@@ -332,7 +327,7 @@ DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
   llvm::Expected<addr_t> tls_base =
       process->ReadPointerFromMemory(tls_index_item);
   if (!tls_base || *tls_base == LLDB_INVALID_ADDRESS || *tls_base == 0) {
-    LLDB_LOG_ERROR(log, error.takeError(),
+    LLDB_LOG_ERROR(log, tls_base.takeError(),
                    "failed to read tls array in {1} at index {2} ({3:x8}): {0}",
                    object_name, tls_index, tls_index_item);
     return LLDB_INVALID_ADDRESS;
@@ -340,3 +335,30 @@ DynamicLoaderWindowsDYLD::GetThreadLocalData(const lldb::ModuleSP module,
 
   return *tls_base + tls_file_addr;
 }
+
+bool DynamicLoaderWindowsDYLD::GetTlsIndexAddressForModule(
+    const ModuleSP &module, Address &addr) const {
+  ObjectFilePECOFF *obj =
+      llvm::dyn_cast_or_null<ObjectFilePECOFF>(module->GetObjectFile());
+  if (obj) {
+    addr_t tls_index_file_addr = obj->GetTlsIndexAddress();
+    if (tls_index_file_addr != LLDB_INVALID_ADDRESS &&
+        module->ResolveFileAddress(tls_index_file_addr, addr))
+      return true;
+  }
+
+  // If we can't get the tls index from the object file, try the _tls_index
+  // symbol.
+  Symtab *symtab = module->GetSymtab();
+  if (!symtab)
+    return false;
+
+  Symbol *tls_index_sym = symtab->FindFirstSymbolWithNameAndType(
+      ConstString("_tls_index"), eSymbolTypeAny, Symtab::eDebugAny,
+      Symtab::eVisibilityAny);
+  if (!tls_index_sym)
+    return false;
+
+  addr = tls_index_sym->GetAddress();
+  return addr.IsValid();
+}
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 6784fed45242d..b283e0ce270ae 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -76,6 +76,10 @@ class DynamicLoaderWindowsDYLD : public DynamicLoader {
   /// its own reference, keeping the file locked and blocking recompilation
   /// during an active debug session.
   llvm::DenseMap<lldb::addr_t, lldb::ModuleWP> m_loaded_modules;
+
+private:
+  bool GetTlsIndexAddressForModule(const lldb::ModuleSP &module,
+                                   Address &addr) const;
 };
 
 } // namespace lldb_private
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index ac53b53fba868..8d3815e7e6443 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -958,6 +958,19 @@ std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo() {
                                            data_dir_exception.vmsize);
 }
 
+lldb::addr_t ObjectFilePECOFF::GetTlsIndexAddress() const {
+  addr_t addr = LLDB_INVALID_ADDRESS;
+  if (m_binary->is64()) {
+    if (m_binary->getTLSDirectory64())
+      addr = m_binary->getTLSDirectory64()->AddressOfIndex.value();
+  } else if (m_binary->getTLSDirectory32())
+    addr = m_binary->getTLSDirectory32()->AddressOfIndex.value();
+
+  if (addr == 0)
+    addr = LLDB_INVALID_ADDRESS;
+  return addr;
+}
+
 bool ObjectFilePECOFF::IsStripped() {
   // TODO: determine this for COFF
   return false;
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index fe620b9fc938e..923097348d971 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -154,6 +154,8 @@ class ObjectFilePECOFF : public lldb_private::ObjectFile {
 
   std::unique_ptr<lldb_private::CallFrameInfo> CreateCallFrameInfo() override;
 
+  lldb::addr_t GetTlsIndexAddress() const;
+
 protected:
   bool NeedsEndianSwap() const;
 
diff --git a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
index 9e20a62f23630..efef5a2bf143e 100644
--- a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
+++ b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
@@ -75,9 +75,9 @@ def test(self):
             thread.GetFrameAtIndex(0).GetFunctionName() or ""
         )
         if not is_second_thread(self.thread()):
-            for thread in self.process():
-                if is_second_thread(thread):
-                    self.runCmd(f"thread select {thread.GetIndexID()}", "Change thread")
+            thread = next((t for t in self.process() if is_second_thread(t)), None)
+            self.assertIsNotNone(thread, "could not find the fn_static thread")
+            self.runCmd(f"thread select {thread.GetIndexID()}", "Change thread")
 
         # Check that TLS evaluates correctly within the thread.
         self.expect(

>From 72281b809c7ffdf69624896a74d61c30a5529c92 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Thu, 8 Oct 2026 20:45:06 +0200
Subject: [PATCH 3/4] chore: remove symtab

---
 lldb/test/API/lang/c/tls_globals/Makefile | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/lldb/test/API/lang/c/tls_globals/Makefile b/lldb/test/API/lang/c/tls_globals/Makefile
index e4bee9c3cd192..0da5ddd724e98 100644
--- a/lldb/test/API/lang/c/tls_globals/Makefile
+++ b/lldb/test/API/lang/c/tls_globals/Makefile
@@ -5,11 +5,4 @@ DYLIB_C_SOURCES := a.c
 
 ENABLE_THREADS := YES
 
-ifeq "$(OS)" "Windows_NT"
-	ifneq "$(MAKE_PDB)" "YES"
-		# Embed a symbol table in the executable.
-		LD_EXTRAS := -Wl,/debug:symtab
-	endif
-endif
-
 include Makefile.rules

>From e507f2c2e6f32e1ed4dc76a6565000cc64738286 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Sun, 11 Oct 2026 22:10:20 +0200
Subject: [PATCH 4/4] fix: link to windows dyld and object file pe/coff

---
 lldb/unittests/Thread/CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/unittests/Thread/CMakeLists.txt b/lldb/unittests/Thread/CMakeLists.txt
index 8fc44da6f5b39..a34121e493385 100644
--- a/lldb/unittests/Thread/CMakeLists.txt
+++ b/lldb/unittests/Thread/CMakeLists.txt
@@ -1,6 +1,8 @@
 if (CMAKE_SYSTEM_NAME MATCHES "Windows")
   list(APPEND LLDB_WINDOWS_LIBS lldbPluginPlatformWindows)
   list(APPEND LLDB_WINDOWS_LIBS lldbPluginProcessWindowsCommon)
+  list(APPEND LLDB_WINDOWS_LIBS lldbPluginDynamicLoaderWindowsDYLD)
+  list(APPEND LLDB_WINDOWS_LIBS lldbPluginObjectFilePECOFF)
 endif()
 
 add_lldb_unittest(ThreadTests



More information about the lldb-commits mailing list