Skip to content

Commit 26fa1bf

Browse files
committed
Re-land "Fix Bug 30978 by emitting cv file checksums."
This reverts r313431 and brings back r313374 with a fix to write checksums as binary data and not ASCII hex strings. llvm-svn: 313657
1 parent 0a84b1a commit 26fa1bf

File tree

16 files changed

+305
-81
lines changed

16 files changed

+305
-81
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,12 @@ class DIFile : public DIScope {
473473
friend class MDNode;
474474

475475
public:
476+
// These values must be explictly set, as they end up in the final object
477+
// file.
476478
enum ChecksumKind {
477-
CSK_None,
478-
CSK_MD5,
479-
CSK_SHA1,
479+
CSK_None = 0,
480+
CSK_MD5 = 1,
481+
CSK_SHA1 = 2,
480482
CSK_Last = CSK_SHA1 // Should be last enumeration.
481483
};
482484

@@ -510,7 +512,7 @@ class DIFile : public DIScope {
510512
ChecksumKind CSK = CSK_None,
511513
StringRef CS = StringRef()),
512514
(Filename, Directory, CSK, CS))
513-
DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
515+
DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
514516
ChecksumKind CSK = CSK_None,
515517
MDString *CS = nullptr),
516518
(Filename, Directory, CSK, CS))

llvm/include/llvm/MC/MCCodeView.h

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ class CodeViewContext {
161161
~CodeViewContext();
162162

163163
bool isValidFileNumber(unsigned FileNumber) const;
164-
bool addFile(unsigned FileNumber, StringRef Filename);
165-
ArrayRef<StringRef> getFilenames() { return Filenames; }
164+
bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
165+
ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
166166

167167
/// Records the function id of a normal function. Returns false if the
168168
/// function id has already been used, and true otherwise.
@@ -273,6 +273,9 @@ class CodeViewContext {
273273
/// Emits the file checksum substream.
274274
void emitFileChecksums(MCObjectStreamer &OS);
275275

276+
/// Emits the offset into the checksum table of the given file number.
277+
void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
278+
276279
private:
277280
/// The current CodeView line information from the last .cv_loc directive.
278281
MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
@@ -287,14 +290,31 @@ class CodeViewContext {
287290

288291
MCDataFragment *getStringTableFragment();
289292

290-
/// Add something to the string table.
291-
StringRef addToStringTable(StringRef S);
293+
/// Add something to the string table. Returns the final string as well as
294+
/// offset into the string table.
295+
std::pair<StringRef, unsigned> addToStringTable(StringRef S);
292296

293297
/// Get a string table offset.
294298
unsigned getStringTableOffset(StringRef S);
295299

296-
/// An array of absolute paths. Eventually this may include the file checksum.
297-
SmallVector<StringRef, 4> Filenames;
300+
struct FileInfo {
301+
unsigned StringTableOffset;
302+
303+
// Indicates if this FileInfo corresponds to an actual file, or hasn't been
304+
// set yet.
305+
bool Assigned = false;
306+
307+
uint8_t ChecksumKind;
308+
309+
ArrayRef<uint8_t> Checksum;
310+
311+
// Checksum offset stored as a symbol because it might be requested
312+
// before it has been calculated, so a fixup may be needed.
313+
MCSymbol *ChecksumTableOffset;
314+
};
315+
316+
/// Array storing added file information.
317+
SmallVector<FileInfo, 4> Files;
298318

299319
/// The offset of the first and last .cv_loc directive for a given function
300320
/// id.
@@ -305,6 +325,10 @@ class CodeViewContext {
305325

306326
/// All known functions and inlined call sites, indexed by function id.
307327
std::vector<MCCVFunctionInfo> Functions;
328+
329+
/// Indicate whether we have already laid out the checksum table addresses or
330+
/// not.
331+
bool ChecksumOffsetsAssigned = false;
308332
};
309333

310334
} // end namespace llvm

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class MCObjectStreamer : public MCStreamer {
140140
StringRef FixedSizePortion) override;
141141
void EmitCVStringTableDirective() override;
142142
void EmitCVFileChecksumsDirective() override;
143+
void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
143144
void EmitDTPRel32Value(const MCExpr *Value) override;
144145
void EmitDTPRel64Value(const MCExpr *Value) override;
145146
void EmitTPRel32Value(const MCExpr *Value) override;

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,12 @@ class MCStreamer {
733733
unsigned Isa, unsigned Discriminator,
734734
StringRef FileName);
735735

736-
/// \brief Associate a filename with a specified logical file number. This
737-
/// implements the '.cv_file 4 "foo.c"' assembler directive. Returns true on
738-
/// success.
739-
virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename);
736+
/// Associate a filename with a specified logical file number, and also
737+
/// specify that file's checksum information. This implements the '.cv_file 4
738+
/// "foo.c"' assembler directive. Returns true on success.
739+
virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
740+
ArrayRef<uint8_t> Checksum,
741+
unsigned ChecksumKind);
740742

