Skip to content

Commit a7e33a1

Browse files
committed
[LLDB] Warn about truncated DWARF section names on Windows
1 parent 626be98 commit a7e33a1

File tree

5 files changed

+59
-6
lines changed

5 files changed

+59
-6
lines changed

lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,12 +1036,23 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
10361036
m_sections_up->AddSection(header_sp);
10371037
unified_section_list.AddSection(header_sp);
10381038

1039+
std::vector<llvm::StringRef> truncated_dwarf_sections;
10391040
const uint32_t nsects = m_sect_headers.size();
10401041
for (uint32_t idx = 0; idx < nsects; ++idx) {
10411042
llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
10421043
ConstString const_sect_name(sect_name);
10431044
SectionType section_type = GetSectionType(sect_name, m_sect_headers[idx]);
10441045

1046+
// Detect unknown sections matching ".debug_*"
1047+
// In PECOFF files, the section name in the section header can only
1048+
// contain 8 bytes. If a section name doesn't fit there, it can be
1049+
// extended in the string table. Since, officially, executable images
1050+
// don't have a string table, the default link.exe truncates section names
1051+
// to fit in the section header.
1052+
if (section_type == eSectionTypeOther && sect_name.size() == 8 &&
1053+
sect_name.starts_with(".debug_"))
1054+
truncated_dwarf_sections.emplace_back(sect_name);
1055+
10451056
SectionSP section_sp(new Section(
10461057
module_sp, // Module to which this section belongs
10471058
this, // Object file to which this section belongs
@@ -1071,6 +1082,16 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
10711082
m_sections_up->AddSection(section_sp);
10721083
unified_section_list.AddSection(section_sp);
10731084
}
1085+
1086+
if (!truncated_dwarf_sections.empty())
1087+
module_sp->ReportWarning(
1088+
"contains {} DWARF sections with truncated names ({}).\nWindows "
1089+
"executable (PECOFF) images produced by the default link.exe don't "
1090+
"include the required section names. A third party linker like "
1091+
"lld-link is required (compile with -fuse-ld=lld-link when using "
1092+
"Clang).",
1093+
truncated_dwarf_sections.size(),
1094+
llvm::join(truncated_dwarf_sections, ", "));
10741095
}
10751096
}
10761097

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
config.suffixes = ['.yaml', '.test']
1+
config.suffixes = ['.yaml', '.test', '.c']
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// REQUIRES: target-windows
2+
// RUN: %build --compiler=clang-cl --force-dwarf-symbols --force-ms-link -o %t.exe -- %s
3+
// RUN: %lldb -f %t.exe 2>&1 | FileCheck %s
4+
5+
int main(void) {}
6+
7+
// CHECK: warning: {{.*}} contains 4 DWARF sections with truncated names (.debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}}, .debug_{{[a-z]}})

lldb/test/Shell/helper/build.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,22 @@
173173
help="Specify the C/C++ standard.",
174174
)
175175

176+
parser.add_argument(
177+
"--force-dwarf-symbols",
178+
dest="force_dwarf_symbols",
179+
action="store_true",
180+
default=False,
181+
help="When compiling with clang-cl on Windows, use DWARF instead of CodeView",
182+
)
183+
184+
parser.add_argument(
185+
"--force-ms-link",
186+
dest="force_ms_link",
187+
action="store_true",
188+
default=False,
189+
help="When compiling with clang-cl on Windows, always use link.exe",
190+
)
191+
176192

177193
args = parser.parse_args(args=sys.argv[1:])
178194

@@ -379,15 +395,20 @@ def __init__(self, toolchain_type, args):
379395
)
380396

381397
if self.mode == "link" or self.mode == "compile-and-link":
382-
self.linker = (
383-
self._find_linker("link")
384-
if toolchain_type == "msvc"
385-
else self._find_linker("lld-link", args.tools_dir)
386-
)
398+
if toolchain_type == "msvc" or args.force_ms_link:
399+
search_paths = []
400+
if toolchain_type != "msvc":
401+
search_paths.append(
402+
os.path.dirname(find_executable("cl", args.tools_dir))
403+
)
404+
self.linker = self._find_linker("link", search_paths)
405+
else:
406+
self.linker = self._find_linker("lld-link", args.tools_dir)
387407
if not self.linker:
388408
raise ValueError("Unable to find an appropriate linker.")
389409

390410
self.compile_env, self.link_env = self._get_visual_studio_environment()
411+
self.force_dwarf_symbols = args.force_dwarf_symbols
391412

392413
def _find_linker(self, name, search_paths=[]):
393414
compiler_dir = os.path.dirname(self.compiler)
@@ -678,6 +699,8 @@ def _get_compilation_command(self, source, obj):
678699
args.append("/GR-")
679700
args.append("/Z7")
680701
if self.toolchain_type == "clang-cl":
702+
if self.force_dwarf_symbols:
703+
args.append("-gdwarf")
681704
args.append("-Xclang")
682705
args.append("-fkeep-static-consts")
683706
args.append("-fms-compatibility-version=19")

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ Changes to LLDB
304304
stop reason = SIGSEGV: sent by tkill system call (sender pid=649752, uid=2667987)
305305
```
306306
* ELF Cores can now have their siginfo structures inspected using `thread siginfo`.
307+
* LLDB now detects when the names of known DWARF sections in a PECOFF file have
308+
been truncated by link.exe on Windows, and advises the user how to avoid this.
307309

308310
### Changes to lldb-dap
309311

0 commit comments

Comments
 (0)