llvm.org GIT mirror llvm / d796da8
[DWARFv5] Tolerate files not all having an MD5 checksum. In some cases, for example when compiling a preprocessed file, the front-end is not able to provide an MD5 checksum for all files. When that happens, omit the MD5 checksums from the final DWARF, because DWARF doesn't have a way to indicate that some but not all files have a checksum. When assembling a .s file, and some but not all .file directives provide an MD5 checksum, issue a warning and don't emit MD5 into the DWARF. Fixes PR37623. Differential Revision: https://reviews.llvm.org/D48135 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334710 91177308-0d34-0410-b5e6-96231b3b80d8 Paul Robinson 2 years ago
9 changed file(s) with 118 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
547547 Optional Source) {
548548 getMCDwarfLineTable(CUID).setRootFile(CompilationDir, Filename, Checksum,
549549 Source);
550 }
551
552 /// Reports whether MD5 checksum usage is consistent (all-or-none).
553 bool isDwarfMD5UsageConsistent(unsigned CUID) const {
554 return getMCDwarfLineTable(CUID).isMD5UsageConsistent();
550555 }
551556
552557 /// Saves the information from the currently parsed dwarf .loc directive
214214 StringMap SourceIdMap;
215215 StringRef CompilationDir;
216216 MCDwarfFile RootFile;
217 bool HasMD5 = false;
218217 bool HasSource = false;
219
218 private:
219 bool HasAllMD5 = true;
220 bool HasAnyMD5 = false;
221
222 public:
220223 MCDwarfLineTableHeader() = default;
221224
222225 Expected tryGetFile(StringRef &Directory, StringRef &FileName,
230233 Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
231234 ArrayRef SpecialOpcodeLengths,
232235 Optional &LineStr) const;
236 void resetMD5Usage() {
237 HasAllMD5 = true;
238 HasAnyMD5 = false;
239 }
240 void trackMD5Usage(bool MD5Used) {
241 HasAllMD5 &= MD5Used;
242 HasAnyMD5 |= MD5Used;
243 }
244 bool isMD5UsageConsistent() const {
245 return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
246 }
233247
234248 private:
235249 void emitV2FileDirTables(MCStreamer *MCOS) const;
250264 Header.RootFile.DirIndex = 0;
251265 Header.RootFile.Checksum = Checksum;
252266 Header.RootFile.Source = Source;
253 Header.HasMD5 = (Checksum != nullptr);
267 Header.trackMD5Usage(Checksum);
254268 Header.HasSource = Source.hasValue();
255269 }
256270
293307 Header.RootFile.DirIndex = 0;
294308 Header.RootFile.Checksum = Checksum;
295309 Header.RootFile.Source = Source;
296 Header.HasMD5 = (Checksum != nullptr);
310 Header.trackMD5Usage(Checksum);
297311 Header.HasSource = Source.hasValue();
298312 }
313
314 void resetRootFile() {
315 assert(Header.MCDwarfFiles.empty());
316 Header.resetMD5Usage();
317 Header.HasSource = false;
318 }
319
320 // Report whether MD5 usage has been consistent (all-or-none).
321 bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
299322
300323 MCSymbol *getLabel() const {
301324 return Header.Label;
11701170 // .file 0 is new for DWARF v5.
11711171 if (getContext().getDwarfVersion() < 5)
11721172 return;
1173 // Inform MCDwarf about the root file.
1174 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1175 Source);
11731176
11741177 SmallString<128> Str;
11751178 raw_svector_ostream OS1(Str);
349349 }
350350
351351 static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
352 bool HasMD5, bool HasSource,
352 bool EmitMD5, bool HasSource,
353353 Optional &LineStr) {
354354 assert(!DwarfFile.Name.empty());
355355 if (LineStr)
359359 MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
360360 }
361361 MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
362 if (HasMD5) {
362 if (EmitMD5) {
363363 MD5::MD5Result *Cksum = DwarfFile.Checksum;
364364 MCOS->EmitBinaryData(
365365 StringRef(reinterpret_cast(Cksum->Bytes.data()),
409409 // directory index. We don't track file size/timestamp so don't emit them
410410 // in the v5 table. Emit MD5 checksums and source if we have them.
411411 uint64_t Entries = 2;
412 if (HasMD5)
412 if (HasAllMD5)
413413 Entries += 1;
414414 if (HasSource)
415415 Entries += 1;
419419 : dwarf::DW_FORM_string);
420420 MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
421421 MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
422 if (HasMD5) {
422 if (HasAllMD5) {
423423 MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
424424 MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
425425 }
434434 // explicitly, replicate file #1.
435435 MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
436436 emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
437 HasMD5, HasSource, LineStr);
437 HasAllMD5, HasSource, LineStr);
438438 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
439 emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasMD5, HasSource, LineStr);
439 emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasSource, LineStr);
440440 }
441441
442442 std::pair
553553 Directory = "";
554554 }
555555 assert(!FileName.empty());
556 // If any files have an MD5 checksum or embedded source, they all must.
556 // Keep track of whether any or all files have an MD5 checksum.
557 // If any files have embedded source, they all must.
557558 if (MCDwarfFiles.empty()) {
558 HasMD5 = (Checksum != nullptr);
559 trackMD5Usage(Checksum);
559560 HasSource = (Source != None);
560561 }
561562 if (FileNumber == 0) {
581582 return make_error("file number already allocated",
582583 inconvertibleErrorCode());
583584
584 // If any files have an MD5 checksum, they all must.
585 if (HasMD5 != (Checksum != nullptr))
586 return make_error("inconsistent use of MD5 checksums",
587 inconvertibleErrorCode());
588585 // If any files have embedded source, they all must.
589586 if (HasSource != (Source != None))
590587 return make_error("inconsistent use of embedded source",
624621 File.Name = FileName;
625622 File.DirIndex = DirIndex;
626623 File.Checksum = Checksum;
627 if (Checksum)
628 HasMD5 = true;
624 trackMD5Usage(Checksum);
629625 File.Source = Source;
630626 if (Source)
631627 HasSource = true;
175175
176176 /// Are we parsing ms-style inline assembly?
177177 bool ParsingInlineAsm = false;
178
179 /// Did we already inform the user about inconsistent MD5 usage?
180 bool ReportedInconsistentMD5 = false;
178181
179182 public:
180183 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
33363339
33373340 // In case there is a -g option as well as debug info from directive .file,
33383341 // we turn off the -g option, directly use the existing debug info instead.
3339 getContext().setGenDwarfForAssembly(false);
3342 // Also reset any implicit ".file 0" for the assembler source.
3343 if (Ctx.getGenDwarfForAssembly()) {
3344 Ctx.getMCDwarfLineTable(0).resetRootFile();
3345 Ctx.setGenDwarfForAssembly(false);
3346 }
33403347
33413348 if (FileNumber == -1)
33423349 getStreamer().EmitFileDirective(Filename);
33623369 if (!FileNumOrErr)
33633370 return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
33643371 FileNumber = FileNumOrErr.get();
3372 }
3373 // Alert the user if there are some .file directives with MD5 and some not.
3374 // But only do that once.
3375 if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
3376 ReportedInconsistentMD5 = true;
3377 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
33653378 }
33663379 }
33673380
44 ; XFAIL: darwin
55
66 ; REQUIRES: object-emission
7 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-4
8 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
7 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
8 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
99 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
1010 ; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefix=OBJ
1111 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
1212 ; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
1313
1414 ; ASM-4-NOT: .file 0
15 ; ASM-4: .file 1 "/scratch{{.*[/\\]}}t1.h"
16 ; ASM-4-NOT: md5
17 ; ASM-4: .file 2 "/scratch{{.*[/\\]}}t2.h"
18 ; ASM-4-NOT: md5
1519 ; ASM-5: .file 0 "/scratch{{.*[/\\]}}t.c" md5 0x00000000000000000000000000000000
16 ; ASM: .file 1 "/scratch{{.*[/\\]}}t1.h"
17 ; ASM-4-NOT: md5
18 ; ASM-5-SAME: md5 0x11111111111111111111111111111111
19 ; ASM: .file 2 "/scratch{{.*[/\\]}}t2.h"
20 ; ASM-4-NOT: md5
21 ; ASM-5-SAME: md5 0x22222222222222222222222222222222
20 ; ASM-5: .file 1 "t1.h" md5 0x11111111111111111111111111111111
21 ; ASM-5: .file 2 "t2.h" md5 0x22222222222222222222222222222222
2222
2323 ; OBJ-5: file_names[ 0]:
2424 ; OBJ-5-NEXT: name: "t.c"
44 ; XFAIL: darwin
55
66 ; REQUIRES: object-emission
7 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM
8 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
7 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
8 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
99 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
1010 ; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefixes=OBJ,OBJ-4
1111 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
1212 ; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
1313
14 ; ASM-4: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
15 ; ASM-4: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
1416 ; ASM-5: .file 0 "/test{{.*[/\\]}}t.c" source "00000000000000000000000000000000"
15 ; ASM: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
16 ; ASM: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
17 ; ASM-5: .file 1 "t1.h" source "11111111111111111111111111111111"
18 ; ASM-5: .file 2 "t2.h" source "22222222222222222222222222222222"
1719
1820 ; OBJ-5: file_names[ 0]:
1921 ; OBJ-5-NEXT: name: "t.c"
2121 .file "baz" md5 0xffeeddccbbaa99887766554433221100
2222
2323 # Inconsistent use of MD5 option. Note: .file 1 did not supply one.
24 # CHECK: [[@LINE+1]]:{{[0-9]+}}: error: inconsistent use of MD5 checksums
24 # CHECK: [[@LINE+1]]:{{[0-9]+}}: warning: inconsistent use of MD5 checksums
2525 .file 5 "bax" md5 0xffeeddccbbaa99887766554433221100
0 ; RUN: %llc_dwarf -filetype=asm -dwarf-version=5 %s -o - | FileCheck %s -check-prefix=ASM
1 ; RUN: %llc_dwarf -filetype=obj -dwarf-version=5 %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s -check-prefix=OBJ
2 ; ASM: .file 0 "{{.+}}" md5
3 ; ASM: .file 1 "{{.+}}" md5
4 ; ASM: .file 2 "t1.cpp"
5 ; ASM-NOT: md5
6 ; OBJ: file_names[ 0]:
7 ; OBJ-NOT: md5
8 ;
9 ; Generated from this source (see PR37623):
10 ;
11 ; #define a(...) template __VA_ARGS__;
12 ; template class b {};
13 ; a(class b)
14 ; # 1 ""
15 ; int c;
16
17 ; ModuleID = 't1.cpp'
18 source_filename = "t1.cpp"
19 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
20 target triple = "x86_64-unknown-linux-gnu"
21
22 @c = global i32 0, align 4, !dbg !0
23
24 !llvm.dbg.cu = !{!2}
25 !llvm.module.flags = !{!12, !13, !14}
26 !llvm.ident = !{!15}
27
28 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
29 !1 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true)
30 !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !11)
31 !3 = !DIFile(filename: "", directory: "/home/probinson/projects/scratch", checksumkind: CSK_MD5, checksum: "9252ff18ee25a08c2b4216b21b5d66d4")
32 !4 = !{}
33 !5 = !{!6}
34 !6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "b", file: !7, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !4, templateParams: !8, identifier: "_ZTS1bIiE")
35 !7 = !DIFile(filename: "t1.cpp", directory: "/home/probinson/projects/scratch")
36 !8 = !{!9}
37 !9 = !DITemplateTypeParameter(type: !10)
38 !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
39 !11 = !{!0}
40 !12 = !{i32 2, !"Dwarf Version", i32 5}
41 !13 = !{i32 2, !"Debug Info Version", i32 3}
42 !14 = !{i32 1, !"wchar_size", i32 4}
43 !15 = !{!"clang version 7.0.0 "}