[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2026-07-08 Thread via lldb-commits

Nerixyz wrote:

> are you still interested in this?

It's not as important with the next LLVM release. I made Clang use LLD if the 
user asks for DWARF in https://github.com/llvm/llvm-project/pull/198600.
It's still a useful warning if you have that issue.

I thought we could use something similar for the LLDB sections, but it looks 
like they already accept the truncated names (#198377).

https://github.com/llvm/llvm-project/pull/145175
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2026-07-08 Thread via lldb-commits

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

>From f4c819799286ae8ff2b152ae0a62956598f45740 Mon Sep 17 00:00:00 2001
From: Nerixyz 
Date: Sat, 21 Jun 2025 17:36:58 +0200
Subject: [PATCH] [LLDB] Warn about truncated DWARF section names on Windows

---
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp| 21 
 .../Shell/ObjectFile/PECOFF/lit.local.cfg |  2 +-
 .../Shell/ObjectFile/PECOFF/truncated-dwarf.c |  7 
 lldb/test/Shell/helper/build.py   | 33 ---
 llvm/docs/ReleaseNotes.md |  2 ++
 5 files changed, 59 insertions(+), 6 deletions(-)
 create mode 100644 lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c

diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 15f257f8b0ed4..0260062dc348d 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1053,12 +1053,23 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ".debug_*"
+  // In PECOFF files, the section name in the section header can only
+  // contain 8 bytes. If a section name doesn't fit there, it can be
+  // extended in the string table. Since, officially, executable images
+  // don't have a string table, the default link.exe truncates section 
names
+  // to fit in the section header.
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&
+  sect_name.starts_with(".debug_"))
+truncated_dwarf_sections.emplace_back(sect_name);
+
   SectionSP section_sp(new Section(
   module_sp,   // Module to which this section belongs
   this,// Object file to which this section belongs
@@ -1088,6 +1099,16 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
   m_sections_up->AddSection(section_sp);
   unified_section_list.AddSection(section_sp);
 }
+
+if (!truncated_dwarf_sections.empty())
+  module_sp->ReportWarning(
+  "contains {} DWARF sections with truncated names ({}).\nWindows "
+  "executable (PECOFF) images produced by the default link.exe don't "
+  "include the required section names. A third party linker like "
+  "lld-link is required (compile with -fuse-ld=lld-link when using "
+  "Clang)",
+  truncated_dwarf_sections.size(),
+  llvm::join(truncated_dwarf_sections, ", "));
   }
 }
 
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg 
b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
index 9ef350be1dee2..1ae00d07fc3e6 100644
--- a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
+++ b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.yaml', '.test']
+config.suffixes = ['.yaml', '.test', '.c']
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c 
b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
new file mode 100644
index 0..43dc252739ebc
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
@@ -0,0 +1,7 @@
+// REQUIRES: target-windows
+// RUN: %build --compiler=clang-cl --force-dwarf-symbols --force-ms-link -o 
%t.exe -- %s
+// RUN: %lldb -f %t.exe 2>&1 | FileCheck %s
+
+int main(void) {}
+
+// CHECK: warning: {{.*}} contains 4 DWARF sections with truncated names 
(.debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}})
diff --git a/lldb/test/Shell/helper/build.py b/lldb/test/Shell/helper/build.py
index 1c15fb04bc3d6..4240fe923497d 100755
--- a/lldb/test/Shell/helper/build.py
+++ b/lldb/test/Shell/helper/build.py
@@ -169,6 +169,22 @@
 help="Specify the C/C++ standard.",
 )
 
+parser.add_argument(
+"--force-dwarf-symbols",
+dest="force_dwarf_symbols",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, use DWARF instead of 
CodeView",
+)
+
+parser.add_argument(
+"--force-ms-link",
+dest="force_ms_link",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, always use link.exe",
+)
+
 
 args = parser.parse_args(args=sys.argv[1:])
 
@@ -375,15 +391,20 @@ def __init__(self, toolchain_type, args):
 )
 
 if self.mode == "link" or self.mode == "compile-and-link":
