Skip to content

Commit d20e4a1

Browse files
committed
[DebugInfo] Fix potential CU mismatch for attachRangesOrLowHighPC
When a CU attaches some ranges for a subprogram or an inlined code, the CU should be that of the subprogram/inlined code that was emitted. If not, then these emitted ranges will use the incorrect base of the CU in `emitRangeList`. A reproducible example is: When linking these two LLVM IRs, dsymutil will report no mapping for range or inconsistent range data warnings. `foo.swift` ```swift import AppKit.NSLayoutConstraint public class Foo { public var c: Int { get { Int(NSLayoutConstraint().constant) } set { } } } ``` `main.swift` ```swift // no mapping for range let f: Foo! = nil // inconsistent range data //let l: Foo = Foo() ``` Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D136039
1 parent fc26a75 commit d20e4a1

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,12 @@ void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
445445
// scope then create and insert DIEs for these variables.
446446
DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
447447
DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
448+
auto *ContextCU = static_cast<DwarfCompileUnit *>(SPDie->getUnit());
449+
return ContextCU->updateSubprogramScopeDIEImpl(SP, SPDie);
450+
}
448451

452+
DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
453+
DIE *SPDie) {
449454
SmallVector<RangeSpan, 2> BB_List;
450455
// If basic block sections are on, ranges for each basic block section has
451456
// to be emitted separately.
@@ -1015,15 +1020,18 @@ sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
10151020
DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
10161021
LexicalScope *Scope) {
10171022
DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
1023+
auto *ContextCU = static_cast<DwarfCompileUnit *>(ScopeDIE.getUnit());
10181024

10191025
if (Scope) {
10201026
assert(!Scope->getInlinedAt());
10211027
assert(!Scope->isAbstractScope());
10221028
// Collect lexical scope children first.
10231029
// ObjectPointer might be a local (non-argument) local variable if it's a
10241030
// block's synthetic this pointer.
1025-
if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
1026-
addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
1031+
if (DIE *ObjectPointer =
1032+
ContextCU->createAndAddScopeChildren(Scope, ScopeDIE))
1033+
ContextCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer,
1034+
*ObjectPointer);
10271035
}
10281036

10291037
// If this is a variadic function, add an unspecified parameter.

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class DwarfCompileUnit final : public DwarfUnit {
192192
/// variables in this scope then create and insert DIEs for these
193193
/// variables.
194194
DIE &updateSubprogramScopeDIE(const DISubprogram *SP);
195+
DIE &updateSubprogramScopeDIEImpl(const DISubprogram *SP, DIE *SPDie);
195196

196197
void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);
197198

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
; RUN: %llc_dwarf %s -O0 -filetype=obj -o %t.o
2+
; RUN: llvm-dwarfdump %t.o --debug-info --verify
3+
4+
; We want to check that when the CU attaches ranges use the correct ContextCU.
5+
; In the following example, after accessing `@foo`, `bar` an `inlined_baz` are created in `foo.swift` CU.
6+
; Setting ranges in `@bar` will then use `bar.swift` CU.
7+
; An incorrect address is eventually calculated based on Base.
8+
9+
; The origin code is:
10+
; foo.swift
11+
; import AppKit.NSLayoutConstraint
12+
; public class Foo {
13+
; public var c: Int {
14+
; get {
15+
; Int(NSLayoutConstraint().constant)
16+
; }
17+
; set {
18+
; }
19+
; }
20+
; }
21+
; main.swift
22+
; // no mapping for range
23+
; let f: Foo! = nil
24+
25+
; After LTO, `main.swift` will create a global variable, then `Foo` (and relative DIE) created in `main.swift` CU.
26+
27+
define void @foo() !dbg !6 {
28+
ret void, !dbg !9
29+
}
30+
31+
define void @bar(i32* %0) !dbg !15 {
32+
store i32 1, i32* %0, align 4, !dbg !16
33+
store i32 1, i32* %0, align 4, !dbg !21
34+
ret void, !dbg !16
35+
}
36+
37+
!llvm.dbg.cu = !{!0, !2}
38+
!llvm.module.flags = !{!4, !5}
39+
40+
!0 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !1, isOptimized: true, runtimeVersion: 5, emissionKind: FullDebug)
41+
!1 = !DIFile(filename: "foo.swift", directory: "")
42+
!2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, isOptimized: true, runtimeVersion: 5, emissionKind: FullDebug)
43+
!3 = !DIFile(filename: "bar.swift", directory: "")
44+
!4 = !{i32 7, !"Dwarf Version", i32 4}
45+
!5 = !{i32 2, !"Debug Info Version", i32 3}
46+
!6 = distinct !DISubprogram(name: "foo", scope: !0, type: !7, spFlags: DISPFlagDefinition, unit: !0)
47+
!7 = !DISubroutineType(types: !8)
48+
!8 = !{}
49+
!9 = !DILocation(line: 0, scope: !10, inlinedAt: !13)
50+
!10 = distinct !DISubprogram(name: "init", scope: !12, file: !11, type: !7, spFlags: DISPFlagDefinition, unit: !0)
51+
!11 = !DIFile(filename: "<compiler-generated>", directory: "")
52+
!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Type", file: !3, runtimeLang: DW_LANG_Swift, identifier: "Type")
53+
!13 = !DILocation(line: 0, scope: !14)
54+
!14 = distinct !DILexicalBlock(scope: !6, file: !1)
55+
!15 = distinct !DISubprogram(name: "bar", scope: !12, type: !7, spFlags: DISPFlagDefinition, unit: !2)
56+
!16 = !DILocation(line: 0, scope: !17, inlinedAt: !19)
57+
!17 = distinct !DILexicalBlock(scope: !18, file: !3)
58+
!18 = distinct !DISubprogram(name: "inlined_baz", scope: !12, file: !3, type: !7, spFlags: DISPFlagDefinition, unit: !2)
59+
!19 = !DILocation(line: 0, scope: !20)
60+
!20 = distinct !DILexicalBlock(scope: !15, file: !3)
61+
!21 = !DILocation(line: 0, scope: !15)

0 commit comments

Comments
 (0)