Skip to content

Commit 0609233

Browse files
committed
[MC][DebugInfo] Consider the target when deciding what's a path separator
This patch teaches MCContext and DWARF linetable headers about path separators, or at least lets them store them, so that we can switch out the path separator at runtime. The use-case for this is targets where the development environment isn't the same as the compilers native environment, which can lead to differences in the computed DWARF directory tables in .debug_line.
1 parent a7b249e commit 0609233

File tree

6 files changed

+104
-14
lines changed

6 files changed

+104
-14
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ class MCContext {
335335

336336
MCTargetOptions const *TargetOptions;
337337

338+
llvm::sys::path::Style PathStyle = llvm::sys::path::Style::native;
339+
338340
bool HadError = false;
339341

340342
void reportCommon(SMLoc Loc,
@@ -721,14 +723,16 @@ class MCContext {
721723

722724
void setDwarfCompileUnitID(unsigned CUIndex) { DwarfCompileUnitID = CUIndex; }
723725

726+
llvm::sys::path::Style getPathStyle() const { return PathStyle; }
727+
724728
/// Specifies the "root" file and directory of the compilation unit.
725729
/// These are "file 0" and "directory 0" in DWARF v5.
726730
void setMCLineTableRootFile(unsigned CUID, StringRef CompilationDir,
727731
StringRef Filename,
728732
std::optional<MD5::MD5Result> Checksum,
729733
std::optional<StringRef> Source) {
730734
getMCDwarfLineTable(CUID).setRootFile(CompilationDir, Filename, Checksum,
731-
Source);
735+
Source, PathStyle);
732736
}
733737

734738
/// Reports whether MD5 checksum usage is consistent (all-or-none).

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/MC/StringTableBuilder.h"
2222
#include "llvm/Support/Error.h"
2323
#include "llvm/Support/MD5.h"
24+
#include "llvm/Support/Path.h"
2425
#include "llvm/Support/SMLoc.h"
2526
#include "llvm/Support/StringSaver.h"
2627
#include <cassert>
@@ -277,6 +278,7 @@ struct MCDwarfLineTableHeader {
277278
StringMap<unsigned> SourceIdMap;
278279
std::string CompilationDir;
279280
MCDwarfFile RootFile;
281+
llvm::sys::path::Style PathStyle = llvm::sys::path::Style::native;
280282
bool HasAnySource = false;
281283

282284
private:
@@ -311,7 +313,9 @@ struct MCDwarfLineTableHeader {
311313

312314
void setRootFile(StringRef Directory, StringRef FileName,
313315
std::optional<MD5::MD5Result> Checksum,
314-
std::optional<StringRef> Source) {
316+
std::optional<StringRef> Source,
317+
llvm::sys::path::Style S = llvm::sys::path::Style::native) {
318+
PathStyle = S;
315319
CompilationDir = std::string(Directory);
316320
RootFile.Name = std::string(FileName);
317321
RootFile.DirIndex = 0;
@@ -342,10 +346,11 @@ class MCDwarfDwoLineTable {
342346
public:
343347
void maybeSetRootFile(StringRef Directory, StringRef FileName,
344348
std::optional<MD5::MD5Result> Checksum,
345-
std::optional<StringRef> Source) {
349+
std::optional<StringRef> Source,
350+
llvm::sys::path::Style S) {
346351
if (!Header.RootFile.Name.empty())
347352
return;
348-
Header.setRootFile(Directory, FileName, Checksum, Source);
353+
Header.setRootFile(Directory, FileName, Checksum, Source, S);
349354
}
350355

351356
unsigned getFile(StringRef Directory, StringRef FileName,
@@ -394,7 +399,9 @@ class MCDwarfLineTable {
394399

395400
void setRootFile(StringRef Directory, StringRef FileName,
396401
std::optional<MD5::MD5Result> Checksum,
397-
std::optional<StringRef> Source) {
402+
std::optional<StringRef> Source,
403+
llvm::sys::path::Style S) {
404+
Header.PathStyle = S;
398405
Header.CompilationDir = std::string(Directory);
399406
Header.RootFile.Name = std::string(FileName);
400407
Header.RootFile.DirIndex = 0;

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3429,7 +3429,8 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
34293429
const DICompileUnit *DIUnit = CU.getCUNode();
34303430
SplitTypeUnitFileTable.maybeSetRootFile(
34313431
DIUnit->getDirectory(), DIUnit->getFilename(),
3432-
getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource());
3432+
getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource(),
3433+
Asm->OutStreamer->getContext().getPathStyle());
34333434
return &SplitTypeUnitFileTable;
34343435
}
34353436

llvm/lib/MC/MCContext.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
7777
SaveTempLabels = TargetOptions && TargetOptions->MCSaveTempLabels;
7878
SecureLogFile = TargetOptions ? TargetOptions->AsSecureLogFile : "";
7979

80+
if (TheTriple.isPS())
81+
PathStyle = llvm::sys::path::Style::windows;
82+
8083
if (SrcMgr && SrcMgr->getNumBuffers())
8184
MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())
8285
->getBufferIdentifier());
@@ -970,12 +973,12 @@ void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
970973
if (FileNameBuf.empty() || FileNameBuf == "-")
971974
FileNameBuf = "<stdin>";
972975
if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {
973-
llvm::sys::path::remove_filename(FileNameBuf);
974-
llvm::sys::path::append(FileNameBuf, getMainFileName());
976+
llvm::sys::path::remove_filename(FileNameBuf, PathStyle);
977+
llvm::sys::path::append(FileNameBuf, PathStyle, getMainFileName());
975978
}
976979
StringRef FileName = FileNameBuf;
977980
if (FileName.consume_front(getCompilationDir()))
978-
if (llvm::sys::path::is_separator(FileName.front()))
981+
if (llvm::sys::path::is_separator(FileName.front(), PathStyle))
979982
FileName = FileName.drop_front();
980983
assert(!FileName.empty());
981984
setMCLineTableRootFile(

llvm/lib/MC/MCDwarf.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -664,9 +664,9 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
664664

665665
if (Directory.empty()) {
666666
// Separate the directory part from the basename of the FileName.
667-
StringRef tFileName = sys::path::filename(FileName);
667+
StringRef tFileName = sys::path::filename(FileName, PathStyle);
668668
if (!tFileName.empty()) {
669-
Directory = sys::path::parent_path(FileName);
669+
Directory = sys::path::parent_path(FileName, PathStyle);
670670
if (!Directory.empty())
671671
FileName = tFileName;
672672
}
@@ -939,7 +939,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
939939
static void EmitGenDwarfInfo(MCStreamer *MCOS,
940940
const MCSymbol *AbbrevSectionSymbol,
941941
const MCSymbol *LineSectionSymbol,
942-
const MCSymbol *RangesSymbol) {
942+
const MCSymbol *RangesSymbol,
943+
llvm::sys::path::Style Style) {
943944
MCContext &context = MCOS->getContext();
944945

945946
MCOS->switchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -1037,7 +1038,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
10371038
const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
10381039
if (MCDwarfDirs.size() > 0) {
10391040
MCOS->emitBytes(MCDwarfDirs[0]);
1040-
MCOS->emitBytes(sys::path::get_separator());
1041+
MCOS->emitBytes(sys::path::get_separator(Style));
10411042
}
10421043
const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
10431044
// MCDwarfFiles might be empty if we have an empty source file.
@@ -1225,7 +1226,8 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
12251226
EmitGenDwarfAbbrev(MCOS);
12261227

12271228
// Output the data for .debug_info section.
1228-
EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1229+
EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol,
1230+
context.getPathStyle());
12291231
}
12301232

12311233
//
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
; RUN: llc %s -o - -filetype=obj -mtriple x86_64-pc-linux-gnu | llvm-dwarfdump - --debug-line | FileCheck %s --check-prefix=LINUX
2+
; RUN: llc %s -o - -filetype=obj -mtriple x86_64-sie-ps5 | llvm-dwarfdump - --debug-line | FileCheck %s --check-prefix=PS5
3+
;
4+
; UNSUPPORTED: system-windows
5+
;
6+
; Check that the DWARF-printing MC backend is willing to consider Windows '\'
7+
; characters as path separators so that it can build the directory index table.
8+
; On Linux, the Windows path separators below would been seen as part of the
9+
; filename, and so wouldn't be combined into a directory entry. Wheras on
10+
; Windows (or a target masquerading as Windows) they should be combined into a
11+
; "foo\bar" directory.
12+
;
13+
; LINUX: include_directories[ 0] = "C:\\foobar"
14+
; LINUX: file_names[ 0]:
15+
; LINUX: name: "foo\\bar\\test.cpp"
16+
; LINUX: dir_index: 0
17+
; LINUX: file_names[ 1]:
18+
; LINUX: name: "foo\\bar\\bar.cpp"
19+
; LINUX: dir_index: 0
20+
; LINUX: file_names[ 2]:
21+
; LINUX: name: "foo\\bar\\baz.cpp"
22+
; LINUX: dir_index: 0
23+
;
24+
; PS5: include_directories[ 0] = "C:\\foobar"
25+
; PS5-NEXT: include_directories[ 1] = "foo\\bar"
26+
; PS5-NEXT: file_names[ 0]:
27+
; PS5-NEXT: name: "foo\\bar\\test.cpp"
28+
; PS5-NEXT: dir_index: 0
29+
; PS5-NEXT: file_names[ 1]:
30+
; PS5-NEXT: name: "bar.cpp"
31+
; PS5-NEXT: dir_index: 1
32+
; PS5-NEXT: file_names[ 2]:
33+
; PS5-NEXT: name: "baz.cpp"
34+
; PS5-NEXT: dir_index: 1
35+
36+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
37+
38+
define dso_local noundef i32 @_Z3foov() local_unnamed_addr !dbg !9 {
39+
ret i32 0, !dbg !14
40+
}
41+
42+
define dso_local noundef i32 @_Z3barv() local_unnamed_addr !dbg !15 {
43+
ret i32 0, !dbg !17
44+
}
45+
46+
define dso_local noundef i32 @main() local_unnamed_addr !dbg !18 {
47+
ret i32 0, !dbg !19
48+
}
49+
50+
!llvm.dbg.cu = !{!0}
51+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
52+
!llvm.ident = !{!8}
53+
54+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
55+
!1 = !DIFile(filename: "foo\\bar\\test.cpp", directory: "C:\\foobar")
56+
!2 = !{i32 7, !"Dwarf Version", i32 5}
57+
!3 = !{i32 2, !"Debug Info Version", i32 3}
58+
!4 = !{i32 1, !"wchar_size", i32 4}
59+
!5 = !{i32 8, !"PIC Level", i32 2}
60+
!6 = !{i32 7, !"PIE Level", i32 2}
61+
!7 = !{i32 7, !"uwtable", i32 2}
62+
!8 = !{!"clang"}
63+
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
64+
!10 = !DIFile(filename: "foo\\bar\\bar.cpp", directory: "C:\\foobar")
65+
!11 = !DISubroutineType(types: !12)
66+
!12 = !{!13}
67+
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
68+
!14 = !DILocation(line: 2, column: 3, scope: !9)
69+
!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !16, file: !16, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
70+
!16 = !DIFile(filename: "foo\\bar\\baz.cpp", directory: "C:\\foobar")
71+
!17 = !DILocation(line: 2, column: 3, scope: !15)
72+
!18 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
73+
!19 = !DILocation(line: 4, column: 3, scope: !18)

0 commit comments

Comments
 (0)