Skip to content

Commit 1aa3ace

Browse files
Add support for reading and writing DW_FORM_implicit_const in MCCAS
In DWARF 5, there is a new form, DW_FORM_implicit_const, which encodes the value of the attribute in the debug_abbrev section, as a signed LEB128 number. This change adds support for being able to parse that and write it into MCCAS, as well as read it from a CASObject.
1 parent a414c21 commit 1aa3ace

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

llvm/lib/MCCAS/MCCASDebugV1.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,13 @@ void AbbrevEntryWriter::writeAbbrevEntry(DWARFDie DIE) {
255255
if (Form == dwarf::Form::DW_FORM_strp)
256256
Form = dwarf::Form::DW_FORM_strp_cas;
257257
writeULEB128(Form);
258+
// Dwarf 5: Section 7.4:
259+
// The form DW_FORM_implicit_const has to be handled specially. It's
260+
// specification contains a third part, which is a signed LEB128 number.
261+
// This number is used as the value of the attribute with the aformentioned
262+
// form and nothing is stored in the .debug_info section.
263+
if (Form == dwarf::Form::DW_FORM_implicit_const)
264+
writeSLEB128(AttrValue.Value.getRawSValue());
258265
}
259266
}
260267

@@ -281,11 +288,32 @@ Expected<dwarf::Attribute> AbbrevEntryReader::readAttr() {
281288
return static_cast<dwarf::Attribute>(AttrAsInt);
282289
}
283290

291+
static Expected<int64_t> handleImplicitConst(BinaryStreamReader &Reader) {
292+
int64_t ImplicitVal;
293+
if (auto E = Reader.readSLEB128(ImplicitVal))
294+
return E;
295+
return ImplicitVal;
296+
}
297+
284298
Expected<dwarf::Form> AbbrevEntryReader::readForm() {
285299
uint64_t FormAsInt;
286300
if (auto E = DataStream.readULEB128(FormAsInt))
287301
return std::move(E);
288-
return static_cast<dwarf::Form>(FormAsInt);
302+
auto Form = static_cast<dwarf::Form>(FormAsInt);
303+
304+
// Dwarf 5: Section 7.4:
305+
// The form DW_FORM_implicit_const has to be handled specially. It's
306+
// specification contains a third part, which is a signed LEB128 number. This
307+
// number is used as the value of the attribute with the aformentioned form
308+
// and nothing is stored in the .debug_info section.
309+
310+
// Advance reader to beyond the implicit_const value, to read Forms correctly.
311+
if (Form == dwarf::Form::DW_FORM_implicit_const) {
312+
auto ImplicitVal = handleImplicitConst(DataStream);
313+
if (!ImplicitVal)
314+
return ImplicitVal.takeError();
315+
}
316+
return Form;
289317
}
290318

291319
uint64_t
@@ -330,6 +358,18 @@ mccasformats::v1::reconstructAbbrevSection(raw_ostream &OS,
330358
Form = dwarf::Form::DW_FORM_strp;
331359

332360
WrittenSize += encodeULEB128(Form, OS);
361+
362+
// Dwarf 5: Section 7.4:
363+
// The form DW_FORM_implicit_const has to be handled specially. It's
364+
// specification contains a third part, which is a signed LEB128 number.
365+
// This number is used as the value of the attribute with the
366+
// aformentioned form and nothing is stored in the .debug_info section.
367+
if (Form == dwarf::Form::DW_FORM_implicit_const) {
368+
auto ImplicitVal = handleImplicitConst(Reader);
369+
if (!ImplicitVal)
370+
handleAllErrors(ImplicitVal.takeError());
371+
WrittenSize += encodeSLEB128(*ImplicitVal, OS);
372+
}
333373
}
334374

335375
// Dwarf 5: Section 7.5.3:

