diff options
author | Paul Robinson <paul.robinson@sony.com> | 2018-01-09 23:31:48 +0000 |
---|---|---|
committer | Paul Robinson <paul.robinson@sony.com> | 2018-01-09 23:31:48 +0000 |
commit | 29f5f987f1b76b5c43310b2062c9f447667a4f80 (patch) | |
tree | e19e9304ed5003b04e3a2a2b88c3c833df6a6c1e /llvm/lib/MC | |
parent | d72f78e7c8d6dbef66cdbee0292237c68d780160 (diff) | |
download | bcm5719-llvm-29f5f987f1b76b5c43310b2062c9f447667a4f80.tar.gz bcm5719-llvm-29f5f987f1b76b5c43310b2062c9f447667a4f80.zip |
[DWARFv5] MC support for MD5 file checksums
Extend .file directive syntax to allow specifying an MD5 checksum for
the source file. Emit the checksums in DWARF v5 line tables.
llvm-svn: 322134
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 33 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 39 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 6 |
5 files changed, 68 insertions, 19 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index b82dcbdc0f7..94af2881af7 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -212,6 +212,7 @@ public: void EmitFileDirective(StringRef Filename) override; unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, + MD5::MD5Result *Checksum = 0, unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, @@ -1068,12 +1069,13 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { unsigned MCAsmStreamer::EmitDwarfFileDirective(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, FileNo); + FileNo = Table.getFile(Directory, Filename, Checksum, FileNo); if (FileNo == 0) return 0; if (NumFiles == Table.getMCDwarfFiles().size()) diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 5c25e902bbe..ac2e45484ed 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -535,9 +535,10 @@ MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { /// 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, unsigned CUID) { + unsigned FileNumber, MD5::MD5Result *Checksum, + unsigned CUID) { MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; - return Table.getFile(Directory, FileName, FileNumber); + return Table.getFile(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 9e5d9ff73c7..62af6d851bf 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -284,7 +284,7 @@ static void emitV5FileDirTables(MCStreamer *MCOS, const SmallVectorImpl<std::string> &MCDwarfDirs, const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles, - StringRef CompilationDir) { + StringRef CompilationDir, bool HasMD5) { // The directory format, which is just inline null-terminated strings. MCOS->EmitIntValue(1, 1); MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path); @@ -300,20 +300,29 @@ emitV5FileDirTables(MCStreamer *MCOS, // The file format, which is the inline null-terminated filename and a // directory index. We don't track file size/timestamp so don't emit them - // in the v5 table. - // FIXME: Arrange to emit MD5 signatures for the source files. - MCOS->EmitIntValue(2, 1); + // in the v5 table. Emit MD5 checksums if we have them. + MCOS->EmitIntValue(HasMD5 ? 3 : 2, 1); MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path); MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string); MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index); MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata); - // Then the list of file names. These start at 1 for some reason. + if (HasMD5) { + MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5); + MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16); + } + // 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()); 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())); + } } } @@ -384,7 +393,8 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, // Put out the directory and file tables. The formats vary depending on // the version. if (LineTableVersion >= 5) - emitV5FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles, CompilationDir); + emitV5FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles, CompilationDir, + HasMD5); else emitV2FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles); @@ -409,12 +419,14 @@ void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS, } unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName, + MD5::MD5Result *Checksum, unsigned FileNumber) { - return Header.getFile(Directory, FileName, FileNumber); + return Header.getFile(Directory, FileName, Checksum, FileNumber); } unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, StringRef &FileName, + MD5::MD5Result *Checksum, unsigned FileNumber) { if (Directory == CompilationDir) Directory = ""; @@ -445,6 +457,10 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, if (!File.Name.empty()) return 0; + // If any files have an MD5 checksum, they all must. + if (FileNumber > 1) + assert(HasMD5 == (Checksum != nullptr)); + if (Directory.empty()) { // Separate the directory part from the basename of the FileName. StringRef tFileName = sys::path::filename(FileName); @@ -478,6 +494,9 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, File.Name = FileName; File.DirIndex = DirIndex; + File.Checksum = Checksum; + if (Checksum) + HasMD5 = true; // return the allocated FileNumber. return FileNumber; diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 2259136c6ec..17ad4e561e3 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -50,6 +50,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SMLoc.h" @@ -3294,8 +3295,8 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { } /// parseDirectiveFile -/// ::= .file [number] filename -/// ::= .file number directory filename +/// ::= .file filename +/// ::= .file number [directory] filename [md5 checksum] bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; @@ -3331,19 +3332,43 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { Filename = Path; } - if (parseToken(AsmToken::EndOfStatement, - "unexpected token in '.file' directive")) - return true; + std::string Checksum; + if (!parseOptionalToken(AsmToken::EndOfStatement)) { + StringRef Keyword; + if (check(getTok().isNot(AsmToken::Identifier), + "unexpected token in '.file' directive") || + parseIdentifier(Keyword) || + check(Keyword != "md5", "unexpected token in '.file' directive")) + return true; + if (getLexer().is(AsmToken::String) && + check(FileNumber == -1, "MD5 checksum specified, but no file number")) + return true; + if (check(getTok().isNot(AsmToken::String), + "unexpected token in '.file' directive") || + parseEscapedString(Checksum) || + check(Checksum.size() != 32, "invalid MD5 checksum specified") || + parseToken(AsmToken::EndOfStatement, + "unexpected token in '.file' directive")) + return true; + } if (FileNumber == -1) getStreamer().EmitFileDirective(Filename); else { + MD5::MD5Result *CKMem = nullptr; + if (!Checksum.empty()) { + Checksum = fromHex(Checksum); + if (check(Checksum.size() != 16, "invalid MD5 checksum specified")) + return true; + CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1); + memcpy(&CKMem->Bytes, Checksum.data(), 16); + } // If there is -g option as well as debug info from directive file, // 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) == - 0) + else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, + Filename, CKMem) == 0) return Error(FileNumberLoc, "file number already allocated"); } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index af1fc5277db..a6784273aab 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -194,8 +194,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID) { - return getContext().getDwarfFile(Directory, Filename, FileNo, CUID); + StringRef Filename, + MD5::MD5Result *Checksum, + unsigned CUID) { + return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, CUID); } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, |