-self.linker = (
-self._find_linker("link")
-if to

[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2026-07-08 Thread David Spickett via lldb-commits

DavidSpickett wrote:

@Nerixyz are you still interested in this?

https://github.com/llvm/llvm-project/pull/145175
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-25 Thread via lldb-commits

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

>From a7e33a16dd280250df2ff2d01648bd4d5bfe000b Mon Sep 17 00:00:00 2001
From: Nerixyz 
Date: Sat, 21 Jun 2025 17:36:58 +0200
Subject: [PATCH] [LLDB] Warn about truncated DWARF section names on Windows

---
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp| 21 
 .../Shell/ObjectFile/PECOFF/lit.local.cfg |  2 +-
 .../Shell/ObjectFile/PECOFF/truncated-dwarf.c |  7 
 lldb/test/Shell/helper/build.py   | 33 ---
 llvm/docs/ReleaseNotes.md |  2 ++
 5 files changed, 59 insertions(+), 6 deletions(-)
 create mode 100644 lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c

diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 4984445dcbab9..61c03e25e461c 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1036,12 +1036,23 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ".debug_*"
+  // In PECOFF files, the section name in the section header can only
+  // contain 8 bytes. If a section name doesn't fit there, it can be
+  // extended in the string table. Since, officially, executable images
+  // don't have a string table, the default link.exe truncates section 
names
+  // to fit in the section header.
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&
+  sect_name.starts_with(".debug_"))
+truncated_dwarf_sections.emplace_back(sect_name);
+
   SectionSP section_sp(new Section(
   module_sp,   // Module to which this section belongs
   this,// Object file to which this section belongs
@@ -1071,6 +1082,16 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
   m_sections_up->AddSection(section_sp);
   unified_section_list.AddSection(section_sp);
 }
+
+if (!truncated_dwarf_sections.empty())
+  module_sp->ReportWarning(
+  "contains {} DWARF sections with truncated names ({}).\nWindows "
+  "executable (PECOFF) images produced by the default link.exe don't "
+  "include the required section names. A third party linker like "
+  "lld-link is required (compile with -fuse-ld=lld-link when using "
+  "Clang).",
+  truncated_dwarf_sections.size(),
+  llvm::join(truncated_dwarf_sections, ", "));
   }
 }
 
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg 
b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
index 9ef350be1dee2..1ae00d07fc3e6 100644
--- a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
+++ b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.yaml', '.test']
+config.suffixes = ['.yaml', '.test', '.c']
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c 
b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
new file mode 100644
index 0..43dc252739ebc
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
@@ -0,0 +1,7 @@
+// REQUIRES: target-windows
+// RUN: %build --compiler=clang-cl --force-dwarf-symbols --force-ms-link -o 
%t.exe -- %s
+// RUN: %lldb -f %t.exe 2>&1 | FileCheck %s
+
+int main(void) {}
+
+// CHECK: warning: {{.*}} contains 4 DWARF sections with truncated names 
(.debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}})
diff --git a/lldb/test/Shell/helper/build.py b/lldb/test/Shell/helper/build.py
index caaa14f90af1c..c73aa8a11b396 100755
--- a/lldb/test/Shell/helper/build.py
+++ b/lldb/test/Shell/helper/build.py
@@ -173,6 +173,22 @@
 help="Specify the C/C++ standard.",
 )
 
+parser.add_argument(
+"--force-dwarf-symbols",
+dest="force_dwarf_symbols",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, use DWARF instead of 
CodeView",
+)
+
+parser.add_argument(
+"--force-ms-link",
+dest="force_ms_link",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, always use link.exe",
+)
+
 
 args = parser.parse_args(args=sys.argv[1:])
 
@@ -379,15 +395,20 @@ def __init__(self, toolchain_type, args):
 )
 
 if self.mode == "link" or self.mode == "compile-and-link":
