[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