mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[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 llvm-svn: 334710
This commit is contained in:
parent
ee8aa2671a
commit
fc9b585c42
@ -550,6 +550,11 @@ namespace llvm {
|
||||
Source);
|
||||
}
|
||||
|
||||
/// Reports whether MD5 checksum usage is consistent (all-or-none).
|
||||
bool isDwarfMD5UsageConsistent(unsigned CUID) const {
|
||||
return getMCDwarfLineTable(CUID).isMD5UsageConsistent();
|
||||
}
|
||||
|
||||
/// Saves the information from the currently parsed dwarf .loc directive
|
||||
/// and sets DwarfLocSeen. When the next instruction is assembled an entry
|
||||
/// in the line number table with this information and the address of the
|
||||
|
@ -215,9 +215,12 @@ struct MCDwarfLineTableHeader {
|
||||
StringMap<unsigned> SourceIdMap;
|
||||
StringRef CompilationDir;
|
||||
MCDwarfFile RootFile;
|
||||
bool HasMD5 = false;
|
||||
bool HasSource = false;
|
||||
private:
|
||||
bool HasAllMD5 = true;
|
||||
bool HasAnyMD5 = false;
|
||||
|
||||
public:
|
||||
MCDwarfLineTableHeader() = default;
|
||||
|
||||
Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
|
||||
@ -231,6 +234,17 @@ struct MCDwarfLineTableHeader {
|
||||
Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
||||
ArrayRef<char> SpecialOpcodeLengths,
|
||||
Optional<MCDwarfLineStr> &LineStr) const;
|
||||
void resetMD5Usage() {
|
||||
HasAllMD5 = true;
|
||||
HasAnyMD5 = false;
|
||||
}
|
||||
void trackMD5Usage(bool MD5Used) {
|
||||
HasAllMD5 &= MD5Used;
|
||||
HasAnyMD5 |= MD5Used;
|
||||
}
|
||||
bool isMD5UsageConsistent() const {
|
||||
return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
|
||||
}
|
||||
|
||||
private:
|
||||
void emitV2FileDirTables(MCStreamer *MCOS) const;
|
||||
@ -251,7 +265,7 @@ public:
|
||||
Header.RootFile.DirIndex = 0;
|
||||
Header.RootFile.Checksum = Checksum;
|
||||
Header.RootFile.Source = Source;
|
||||
Header.HasMD5 = (Checksum != nullptr);
|
||||
Header.trackMD5Usage(Checksum);
|
||||
Header.HasSource = Source.hasValue();
|
||||
}
|
||||
|
||||
@ -294,10 +308,19 @@ public:
|
||||
Header.RootFile.DirIndex = 0;
|
||||
Header.RootFile.Checksum = Checksum;
|
||||
Header.RootFile.Source = Source;
|
||||
Header.HasMD5 = (Checksum != nullptr);
|
||||
Header.trackMD5Usage(Checksum);
|
||||
Header.HasSource = Source.hasValue();
|
||||
}
|
||||
|
||||
void resetRootFile() {
|
||||
assert(Header.MCDwarfFiles.empty());
|
||||
Header.resetMD5Usage();
|
||||
Header.HasSource = false;
|
||||
}
|
||||
|
||||
// Report whether MD5 usage has been consistent (all-or-none).
|
||||
bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
|
||||
|
||||
MCSymbol *getLabel() const {
|
||||
return Header.Label;
|
||||
}
|
||||
|
@ -1171,6 +1171,9 @@ void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory,
|
||||
// .file 0 is new for DWARF v5.
|
||||
if (getContext().getDwarfVersion() < 5)
|
||||
return;
|
||||
// Inform MCDwarf about the root file.
|
||||
getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
|
||||
Source);
|
||||
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS1(Str);
|
||||
|
@ -350,7 +350,7 @@ void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
|
||||
}
|
||||
|
||||
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
|
||||
bool HasMD5, bool HasSource,
|
||||
bool EmitMD5, bool HasSource,
|
||||
Optional<MCDwarfLineStr> &LineStr) {
|
||||
assert(!DwarfFile.Name.empty());
|
||||
if (LineStr)
|
||||
@ -360,7 +360,7 @@ static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
|
||||
MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
|
||||
}
|
||||
MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
|
||||
if (HasMD5) {
|
||||
if (EmitMD5) {
|
||||
MD5::MD5Result *Cksum = DwarfFile.Checksum;
|
||||
MCOS->EmitBinaryData(
|
||||
StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()),
|
||||
@ -410,7 +410,7 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
|
||||
// directory index. We don't track file size/timestamp so don't emit them
|
||||
// in the v5 table. Emit MD5 checksums and source if we have them.
|
||||
uint64_t Entries = 2;
|
||||
if (HasMD5)
|
||||
if (HasAllMD5)
|
||||
Entries += 1;
|
||||
if (HasSource)
|
||||
Entries += 1;
|
||||
@ -420,7 +420,7 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
|
||||
: dwarf::DW_FORM_string);
|
||||
MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
|
||||
MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
|
||||
if (HasMD5) {
|
||||
if (HasAllMD5) {
|
||||
MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
|
||||
MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
|
||||
}
|
||||
@ -435,9 +435,9 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
|
||||
// explicitly, replicate file #1.
|
||||
MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
|
||||
emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
|
||||
HasMD5, HasSource, LineStr);
|
||||
HasAllMD5, HasSource, LineStr);
|
||||
for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
|
||||
emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasMD5, HasSource, LineStr);
|
||||
emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasSource, LineStr);
|
||||
}
|
||||
|
||||
std::pair<MCSymbol *, MCSymbol *>
|
||||
@ -554,9 +554,10 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
|
||||
Directory = "";
|
||||
}
|
||||
assert(!FileName.empty());
|
||||
// If any files have an MD5 checksum or embedded source, they all must.
|
||||
// Keep track of whether any or all files have an MD5 checksum.
|
||||
// If any files have embedded source, they all must.
|
||||
if (MCDwarfFiles.empty()) {
|
||||
HasMD5 = (Checksum != nullptr);
|
||||
trackMD5Usage(Checksum);
|
||||
HasSource = (Source != None);
|
||||
}
|
||||
if (FileNumber == 0) {
|
||||
@ -582,10 +583,6 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
|
||||
return make_error<StringError>("file number already allocated",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
// If any files have an MD5 checksum, they all must.
|
||||
if (HasMD5 != (Checksum != nullptr))
|
||||
return make_error<StringError>("inconsistent use of MD5 checksums",
|
||||
inconvertibleErrorCode());
|
||||
// If any files have embedded source, they all must.
|
||||
if (HasSource != (Source != None))
|
||||
return make_error<StringError>("inconsistent use of embedded source",
|
||||
@ -625,8 +622,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
|
||||
File.Name = FileName;
|
||||
File.DirIndex = DirIndex;
|
||||
File.Checksum = Checksum;
|
||||
if (Checksum)
|
||||
HasMD5 = true;
|
||||
trackMD5Usage(Checksum);
|
||||
File.Source = Source;
|
||||
if (Source)
|
||||
HasSource = true;
|
||||
|
@ -177,6 +177,9 @@ private:
|
||||
/// Are we parsing ms-style inline assembly?
|
||||
bool ParsingInlineAsm = false;
|
||||
|
||||
/// Did we already inform the user about inconsistent MD5 usage?
|
||||
bool ReportedInconsistentMD5 = false;
|
||||
|
||||
public:
|
||||
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
|
||||
const MCAsmInfo &MAI, unsigned CB);
|
||||
@ -3337,7 +3340,11 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
|
||||
|
||||
// In case there is a -g option as well as debug info from directive .file,
|
||||
// we turn off the -g option, directly use the existing debug info instead.
|
||||
getContext().setGenDwarfForAssembly(false);
|
||||
// Also reset any implicit ".file 0" for the assembler source.
|
||||
if (Ctx.getGenDwarfForAssembly()) {
|
||||
Ctx.getMCDwarfLineTable(0).resetRootFile();
|
||||
Ctx.setGenDwarfForAssembly(false);
|
||||
}
|
||||
|
||||
if (FileNumber == -1)
|
||||
getStreamer().EmitFileDirective(Filename);
|
||||
@ -3364,6 +3371,12 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
|
||||
return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
|
||||
FileNumber = FileNumOrErr.get();
|
||||
}
|
||||
// Alert the user if there are some .file directives with MD5 and some not.
|
||||
// But only do that once.
|
||||
if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
|
||||
ReportedInconsistentMD5 = true;
|
||||
return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -5,21 +5,21 @@
|
||||
; XFAIL: darwin
|
||||
|
||||
; REQUIRES: object-emission
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-4
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
|
||||
; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefix=OBJ
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
|
||||
; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
|
||||
|
||||
; ASM-4-NOT: .file 0
|
||||
; ASM-4: .file 1 "/scratch{{.*[/\\]}}t1.h"
|
||||
; ASM-4-NOT: md5
|
||||
; ASM-4: .file 2 "/scratch{{.*[/\\]}}t2.h"
|
||||
; ASM-4-NOT: md5
|
||||
; ASM-5: .file 0 "/scratch{{.*[/\\]}}t.c" md5 0x00000000000000000000000000000000
|
||||
; ASM: .file 1 "/scratch{{.*[/\\]}}t1.h"
|
||||
; ASM-4-NOT: md5
|
||||
; ASM-5-SAME: md5 0x11111111111111111111111111111111
|
||||
; ASM: .file 2 "/scratch{{.*[/\\]}}t2.h"
|
||||
; ASM-4-NOT: md5
|
||||
; ASM-5-SAME: md5 0x22222222222222222222222222222222
|
||||
; ASM-5: .file 1 "t1.h" md5 0x11111111111111111111111111111111
|
||||
; ASM-5: .file 2 "t2.h" md5 0x22222222222222222222222222222222
|
||||
|
||||
; OBJ-5: file_names[ 0]:
|
||||
; OBJ-5-NEXT: name: "t.c"
|
||||
|
@ -5,16 +5,18 @@
|
||||
; XFAIL: darwin
|
||||
|
||||
; REQUIRES: object-emission
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
|
||||
; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
|
||||
; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefixes=OBJ,OBJ-4
|
||||
; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
|
||||
; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
|
||||
|
||||
; ASM-4: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
|
||||
; ASM-4: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
|
||||
; ASM-5: .file 0 "/test{{.*[/\\]}}t.c" source "00000000000000000000000000000000"
|
||||
; ASM: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
|
||||
; ASM: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
|
||||
; ASM-5: .file 1 "t1.h" source "11111111111111111111111111111111"
|
||||
; ASM-5: .file 2 "t2.h" source "22222222222222222222222222222222"
|
||||
|
||||
; OBJ-5: file_names[ 0]:
|
||||
; OBJ-5-NEXT: name: "t.c"
|
||||
|
@ -22,5 +22,5 @@
|
||||
.file "baz" md5 0xffeeddccbbaa99887766554433221100
|
||||
|
||||
# Inconsistent use of MD5 option. Note: .file 1 did not supply one.
|
||||
# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: inconsistent use of MD5 checksums
|
||||
# CHECK: [[@LINE+1]]:{{[0-9]+}}: warning: inconsistent use of MD5 checksums
|
||||
.file 5 "bax" md5 0xffeeddccbbaa99887766554433221100
|
||||
|
44
test/MC/ELF/debug-mixed-md5.ll
Normal file
44
test/MC/ELF/debug-mixed-md5.ll
Normal file
@ -0,0 +1,44 @@
|
||||
; RUN: %llc_dwarf -filetype=asm -dwarf-version=5 %s -o - | FileCheck %s -check-prefix=ASM
|
||||
; RUN: %llc_dwarf -filetype=obj -dwarf-version=5 %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s -check-prefix=OBJ
|
||||
; ASM: .file 0 "{{.+}}" md5
|
||||
; ASM: .file 1 "{{.+}}" md5
|
||||
; ASM: .file 2 "t1.cpp"
|
||||
; ASM-NOT: md5
|
||||
; OBJ: file_names[ 0]:
|
||||
; OBJ-NOT: md5
|
||||
;
|
||||
; Generated from this source (see PR37623):
|
||||
;
|
||||
; #define a(...) template __VA_ARGS__;
|
||||
; template <class> class b {};
|
||||
; a(class b<int>)
|
||||
; # 1 ""
|
||||
; int c;
|
||||
|
||||
; ModuleID = 't1.cpp'
|
||||
source_filename = "t1.cpp"
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@c = global i32 0, align 4, !dbg !0
|
||||
|
||||
!llvm.dbg.cu = !{!2}
|
||||
!llvm.module.flags = !{!12, !13, !14}
|
||||
!llvm.ident = !{!15}
|
||||
|
||||
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
|
||||
!1 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true)
|
||||
!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)
|
||||
!3 = !DIFile(filename: "<stdin>", directory: "/home/probinson/projects/scratch", checksumkind: CSK_MD5, checksum: "9252ff18ee25a08c2b4216b21b5d66d4")
|
||||
!4 = !{}
|
||||
!5 = !{!6}
|
||||
!6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "b<int>", file: !7, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !4, templateParams: !8, identifier: "_ZTS1bIiE")
|
||||
!7 = !DIFile(filename: "t1.cpp", directory: "/home/probinson/projects/scratch")
|
||||
!8 = !{!9}
|
||||
!9 = !DITemplateTypeParameter(type: !10)
|
||||
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!11 = !{!0}
|
||||
!12 = !{i32 2, !"Dwarf Version", i32 5}
|
||||
!13 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!14 = !{i32 1, !"wchar_size", i32 4}
|
||||
!15 = !{!"clang version 7.0.0 "}
|
Loading…
Reference in New Issue
Block a user