741743
/// \brief Introduces a function id for use with .cv_loc.
742744
virtual bool EmitCVFuncIdDirective(unsigned FunctionId);
@@ -778,6 +780,10 @@ class MCStreamer {
778780
/// \brief This implements the CodeView '.cv_filechecksums' assembler directive.
779781
virtual void EmitCVFileChecksumsDirective() {}
780782

783+
/// This implements the CodeView '.cv_filechecksumoffset' assembler
784+
/// directive.
785+
virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
786+
781787
/// Emit the absolute difference between two symbols.
782788
///
783789
/// \pre Offset of \c Hi is greater than the offset \c Lo.

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,14 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
159159
if (Insertion.second) {
160160
// We have to compute the full filepath and emit a .cv_file directive.
161161
StringRef FullPath = getFullFilepath(F);
162-
bool Success = OS.EmitCVFileDirective(NextId, FullPath);
162+
std::string Checksum = fromHex(F->getChecksum());
163+
void *CKMem = OS.getContext().allocate(Checksum.size(), 1);
164+
memcpy(CKMem, Checksum.data(), Checksum.size());
165+
ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
166+
Checksum.size());
167+
DIFile::ChecksumKind ChecksumKind = F->getChecksumKind();
168+
bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
169+
static_cast<unsigned>(ChecksumKind));
163170
(void)Success;
164171
assert(Success && ".cv_file directive failed");
165172
}
@@ -681,8 +688,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
681688
OS.AddComment("Inlinee lines subsection");
682689
MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
683690

684-
// We don't provide any extra file info.
685-
// FIXME: Find out if debuggers use this info.
691+
// We emit the checksum info for files. This is used by debuggers to
692+
// determine if a pdb matches the source before loading it. Visual Studio,
693+
// for instance, will display a warning that the breakpoints are not valid if
694+
// the pdb does not match the source.
686695
OS.AddComment("Inlinee lines signature");
687696
OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
688697

@@ -695,13 +704,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
695704
OS.AddComment("Inlined function " + SP->getName() + " starts at " +
696705
SP->getFilename() + Twine(':') + Twine(SP->getLine()));
697706
OS.AddBlankLine();
698-
// The filechecksum table uses 8 byte entries for now, and file ids start at
699-
// 1.
700-
unsigned FileOffset = (FileId - 1) * 8;
701707
OS.AddComment("Type index of inlined function");
702708
OS.EmitIntValue(InlineeIdx.getIndex(), 4);
703709
OS.AddComment("Offset into filechecksum table");
704-
OS.EmitIntValue(FileOffset, 4);
710+
OS.EmitCVFileChecksumOffsetDirective(FileId);
705711
OS.AddComment("Starting line number");
706712
OS.EmitIntValue(SP->getLine(), 4);
707713
}

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
354354
DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
355355
}
356356

357+
// FIXME: Implement this string-enum correspondence with a .def file and macros,
358+
// so that the association is explicit rather than implied.
357359
static const char *ChecksumKindName[DIFile::CSK_Last + 1] = {
358360
"CSK_None",
359361
"CSK_MD5",

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ class MCAsmStreamer final : public MCStreamer {
225225
StringRef FileName) override;
226226
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
227227

228-
bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
228+
bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
229+
ArrayRef<uint8_t> Checksum,
230+
unsigned ChecksumKind) override;
229231
bool EmitCVFuncIdDirective(unsigned FuncId) override;
230232
bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
231233
unsigned IAFile, unsigned IALine,
@@ -245,6 +247,7 @@ class MCAsmStreamer final : public MCStreamer {
245247
StringRef FixedSizePortion) override;
246248
void EmitCVStringTableDirective() override;
247249
void EmitCVFileChecksumsDirective() override;
250+
void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
248251

249252
void EmitIdent(StringRef IdentString) override;
250253
void EmitCFISections(bool EH, bool Debug) override;
@@ -1120,13 +1123,25 @@ MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
11201123
return MCStreamer::getDwarfLineTableSymbol(0);
11211124
}
11221125

1123-
bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
1124-
if (!getContext().getCVContext().addFile(FileNo, Filename))
1126+
bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
1127+
ArrayRef<uint8_t> Checksum,
1128+
unsigned ChecksumKind) {
1129+
if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1130+
ChecksumKind))
11251131
return false;
11261132

11271133
OS << "\t.cv_file\t" << FileNo << ' ';
1128-
11291134
PrintQuotedString(Filename, OS);
1135+
1136+
if (!ChecksumKind) {
1137+
EmitEOL();
1138+
return true;
1139+
}
1140+
1141+
OS << ' ';
1142+
PrintQuotedString(toHex(Checksum), OS);
1143+
OS << ' ' << ChecksumKind;
1144+
11301145
EmitEOL();
11311146
return true;
11321147
}
@@ -1228,6 +1243,11 @@ void MCAsmStreamer::EmitCVFileChecksumsDirective() {
12281243
EmitEOL();
12291244
}
12301245

1246+
void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
1247+
OS << "\t.cv_filechecksumoffset\t" << FileNo;
1248+
EmitEOL();
1249+
}
1250+
12311251
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
12321252
assert(MAI->hasIdentDirective() && ".ident directive not supported");
12331253
OS << "\t.ident\t";

0 commit comments

Comments
 (0)