summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorPaul Robinson <paul.robinson@sony.com>2018-01-09 23:31:48 +0000
committerPaul Robinson <paul.robinson@sony.com>2018-01-09 23:31:48 +0000
commit29f5f987f1b76b5c43310b2062c9f447667a4f80 (patch)
treee19e9304ed5003b04e3a2a2b88c3c833df6a6c1e /llvm/lib/MC
parentd72f78e7c8d6dbef66cdbee0292237c68d780160 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--llvm/lib/MC/MCContext.cpp5
-rw-r--r--llvm/lib/MC/MCDwarf.cpp33
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp39
-rw-r--r--llvm/lib/MC/MCStreamer.cpp6
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,
OpenPOWER on IntegriCloud