-self.linker = (
-self._find_linker("link")
-if t

[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-24 Thread David Spickett via lldb-commits


@@ -1036,12 +1036,18 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ^\.debug_[a-z]$
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&

DavidSpickett wrote:

I was thinking that lldb did not already have support for this format but it 
sounds like we already do. I know lld will write it out this way because I've 
seen that non-standard warning a few times before.

https://github.com/llvm/llvm-project/pull/145175
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-23 Thread via lldb-commits

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

>From fa67d1dc9ffa3157b3d1a5dd9173b99d7e6b75ef Mon Sep 17 00:00:00 2001
From: Nerixyz 
Date: Sat, 21 Jun 2025 17:36:58 +0200
Subject: [PATCH] [LLDB] Warn about truncated DWARF section names on Windows

---
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp| 21 
 .../Shell/ObjectFile/PECOFF/lit.local.cfg |  2 +-
 .../Shell/ObjectFile/PECOFF/truncated-dwarf.c |  7 
 lldb/test/Shell/helper/build.py   | 33 ---
 llvm/docs/ReleaseNotes.md |  2 ++
 5 files changed, 59 insertions(+), 6 deletions(-)
 create mode 100644 lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c

diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 4984445dcbab9..61c03e25e461c 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1036,12 +1036,23 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ".debug_*"
+  // In PECOFF files, the section name in the section header can only
+  // contain 8 bytes. If a section name doesn't fit there, it can be
+  // extended in the string table. Since, officially, executable images
+  // don't have a string table, the default link.exe truncates section 
names
+  // to fit in the section header.
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&
+  sect_name.starts_with(".debug_"))
+truncated_dwarf_sections.emplace_back(sect_name);
+
   SectionSP section_sp(new Section(
   module_sp,   // Module to which this section belongs
   this,// Object file to which this section belongs
@@ -1071,6 +1082,16 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
   m_sections_up->AddSection(section_sp);
   unified_section_list.AddSection(section_sp);
 }
+
+if (!truncated_dwarf_sections.empty())
+  module_sp->ReportWarning(
+  "contains {} DWARF sections with truncated names ({}).\nWindows "
+  "executable (PECOFF) images produced by the default link.exe don't "
+  "include the required section names. A third party linker like "
+  "lld-link is required (compile with -fuse-ld=lld-link when using "
+  "Clang).",
+  truncated_dwarf_sections.size(),
+  llvm::join(truncated_dwarf_sections, ", "));
   }
 }
 
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg 
b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
index 9ef350be1dee2..1ae00d07fc3e6 100644
--- a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
+++ b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.yaml', '.test']
+config.suffixes = ['.yaml', '.test', '.c']
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c 
b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
new file mode 100644
index 0..43dc252739ebc
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
@@ -0,0 +1,7 @@
+// REQUIRES: target-windows
+// RUN: %build --compiler=clang-cl --force-dwarf-symbols --force-ms-link -o 
%t.exe -- %s
+// RUN: %lldb -f %t.exe 2>&1 | FileCheck %s
+
+int main(void) {}
+
+// CHECK: warning: {{.*}} contains 4 DWARF sections with truncated names 
(.debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}})
diff --git a/lldb/test/Shell/helper/build.py b/lldb/test/Shell/helper/build.py
index caaa14f90af1c..c73aa8a11b396 100755
--- a/lldb/test/Shell/helper/build.py
+++ b/lldb/test/Shell/helper/build.py
@@ -173,6 +173,22 @@
 help="Specify the C/C++ standard.",
 )
 
+parser.add_argument(
+"--force-dwarf-symbols",
+dest="force_dwarf_symbols",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, use DWARF instead of 
CodeView",
+)
+
+parser.add_argument(
+"--force-ms-link",
+dest="force_ms_link",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, always use link.exe",
+)
+
 
 args = parser.parse_args(args=sys.argv[1:])
 
@@ -379,15 +395,20 @@ def __init__(self, toolchain_type, args):
 )
 
 if self.mode == "link" or self.mode == "compile-and-link":
