diff options
author | Paul Robinson <paul.robinson@sony.com> | 2018-03-29 17:16:41 +0000 |
---|---|---|
committer | Paul Robinson <paul.robinson@sony.com> | 2018-03-29 17:16:41 +0000 |
commit | b271f31d8d31ad689958fb8ff75110c2db5515df (patch) | |
tree | 9fc7456a6408dc5f91f66d7975f02bfc378de9d6 /llvm/lib/MC | |
parent | 1b20416bfa4ed906d5b5f289aa8a4430b9620132 (diff) | |
download | bcm5719-llvm-b271f31d8d31ad689958fb8ff75110c2db5515df.tar.gz bcm5719-llvm-b271f31d8d31ad689958fb8ff75110c2db5515df.zip |
Reapply "[DWARFv5] Emit file 0 to the line table."
DWARF v5 specifies that the root file (also given in the DW_AT_name
attribute of the compilation unit DIE) should be emitted explicitly to
the line table's list of files. This makes the line table more
independent of the .debug_info section.
We emit the new syntax only for DWARF v5 and later.
Fixes the bug found by asan. Also XFAIL the new test for Darwin, which
is stuck on DWARF v2, and fix up other tests so they stop failing on
Windows. Last but not least, don't break "clang -g" of an assembler
file that has .file directives in it.
Differential Revision: https://reviews.llvm.org/D44054
llvm-svn: 328805
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 91 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 9 |
4 files changed, 117 insertions, 62 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index f30dd3eadbd..c1d74a0e94a 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -219,6 +219,10 @@ public: MD5::MD5Result *Checksum = 0, Optional<StringRef> Source = None, unsigned CUID = 0) override; + void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, + MD5::MD5Result *Checksum, + Optional<StringRef> Source, + unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, @@ -1077,21 +1081,12 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { EmitEOL(); } -Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( - unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, Optional<StringRef> Source, unsigned CUID) { - assert(CUID == 0); - - MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); - unsigned NumFiles = Table.getMCDwarfFiles().size(); - Expected<unsigned> FileNoOrErr = - Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo); - if (!FileNoOrErr) - return FileNoOrErr.takeError(); - FileNo = FileNoOrErr.get(); - if (NumFiles == Table.getMCDwarfFiles().size()) - return FileNo; - +static void printDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum, + Optional<StringRef> Source, + bool UseDwarfDirectory, + raw_svector_ostream &OS) { SmallString<128> FullPathName; if (!UseDwarfDirectory && !Directory.empty()) { @@ -1105,31 +1100,71 @@ Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( } } - SmallString<128> Str; - raw_svector_ostream OS1(Str); - OS1 << "\t.file\t" << FileNo << ' '; + OS << "\t.file\t" << FileNo << ' '; if (!Directory.empty()) { - PrintQuotedString(Directory, OS1); - OS1 << ' '; + PrintQuotedString(Directory, OS); + OS << ' '; } - PrintQuotedString(Filename, OS1); + PrintQuotedString(Filename, OS); if (Checksum) { - OS1 << " md5 "; - PrintQuotedString(Checksum->digest(), OS1); + OS << " md5 "; + PrintQuotedString(Checksum->digest(), OS); } if (Source) { - OS1 << " source "; - PrintQuotedString(*Source, OS1); + OS << " source "; + PrintQuotedString(*Source, OS); } - if (MCTargetStreamer *TS = getTargetStreamer()) { +} + +Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( + unsigned FileNo, StringRef Directory, StringRef Filename, + MD5::MD5Result *Checksum, Optional<StringRef> Source, unsigned CUID) { + assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer"); + + MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); + unsigned NumFiles = Table.getMCDwarfFiles().size(); + Expected<unsigned> FileNoOrErr = + Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo); + if (!FileNoOrErr) + return FileNoOrErr.takeError(); + FileNo = FileNoOrErr.get(); + if (NumFiles == Table.getMCDwarfFiles().size()) + return FileNo; + + SmallString<128> Str; + raw_svector_ostream OS1(Str); + printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source, + UseDwarfDirectory, OS1); + + if (MCTargetStreamer *TS = getTargetStreamer()) TS->emitDwarfFileDirective(OS1.str()); - } else { + else EmitRawText(OS1.str()); - } return FileNo; } +void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum, + Optional<StringRef> Source, + unsigned CUID) { + assert(CUID == 0); + // .file 0 is new for DWARF v5. + if (getContext().getDwarfVersion() < 5) + return; + + SmallString<128> Str; + raw_svector_ostream OS1(Str); + printDwarfFileDirective(0, Directory, Filename, Checksum, Source, + UseDwarfDirectory, OS1); + + if (MCTargetStreamer *TS = getTargetStreamer()) + TS->emitDwarfFileDirective(OS1.str()); + else + EmitRawText(OS1.str()); +} + void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 2da69fe1e4e..0e0ea965d14 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -349,6 +349,34 @@ void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const { MCOS->EmitIntValue(0, 1); // Terminate the file list. } +static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, + bool HasMD5, bool HasSource, + Optional<MCDwarfLineStr> &LineStr) { + assert(!DwarfFile.Name.empty()); + if (LineStr) + LineStr->emitRef(MCOS, DwarfFile.Name); + else { + MCOS->EmitBytes(DwarfFile.Name); // FileName and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + } + MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number. + if (HasMD5) { + MD5::MD5Result *Cksum = DwarfFile.Checksum; + MCOS->EmitBinaryData( + StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()), + Cksum->Bytes.size())); + } + if (HasSource) { + if (LineStr) + LineStr->emitRef(MCOS, DwarfFile.Source.getValueOr(StringRef())); + else { + MCOS->EmitBytes( + DwarfFile.Source.getValueOr(StringRef())); // Source and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + } + } +} + void MCDwarfLineTableHeader::emitV5FileDirTables( MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr) const { // The directory format, which is just a list of the directory paths. In a @@ -397,33 +425,12 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp : dwarf::DW_FORM_string); } - // Then the list of file names. These start at 1. - MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1); - for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) { - assert(!MCDwarfFiles[i].Name.empty()); - if (LineStr) - LineStr->emitRef(MCOS, MCDwarfFiles[i].Name); - else { - MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and... - MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. - } - MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number. - if (HasMD5) { - MD5::MD5Result *Cksum = MCDwarfFiles[i].Checksum; - MCOS->EmitBinaryData( - StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()), - Cksum->Bytes.size())); - } - if (HasSource) { - if (LineStr) - LineStr->emitRef(MCOS, MCDwarfFiles[i].Source.getValueOr(StringRef())); - else { - MCOS->EmitBytes( - MCDwarfFiles[i].Source.getValueOr(StringRef())); // Source and... - MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. - } - } - } + // Then the counted list of files. The root file is file #0, then emit the + // files as provide by .file directives. + MCOS->EmitULEB128IntValue(MCDwarfFiles.size()); + emitOneV5FileEntry(MCOS, RootFile, HasMD5, HasSource, LineStr); + for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) + emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasMD5, HasSource, LineStr); } std::pair<MCSymbol *, MCSymbol *> diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 3042f9964ff..8de6579fe3f 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3276,8 +3276,8 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { FileNumber = getTok().getIntVal(); Lex(); - if (FileNumber < 1) - return TokError("file number less than one"); + if (FileNumber < 0) + return TokError("negative file number"); } std::string Path = getTok().getString(); @@ -3356,11 +3356,15 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { memcpy(SourceBuf, SourceString.data(), SourceString.size()); Source = StringRef(SourceBuf, SourceString.size()); } - Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( - FileNumber, Directory, Filename, CKMem, Source); - if (!FileNumOrErr) - return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); - FileNumber = FileNumOrErr.get(); + if (FileNumber == 0) + getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source); + else { + Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( + FileNumber, Directory, Filename, CKMem, Source); + if (!FileNumOrErr) + return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); + FileNumber = FileNumOrErr.get(); + } } return false; diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 7d847c67605..776569894a5 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -199,6 +199,15 @@ MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, Source, CUID); } +void MCStreamer::emitDwarfFile0Directive(StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum, + Optional<StringRef> Source, + unsigned CUID) { + getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum, + Source); +} + void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, |