diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 8 | ||||
| -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 |
7 files changed, 131 insertions, 71 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 024472db87c..0398d0f4c97 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -499,8 +499,9 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { // explicitly describe the directory of all files, never relying on the // compilation directory. if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU) - Asm->OutStreamer->getContext().setMCLineTableCompilationDir( - NewCU.getUniqueID(), CompilationDir); + Asm->OutStreamer->emitDwarfFile0Directive( + CompilationDir, FN, NewCU.getMD5AsBytes(DIUnit->getFile()), + DIUnit->getSource(), NewCU.getUniqueID()); StringRef Producer = DIUnit->getProducer(); StringRef Flags = DIUnit->getFlags(); @@ -2148,8 +2149,10 @@ void DwarfDebug::emitDebugStrDWO() { MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) { if (!useSplitDwarf()) return nullptr; - if (SingleCU) - SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode()->getDirectory()); + const DICompileUnit *DIUnit = CU.getCUNode(); + SplitTypeUnitFileTable.maybeSetRootFile( + DIUnit->getDirectory(), DIUnit->getFilename(), + CU.getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource()); return &SplitTypeUnitFileTable; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 811112a0430..4bbfb4704e6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -282,8 +282,10 @@ void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute, addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer); } -MD5::MD5Result *DwarfUnit::getMD5AsBytes(const DIFile *File) { +MD5::MD5Result *DwarfUnit::getMD5AsBytes(const DIFile *File) const { assert(File); + if (DD->getDwarfVersion() < 5) + return nullptr; Optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum(); if (!Checksum || Checksum->Kind != DIFile::CSK_MD5) return nullptr; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 328e3549e05..c1d46173567 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -306,6 +306,10 @@ public: const MCSymbol *Label, const MCSymbol *Sec); + /// If the \p File has an MD5 checksum, return it as an MD5Result + /// allocated in the MCContext. + MD5::MD5Result *getMD5AsBytes(const DIFile *File) const; + protected: ~DwarfUnit(); @@ -316,10 +320,6 @@ protected: /// create a new ID and insert it in the line table. virtual unsigned getOrCreateSourceID(const DIFile *File) = 0; - /// If the \p File has an MD5 checksum, return it as an MD5Result - /// allocated in the MCContext. - MD5::MD5Result *getMD5AsBytes(const DIFile *File); - /// Look in the DwarfDebug map for the MDNode that corresponds to the /// reference. template <typename T> T *resolve(TypedDINodeRef<T> Ref) const { 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, |