-self.linker = (
-self._find_linker("link")
-if t

[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-23 Thread via lldb-commits


@@ -1036,12 +1036,18 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ^\.debug_[a-z]$
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&

Nerixyz wrote:

> Besides the point of this PR, but is there any information about whether 
> link.exe does this too, or if it's just an escape route for third parties?

It is officially documented in the [name 
field](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers)
 of the COFF header.

I don't know when/if link.exe will ever generate this indirect section name (I 
think it will always emit executable images).

So it's non-standard (lld-link also warns: `section name .debug_abbrev is 
longer than 8 characters and will use a non-standard string table` - MinGW's 
`ld` does this without any warning), but supported by most tools - even 
Microsoft's dumpbin will happily output the long section names.

https://github.com/llvm/llvm-project/pull/145175
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-23 Thread Michael Buch via lldb-commits


@@ -1036,12 +1036,18 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ^\.debug_[a-z]$
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&

Michael137 wrote:

> The truncation will always be 8 bytes, because that's how much space the 
> section name has in the PE/COFF section header - it's basically a char 
> name[8] field. For longer names, the linker has to write the section name 
> into the string table and set the name in the section header to /n where n is 
> the offset in the string table.

If that's guaranteed by the file format and won't ever change, fair enough. 
Lets at least keep a comment about this here

https://github.com/llvm/llvm-project/pull/145175
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB] Warn about truncated DWARF section names on Windows (PR #145175)

2025-06-23 Thread via lldb-commits

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

>From 72f30f6d2a1dfb5523bafd4a535b078b3de5cfc6 Mon Sep 17 00:00:00 2001
From: Nerixyz 
Date: Sat, 21 Jun 2025 17:36:58 +0200
Subject: [PATCH] [LLDB] Warn about truncated DWARF section names on Windows

---
 .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp| 16 +
 .../Shell/ObjectFile/PECOFF/lit.local.cfg |  2 +-
 .../Shell/ObjectFile/PECOFF/truncated-dwarf.c |  7 
 lldb/test/Shell/helper/build.py   | 33 ---
 llvm/docs/ReleaseNotes.md |  2 ++
 5 files changed, 54 insertions(+), 6 deletions(-)
 create mode 100644 lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c

diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 
b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 4984445dcbab9..e4e59a8c7bdd5 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -1036,12 +1036,18 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
 m_sections_up->AddSection(header_sp);
 unified_section_list.AddSection(header_sp);
 
+std::vector truncated_dwarf_sections;
 const uint32_t nsects = m_sect_headers.size();
 for (uint32_t idx = 0; idx < nsects; ++idx) {
   llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
   ConstString const_sect_name(sect_name);
   SectionType section_type = GetSectionType(sect_name, 
m_sect_headers[idx]);
 
+  // Detect unknown sections matching ".debug_*"
+  if (section_type == eSectionTypeOther && sect_name.size() == 8 &&
+  sect_name.starts_with(".debug_"))
+truncated_dwarf_sections.emplace_back(sect_name);
+
   SectionSP section_sp(new Section(
   module_sp,   // Module to which this section belongs
   this,// Object file to which this section belongs
@@ -1071,6 +1077,16 @@ void ObjectFilePECOFF::CreateSections(SectionList 
&unified_section_list) {
   m_sections_up->AddSection(section_sp);
   unified_section_list.AddSection(section_sp);
 }
+
+if (!truncated_dwarf_sections.empty())
+  module_sp->ReportWarning(
+  "contains {} DWARF sections with truncated names ({}).\nWindows "
+  "executable (PECOFF) images produced by the default link.exe don't "
+  "include the required section names. A third party linker like "
+  "lld-link is required (compile with -fuse-ld=lld-link when using "
+  "Clang).",
+  truncated_dwarf_sections.size(),
+  llvm::join(truncated_dwarf_sections, ", "));
   }
 }
 
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg 
b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
index 9ef350be1dee2..1ae00d07fc3e6 100644
--- a/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
+++ b/lldb/test/Shell/ObjectFile/PECOFF/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.yaml', '.test']
+config.suffixes = ['.yaml', '.test', '.c']
diff --git a/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c 
b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
new file mode 100644
index 0..43dc252739ebc
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/PECOFF/truncated-dwarf.c
@@ -0,0 +1,7 @@
+// REQUIRES: target-windows
+// RUN: %build --compiler=clang-cl --force-dwarf-symbols --force-ms-link -o 
%t.exe -- %s
+// RUN: %lldb -f %t.exe 2>&1 | FileCheck %s
+
+int main(void) {}
+
+// CHECK: warning: {{.*}} contains 4 DWARF sections with truncated names 
(.debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}})
diff --git a/lldb/test/Shell/helper/build.py b/lldb/test/Shell/helper/build.py
index caaa14f90af1c..c73aa8a11b396 100755
--- a/lldb/test/Shell/helper/build.py
+++ b/lldb/test/Shell/helper/build.py
@@ -173,6 +173,22 @@
 help="Specify the C/C++ standard.",
 )
 
+parser.add_argument(
+"--force-dwarf-symbols",
+dest="force_dwarf_symbols",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, use DWARF instead of 
CodeView",
+)
+
+parser.add_argument(
+"--force-ms-link",
+dest="force_ms_link",
+action="store_true",
+default=False,
+help="When compiling with clang-cl on Windows, always use link.exe",
+)
+
 
 args = parser.parse_args(args=sys.argv[1:])
 
@@ -379,15 +395,20 @@ def __init__(self, toolchain_type, args):
 )
 
 if self.mode == "link" or self.mode == "compile-and-link":
-self.linker = (
-self._find_linker("link")
-if toolchain_type == "msvc"
-else self._find_linker("lld-link", args.tools_dir)
-)
+if toolchain_type == "msvc" or args.force_ms_link:
+search_paths = []
+if toolchain_type != "msvc":
+search_paths.append(
+os.path.dirname(find_executable("