llvm.org GIT mirror llvm / b85b70f
Fix some differences between lld and MSVC generated PDBs. A couple of things were different about our generated PDBs. 1) We were outputting the wrong Version on the PDB Stream. The version we were setting was newer than what MSVC is setting. It's not clear what the implications are, but we change LLD to use PdbImplVC70, as MSVC does. 2) For the optional debug stream indices in the DBI Stream, we were outputting 0 to mean "the stream is not present". MSVC outputs uint16_t(-1), which is the "correct" way to specify that a stream is not present. So we fix that as well. 3) We were setting the PDB Stream signature to 0. This is supposed to be the result of calling time(nullptr). Although this leads to non-deterministic builds, a better way to solve that is by having a command line option explicitly for generating a reproducible build, and have the default behavior of lld-link match the default behavior of link. To test this, I'm making use of the new and improved `pdb diff` sub command. To make it suitable for writing tests against, I had to modify the diff subcommand slightly to print less verbose output. Previously it would always print | <column> | <value1> | <value2> | which is quite verbose, and the values are fragile. All we really want to know is "did we produce the same value as link?" So I added command line options to print a single character representing the result status (different, identical, equivalent), and another to hide the value display. Note that just inspecting the diff output used to write the test, you can see some things that are obviously wrong. That is just reflective of the fact that this is the state of affairs today, not that we're asserting that this is "correct". We can use this as a starting point to discover differences, fix them, and update the test. Differential Revision: https://reviews.llvm.org/D35086 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307422 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 3 years ago
9 changed file(s) with 114 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
7777 private:
7878 struct DebugStream {
7979 ArrayRef Data;
80 uint16_t StreamNumber = 0;
80 uint16_t StreamNumber = kInvalidStreamIndex;
8181 };
8282
8383 Error finalize();
251251 return Error::success();
252252
253253 uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
254 if (StreamNum == kInvalidStreamIndex)
255 return Error::success();
256
254257 if (StreamNum >= Pdb.getNumStreams())
255258 return make_error(raw_error_code::no_stream);
256259
5050
5151 Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
5252 ArrayRef Data) {
53 if (DbgStreams[(int)Type].StreamNumber)
53 if (DbgStreams[(int)Type].StreamNumber != kInvalidStreamIndex)
5454 return make_error(raw_error_code::duplicate_entry,
5555 "The specified stream type already exists");
5656 auto ExpectedIndex = Msf.addStream(Data.size());
384384
385385 bool PDBFile::hasPDBGlobalsStream() {
386386 auto DbiS = getPDBDbiStream();
387 if (!DbiS)
387 if (!DbiS) {
388 consumeError(DbiS.takeError());
388389 return false;
390 }
391
389392 return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
390393 }
391394
395398
396399 bool PDBFile::hasPDBPublicsStream() {
397400 auto DbiS = getPDBDbiStream();
398 if (!DbiS)
401 if (!DbiS) {
402 consumeError(DbiS.takeError());
399403 return false;
404 }
400405 return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
401406 }
402407
107107 }
108108
109109 Error DiffStyle::diffSuperBlock() {
110 DiffPrinter D(2, "MSF Super Block", 16, 20, outs());
110 DiffPrinter D(2, "MSF Super Block", 16, 20, opts::diff::PrintResultColumn,
111 opts::diff::PrintValueColumns, outs());
111112 D.printExplicit("File", DiffResult::UNSPECIFIED,
112113 shortFilePath(File1.getFilePath(), 18),
113114 shortFilePath(File2.getFilePath(), 18));
120121 }
121122
122123 Error DiffStyle::diffStreamDirectory() {
123 DiffPrinter D(2, "Stream Directory", 30, 20, outs());
124 DiffPrinter D(2, "Stream Directory", 30, 20, opts::diff::PrintResultColumn,
125 opts::diff::PrintValueColumns, outs());
124126 D.printExplicit("File", DiffResult::UNSPECIFIED,
125127 shortFilePath(File1.getFilePath(), 18),
126128 shortFilePath(File2.getFilePath(), 18));
162164 }
163165
164166 Error DiffStyle::diffStringTable() {
165 DiffPrinter D(2, "String Table", 30, 20, outs());
167 DiffPrinter D(2, "String Table", 30, 20, opts::diff::PrintResultColumn,
168 opts::diff::PrintValueColumns, outs());
166169 D.printExplicit("File", DiffResult::UNSPECIFIED,
167170 shortFilePath(File1.getFilePath(), 18),
168171 shortFilePath(File2.getFilePath(), 18));
250253 Error DiffStyle::diffFreePageMap() { return Error::success(); }
251254
252255 Error DiffStyle::diffInfoStream() {
253 DiffPrinter D(2, "PDB Stream", 22, 40, outs());
256 DiffPrinter D(2, "PDB Stream", 22, 40, opts::diff::PrintResultColumn,
257 opts::diff::PrintValueColumns, outs());
254258 D.printExplicit("File", DiffResult::UNSPECIFIED,
255259 shortFilePath(File1.getFilePath(), 38),
256260 shortFilePath(File2.getFilePath(), 38));
344348 }
345349
346350 Error DiffStyle::diffDbiStream() {
347 DiffPrinter D(2, "DBI Stream", 40, 30, outs());
351 DiffPrinter D(2, "DBI Stream", 40, 30, opts::diff::PrintResultColumn,
352 opts::diff::PrintValueColumns, outs());
348353 D.printExplicit("File", DiffResult::UNSPECIFIED,
349 shortFilePath(File1.getFilePath(), 38),
350 shortFilePath(File2.getFilePath(), 38));
354 shortFilePath(File1.getFilePath(), 28),
355 shortFilePath(File2.getFilePath(), 28));
351356
352357 auto ExpectedDbi1 = File1.getPDBDbiStream();
353358 auto ExpectedDbi2 = File2.getPDBDbiStream();
2121
2222 DiffPrinter::DiffPrinter(uint32_t Indent, StringRef Header,
2323 uint32_t PropertyWidth, uint32_t FieldWidth,
24 raw_ostream &Stream)
25 : Indent(Indent), PropertyWidth(PropertyWidth), FieldWidth(FieldWidth),
26 OS(Stream) {
24 bool Result, bool Fields, raw_ostream &Stream)
25 : PrintResult(Result), PrintValues(Fields), Indent(Indent),
26 PropertyWidth(PropertyWidth), FieldWidth(FieldWidth), OS(Stream) {
2727 printHeaderRow();
2828 printFullRow(Header);
2929 }
3030
3131 DiffPrinter::~DiffPrinter() {}
3232
33 uint32_t DiffPrinter::tableWidth() const {
34 // `|`
35 uint32_t W = 1;
36
37 // `|`
38 W += PropertyWidth + 1;
39
40 if (PrintResult) {
41 // ` I |`
42 W += 4;
43 }
44
45 if (PrintValues) {
46 // `||`
47 W += 2 * (FieldWidth + 1);
48 }
49 return W;
50 }
51
3352 void DiffPrinter::printFullRow(StringRef Text) {
3453 newLine();
35 printField(Text, DiffResult::UNSPECIFIED, AlignStyle::Center,
36 PropertyWidth + 1 + FieldWidth + 1 + FieldWidth);
54 printValue(Text, DiffResult::UNSPECIFIED, AlignStyle::Center,
55 tableWidth() - 2, true);
3756 printSeparatorRow();
3857 }
3958
4059 void DiffPrinter::printSeparatorRow() {
4160 newLine();
4261 OS << formatv("{0}", fmt_repeat('-', PropertyWidth));
43 OS << '+';
44 OS << formatv("{0}", fmt_repeat('-', FieldWidth));
45 OS << '+';
46 OS << formatv("{0}", fmt_repeat('-', FieldWidth));
62 if (PrintResult) {
63 OS << '+';
64 OS << formatv("{0}", fmt_repeat('-', 3));
65 }
66 if (PrintValues) {
67 OS << '+';
68 OS << formatv("{0}", fmt_repeat('-', FieldWidth));
69 OS << '+';
70 OS << formatv("{0}", fmt_repeat('-', FieldWidth));
71 }
4772 OS << '|';
4873 }
4974
5075 void DiffPrinter::printHeaderRow() {
5176 newLine('-');
52 OS << formatv("{0}", fmt_repeat('-', PropertyWidth + 2 * FieldWidth + 3));
77 OS << formatv("{0}", fmt_repeat('-', tableWidth() - 1));
5378 }
5479
5580 void DiffPrinter::newLine(char InitialChar) {
6085 void DiffPrinter::printExplicit(StringRef Property, DiffResult C,
6186 StringRef Left, StringRef Right) {
6287 newLine();
63 printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right,
64 PropertyWidth);
65 printField(Left, C, AlignStyle::Center, FieldWidth);
66 printField(Right, C, AlignStyle::Center, FieldWidth);
88 printValue(Property, DiffResult::UNSPECIFIED, AlignStyle::Right,
89 PropertyWidth, true);
90 printResult(C);
91 printValue(Left, C, AlignStyle::Center, FieldWidth, false);
92 printValue(Right, C, AlignStyle::Center, FieldWidth, false);
6793 printSeparatorRow();
6894 }
6995
70 void DiffPrinter::printSame(StringRef Property, StringRef Value) {
71 newLine();
72 printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right,
73 PropertyWidth);
74 printField(Value, DiffResult::IDENTICAL, AlignStyle::Center,
75 FieldWidth + 1 + FieldWidth);
76 printSeparatorRow();
96 void DiffPrinter::printResult(DiffResult Result) {
97 if (!PrintResult)
98 return;
99 switch (Result) {
100 case DiffResult::DIFFERENT:
101 printValue("D", Result, AlignStyle::Center, 3, true);
102 break;
103 case DiffResult::EQUIVALENT:
104 printValue("E", Result, AlignStyle::Center, 3, true);
105 break;
106 case DiffResult::IDENTICAL:
107 printValue("I", Result, AlignStyle::Center, 3, true);
108 break;
109 case DiffResult::UNSPECIFIED:
110 printValue(" ", Result, AlignStyle::Center, 3, true);
111 break;
112 default:
113 llvm_unreachable("unreachable!");
114 }
77115 }
78116
79 void DiffPrinter::printDifferent(StringRef Property, StringRef Left,
80 StringRef Right) {
81 newLine();
82 printField(Property, DiffResult::UNSPECIFIED, AlignStyle::Right,
83 PropertyWidth);
84 printField(Left, DiffResult::DIFFERENT, AlignStyle::Center, FieldWidth);
85 printField(Right, DiffResult::DIFFERENT, AlignStyle::Center, FieldWidth);
86 printSeparatorRow();
87 }
117 void DiffPrinter::printValue(StringRef Value, DiffResult C, AlignStyle Style,
118 uint32_t Width, bool Force) {
119 if (!Force && !PrintValues)
120 return;
88121
89 void DiffPrinter::printField(StringRef Value, DiffResult C, AlignStyle Style,
90 uint32_t Width) {
91122 if (Style == AlignStyle::Right)
92123 --Width;
93124
5050 class DiffPrinter {
5151 public:
5252 DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth,
53 uint32_t FieldWidth, raw_ostream &Stream);
53 uint32_t FieldWidth, bool Result, bool Values,
54 raw_ostream &Stream);
5455 ~DiffPrinter();
5556
5657 template struct Identical {};
137138 void printFullRow(StringRef Text);
138139
139140 private:
140 void printSame(StringRef Property, StringRef Value);
141 void printDifferent(StringRef Property, StringRef Left, StringRef Right);
141 uint32_t tableWidth() const;
142142
143143 void printHeaderRow();
144144 void printSeparatorRow();
145145 void newLine(char InitialChar = '|');
146 void printField(StringRef Value, DiffResult C, AlignStyle Style,
147 uint32_t Width);
146 void printValue(StringRef Value, DiffResult C, AlignStyle Style,
147 uint32_t Width, bool Force);
148 void printResult(DiffResult Result);
148149
150 bool PrintResult;
151 bool PrintValues;
149152 uint32_t Indent;
150153 uint32_t PropertyWidth;
151154 uint32_t FieldWidth;
283283 }
284284
285285 namespace diff {
286 cl::opt PrintValueColumns(
287 "values", cl::init(true),
288 cl::desc("Print one column for each PDB with the field value"),
289 cl::Optional, cl::sub(DiffSubcommand));
290 cl::opt
291 PrintResultColumn("result", cl::init(false),
292 cl::desc("Print a column with the result status"),
293 cl::Optional, cl::sub(DiffSubcommand));
294
286295 cl::list InputFilenames(cl::Positional,
287296 cl::desc(" "),
288297 cl::OneOrMore, cl::sub(DiffSubcommand));
10781087 if (opts::pdb2yaml::DumpModules)
10791088 opts::pdb2yaml::DbiStream = true;
10801089 }
1090 if (opts::DiffSubcommand) {
1091 if (!opts::diff::PrintResultColumn && !opts::diff::PrintValueColumns) {
1092 llvm::errs() << "WARNING: No diff columns specified\n";
1093 }
1094 }
10811095
10821096 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
10831097
167167 extern llvm::cl::list DumpModuleSubsections;
168168 extern llvm::cl::opt DumpModuleSyms;
169169 } // namespace pdb2yaml
170
171 namespace diff {
172 extern llvm::cl::opt PrintValueColumns;
173 extern llvm::cl::opt PrintResultColumn;
174 } // namespace diff
170175 }
171176
172177 #endif