diff options
-rw-r--r-- | llvm/include/llvm/MC/MCContext.h | 7 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCDwarf.h | 15 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCStreamer.h | 19 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 9 | ||||
-rw-r--r-- | llvm/test/MC/ELF/debug-md5-err.s | 5 |
9 files changed, 83 insertions, 48 deletions
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index fb0e47cbfd6..7044ebb29a2 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -24,6 +24,7 @@ #include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MD5.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -493,9 +494,9 @@ namespace llvm { void setMainFileName(StringRef S) { MainFileName = S; } /// Creates an entry in the dwarf file and directory tables. - unsigned getDwarfFile(StringRef Directory, StringRef FileName, - unsigned FileNumber, MD5::MD5Result *Checksum, - unsigned CUID); + Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName, + unsigned FileNumber, + MD5::MD5Result *Checksum, unsigned CUID); bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0); diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index b4ccc725cbe..d39743e9327 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MD5.h" #include <cassert> #include <cstdint> @@ -213,8 +214,9 @@ struct MCDwarfLineTableHeader { MCDwarfLineTableHeader() = default; - unsigned getFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, unsigned FileNumber = 0); + Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName, + MD5::MD5Result *Checksum, + unsigned FileNumber = 0); std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, Optional<MCDwarfLineStr> &LineStr) const; @@ -239,7 +241,7 @@ public: unsigned getFile(StringRef Directory, StringRef FileName, MD5::MD5Result *Checksum) { - return Header.getFile(Directory, FileName, Checksum); + return cantFail(Header.tryGetFile(Directory, FileName, Checksum)); } void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params) const; @@ -257,8 +259,13 @@ public: void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params, Optional<MCDwarfLineStr> &LineStr) const; + Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName, + MD5::MD5Result *Checksum, + unsigned FileNumber = 0); unsigned getFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, unsigned FileNumber = 0); + MD5::MD5Result *Checksum, unsigned FileNumber = 0) { + return cantFail(tryGetFile(Directory, FileName, Checksum, FileNumber)); + } MCSymbol *getLabel() const { return Header.Label; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index c5171b1ae0f..3adad1504d7 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -23,6 +23,7 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCWinEH.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MD5.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/TargetParser.h" @@ -752,10 +753,20 @@ public: /// \brief Associate a filename with a specified logical file number. This /// implements the DWARF2 '.file 4 "foo.c"' assembler directive. - virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, - MD5::MD5Result *Checksum = nullptr, - unsigned CUID = 0); + unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum = nullptr, + unsigned CUID = 0) { + return cantFail( + tryEmitDwarfFileDirective(FileNo, Directory, Filename, Checksum, CUID)); + } + + /// Associate a filename with a specified logical file number. Returns a + /// StringError for any problem, or the file number. This implements the + /// DWARF2 '.file 4 "foo.c"' assembler directive. + virtual Expected<unsigned> tryEmitDwarfFileDirective( + unsigned FileNo, StringRef Directory, StringRef Filename, + MD5::MD5Result *Checksum = nullptr, unsigned CUID = 0); /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler /// directive. diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 927c1889c88..7ea5b7677b8 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -211,10 +211,11 @@ public: SMLoc Loc) override; void EmitFileDirective(StringRef Filename) override; - unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, - MD5::MD5Result *Checksum = 0, - unsigned CUID = 0) override; + Expected<unsigned> tryEmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum = 0, + unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, @@ -1073,18 +1074,18 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { EmitEOL(); } -unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, - StringRef Directory, - StringRef Filename, - MD5::MD5Result *Checksum, - unsigned CUID) { +Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( + unsigned FileNo, StringRef Directory, StringRef Filename, + MD5::MD5Result *Checksum, unsigned CUID) { assert(CUID == 0); MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); unsigned NumFiles = Table.getMCDwarfFiles().size(); - FileNo = Table.getFile(Directory, Filename, Checksum, FileNo); - if (FileNo == 0) - return 0; + Expected<unsigned> FileNoOrErr = + Table.tryGetFile(Directory, Filename, Checksum, FileNo); + if (!FileNoOrErr) + return FileNoOrErr.takeError(); + FileNo = FileNoOrErr.get(); if (NumFiles == Table.getMCDwarfFiles().size()) return FileNo; diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index c7c6ca7a86e..ea995288b28 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -536,11 +536,13 @@ MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the /// allocated file number is returned. The file numbers may be in any order. -unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName, - unsigned FileNumber, MD5::MD5Result *Checksum, - unsigned CUID) { +Expected<unsigned> MCContext::getDwarfFile(StringRef Directory, + StringRef FileName, + unsigned FileNumber, + MD5::MD5Result *Checksum, + unsigned CUID) { MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; - return Table.getFile(Directory, FileName, Checksum, FileNumber); + return Table.tryGetFile(Directory, FileName, Checksum, FileNumber); } /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 29c08440f4f..1f0fa78bffc 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -497,16 +497,17 @@ void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS, MCOS->EmitLabel(LineEndSym); } -unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, - unsigned FileNumber) { - return Header.getFile(Directory, FileName, Checksum, FileNumber); +Expected<unsigned> MCDwarfLineTable::tryGetFile(StringRef &Directory, + StringRef &FileName, + MD5::MD5Result *Checksum, + unsigned FileNumber) { + return Header.tryGetFile(Directory, FileName, Checksum, FileNumber); } -unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, - StringRef &FileName, - MD5::MD5Result *Checksum, - unsigned FileNumber) { +Expected<unsigned> MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, + StringRef &FileName, + MD5::MD5Result *Checksum, + unsigned FileNumber) { if (Directory == CompilationDir) Directory = ""; if (FileName.empty()) { @@ -514,6 +515,9 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, Directory = ""; } assert(!FileName.empty()); + // If any files have an MD5 checksum, they all must. + if (MCDwarfFiles.empty()) + HasMD5 = (Checksum != nullptr); if (FileNumber == 0) { // File numbers start with 1 and/or after any file numbers // allocated by inline-assembler .file directives. @@ -532,13 +536,15 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, // Get the new MCDwarfFile slot for this FileNumber. MCDwarfFile &File = MCDwarfFiles[FileNumber]; - // It is an error to use see the same number more than once. + // It is an error to see the same number more than once. if (!File.Name.empty()) - return 0; + return make_error<StringError>("file number already allocated", + inconvertibleErrorCode()); // If any files have an MD5 checksum, they all must. - if (FileNumber > 1) - assert(HasMD5 == (Checksum != nullptr)); + if (HasMD5 != (Checksum != nullptr)) + return make_error<StringError>("inconsistent use of MD5 checksums", + inconvertibleErrorCode()); if (Directory.empty()) { // Separate the directory part from the basename of the FileName. diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index e86e0d657dc..8ede318e0e1 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3254,7 +3254,6 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; - SMLoc FileNumberLoc = getLexer().getLoc(); if (getLexer().is(AsmToken::Integer)) { FileNumber = getTok().getIntVal(); Lex(); @@ -3321,9 +3320,13 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { // we turn off -g option, directly use the existing debug info instead. if (getContext().getGenDwarfForAssembly()) getContext().setGenDwarfForAssembly(false); - else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, - Filename, CKMem) == 0) - return Error(FileNumberLoc, "file number already allocated"); + else { + Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( + FileNumber, Directory, Filename, CKMem); + 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 a2c58e6cba4..ab6fd9c7bb0 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -188,11 +188,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); } -unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, - StringRef Directory, - StringRef Filename, - MD5::MD5Result *Checksum, - unsigned CUID) { +Expected<unsigned> +MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + MD5::MD5Result *Checksum, unsigned CUID) { return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, CUID); } diff --git a/llvm/test/MC/ELF/debug-md5-err.s b/llvm/test/MC/ELF/debug-md5-err.s index 989aecce7f2..fef628df80a 100644 --- a/llvm/test/MC/ELF/debug-md5-err.s +++ b/llvm/test/MC/ELF/debug-md5-err.s @@ -1,4 +1,5 @@ # RUN: not llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=asm %s -o /dev/null 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=obj %s -o /dev/null 2>&1 | FileCheck %s # This is syntactically legal, looks like no checksum provided. # CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error: @@ -19,3 +20,7 @@ # Non-DWARF .file syntax with checksum. # CHECK: [[@LINE+1]]:{{[0-9]+}}: error: MD5 checksum specified, but no file number .file "baz" md5 "ffeeddccbbaa998877665544332211gg" + +# Inconsistent use of MD5 option. Note: .file 1 did not supply one. +# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: inconsistent use of MD5 checksums + .file 5 "bax" md5 "ffeeddccbbaa99887766554433221100" |