llvm/test/CAS/dwarf-5.ll

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
; RUN: rm -rf %t && mkdir -p %t
2+
; RUN: llc --filetype=obj --mccas-verify --cas-backend --cas=%t/cas %s -o %t/dwarf-5.o
3+
; RUN: dwarfdump %t/dwarf-5.o | FileCheck %s
4+
; CHECK: .debug_info contents:
5+
; CHECK-NEXT: 0x{{[0-9a-f]+}}: Compile Unit: length = 0x{{[0-9a-f]+}}, format = DWARF32, version = 0x0005
6+
7+
%"class.llvm::StringRef" = type { ptr, i64 }
8+
%"class.llvm::function_ref" = type { ptr, i64 }
9+
%"class.llvm::function_ref.1" = type { ptr, i64 }
10+
%"class.llvm::SmallString" = type { %"class.llvm::SmallVector" }
11+
%"class.llvm::SmallVector" = type { %"class.llvm::SmallVectorImpl.2" }
12+
%"class.llvm::SmallVectorImpl.2" = type { %"class.llvm::SmallVectorTemplateBase.3" }
13+
%"class.llvm::SmallVectorTemplateBase.3" = type { %"class.llvm::SmallVectorTemplateCommon.4" }
14+
%"class.llvm::SmallVectorTemplateCommon.4" = type { %"class.llvm::SmallVectorBase" }
15+
%"class.llvm::SmallVectorBase" = type { ptr, i64, i64 }
16+
define void @_ZN4llvm2cl26TokenizeWindowsCommandLineENS_9StringRefERNS_11StringSaverERNS_15SmallVectorImplIPKcEEb([2 x i64] %0, ptr noundef nonnull align 1 dereferenceable(1) %1, ptr noundef nonnull align 8 dereferenceable(24) %2, i1 noundef zeroext %3) #0 !dbg !114 {
17+
ret void, !dbg !195
18+
}
19+
define internal void @_ZL30tokenizeWindowsCommandLineImplN4llvm9StringRefERNS_11StringSaverENS_12function_refIFvS0_EEEbNS3_IFvvEEEb([2 x i64] %0, ptr noundef nonnull align 1 dereferenceable(1) %1, [2 x i64] %2, i1 noundef zeroext %3, [2 x i64] %4, i1 noundef zeroext %5) #0 !dbg !12 {
20+
%7 = alloca %"class.llvm::StringRef", align 8
21+
%8 = alloca %"class.llvm::function_ref", align 8
22+
%9 = alloca %"class.llvm::function_ref.1", align 8
23+
%10 = alloca ptr, align 8
24+
%11 = alloca i8, align 1
25+
%12 = alloca i8, align 1
26+
%13 = alloca %"class.llvm::SmallString", align 8
27+
%14 = alloca i32, align 4
28+
%15 = alloca i64, align 8
29+
%16 = alloca i64, align 8
30+
%17 = alloca %"class.llvm::StringRef", align 8
31+
%18 = zext i1 %3 to i8
32+
%19 = zext i1 %5 to i8
33+
%20 = call noundef ptr @_ZN4llvm11SmallStringILj128EEC1Ev(ptr noundef nonnull align 8 dereferenceable(24) %13), !dbg !256
34+
%21 = call noundef i64 @_ZNK4llvm9StringRef4sizeEv(ptr noundef nonnull align 8 dereferenceable(16) %7), !dbg !264
35+
br label %22, !dbg !265
36+
br label %22, !dbg !283, !llvm.loop !284
37+
}
38+
define internal noundef ptr @"_ZN4llvm12function_refIFvvEEC1IRZNS_2cl26TokenizeWindowsCommandLineENS_9StringRefERNS_11StringSaverERNS_15SmallVectorImplIPKcEEbE3$_1EEOT_PNSt3__19enable_ifIXooL_ZNSH_17integral_constantIbLb1EE5valueEEsr3std14is_convertibleIDTclclsr3stdE7declvalISF_EEEEvEE5valueEvE4typeE"(ptr noundef nonnull returned align 8 dereferenceable(16) %0, ptr noundef nonnull align 1 dereferenceable(1) %1, ptr noundef %2) unnamed_addr #3 align 2 !dbg !312 {
39+
%4 = alloca ptr, align 8
40+
%5 = alloca ptr, align 8
41+
%6 = alloca ptr, align 8
42+
%7 = load ptr, ptr %4, align 8
43+
ret ptr %7, !dbg !330
44+
}
45+
define linkonce_odr noundef ptr @_ZN4llvm11SmallStringILj128EEC1Ev(ptr noundef nonnull returned align 8 dereferenceable(24) %0) unnamed_addr #3 align 2 !dbg !331 {
46+
%2 = alloca ptr, align 8
47+
%3 = load ptr, ptr %2, align 8
48+
ret ptr %3, !dbg !339
49+
}
50+
define linkonce_odr noundef i64 @_ZNK4llvm9StringRef4sizeEv(ptr noundef nonnull align 8 dereferenceable(16) %0) #0 align 2 !dbg !340 {
51+
%2 = alloca ptr, align 8
52+
%3 = load ptr, ptr %2, align 8
53+
%4 = getelementptr inbounds %"class.llvm::StringRef", ptr %3, i32 0, i32 1, !dbg !344
54+
%5 = load i64, ptr %4, align 8, !dbg !344
55+
ret i64 %5, !dbg !345
56+
}
57+
declare void @llvm.trap() #4
58+
define linkonce_odr noundef ptr @_ZNSt3__122__uninitialized_fill_nIcPcmcEET0_S2_T1_RKT2_(ptr noundef %0, i64 noundef %1, ptr noundef nonnull align 1 dereferenceable(1) %2) #0 !dbg !469 {
59+
call void @llvm.trap(), !dbg !489
60+
unreachable, !dbg !491
61+
}
62+
define linkonce_odr noundef ptr @_ZN4llvm25SmallVectorTemplateCommonIcvE5beginEv(ptr noundef nonnull align 8 dereferenceable(24) %0) #0 align 2 !dbg !492 {
63+
%2 = alloca ptr, align 8
64+
%3 = load ptr, ptr %2, align 8
65+
%4 = getelementptr inbounds %"class.llvm::SmallVectorBase", ptr %3, i32 0, i32 0, !dbg !495
66+
%5 = load ptr, ptr %4, align 8, !dbg !495
67+
ret ptr %5, !dbg !496
68+
}
69+
!llvm.module.flags = !{!1, !2, !6}
70+
!llvm.dbg.cu = !{!7}
71+
!1 = !{i32 7, !"Dwarf Version", i32 5}
72+
!2 = !{i32 2, !"Debug Info Version", i32 3}
73+
!6 = !{i32 7, !"frame-pointer", i32 1}
74+
!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, emissionKind: FullDebug, sdk: "MacOSX14.0.sdk")
75+
!8 = !DIFile(filename: "/Users/shubham/Development/Delta/alternate/CommandLine.cpp", directory: "/Users/shubham/Development/Delta/alternate", checksumkind: CSK_MD5, checksum: "ed7ae158f20f7914bc5fb843291e80da")
76+
!12 = distinct !DISubprogram(name: "tokenizeWindowsCommandLineImpl", type: !13, unit: !7, retainedNodes: !36)
77+
!13 = !DISubroutineType(types: !14)
78+
!14 = !{}
79+
!32 = !DISubroutineType(types: !33)
80+
!33 = !{}
81+
!36 = !{}
82+
!101 = !DISubroutineType(types: !102)
83+
!102 = !{}
84+
!114 = distinct !DISubprogram(name: "TokenizeWindowsCommandLine", type: !116, unit: !7, retainedNodes: !36)
85+
!116 = !DISubroutineType(types: !117)
86+
!117 = !{}
87+
!195 = !DILocation(line: 428, scope: !114)
88+
!256 = !DILocation(line: 410, scope: !12)
89+
!260 = distinct !DILexicalBlock(scope: !12, line: 412, column: 3)
90+
!264 = !DILocation(line: 412, scope: !260)
91+
!265 = !DILocation(line: 412, scope: !260)
92+
!267 = distinct !DILexicalBlock(scope: !260, line: 412, column: 20)
93+
!283 = !DILocation(line: 412, scope: !267)
94+
!284 = distinct !{}
95+
!312 = distinct !DISubprogram(name: "function_ref<(lambda at /Users/shubham/Development/Delta/alternate/CommandLine.cpp:424:16) &>", type: !313, unit: !7, retainedNodes: !36)
96+
!313 = !DISubroutineType(types: !314)
97+
!314 = !{}
98+
!330 = !DILocation(line: 348, scope: !312)
99+
!331 = distinct !DISubprogram(name: "SmallString", type: !332, unit: !7, retainedNodes: !36)
100+
!332 = !DISubroutineType(types: !333)
101+
!333 = !{}
102+
!339 = !DILocation(line: 399, scope: !331)
103+
!340 = distinct !DISubprogram(name: "size", type: !32, unit: !7, retainedNodes: !36)
104+
!344 = !DILocation(line: 372, scope: !340)
105+
!345 = !DILocation(line: 372, scope: !340)
106+
!444 = !DISubroutineType(types: !445)
107+
!445 = !{}
108+
!462 = distinct !DISubprogram(name: "end", scope: !462)
109+
!469 = distinct !DISubprogram(name: "__uninitialized_fill_n<char, char>", type: !444, unit: !7, retainedNodes: !36)
110+
!483 = distinct !DISubprogram(name: "__voidify<char>", unit: !7, retainedNodes: !36)
111+
!488 = distinct !DILocation(line: 214, scope: !469)
112+
!489 = !DILocation(line: 137, scope: !483, inlinedAt: !488)
113+
!491 = !DILocation(line: 214, scope: !469)
114+
!492 = distinct !DISubprogram(name: "begin", type: !101, unit: !7, retainedNodes: !36)
115+
!495 = !DILocation(line: 290, scope: !492)
116+
!496 = !DILocation(line: 290, scope: !492)

0 commit comments

Comments
 (0)