llvm.org GIT mirror llvm / 77a6888
[PDB] Write FPO Data to the PDB. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342003 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 1 year, 8 days ago
9 changed file(s) with 132 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
2525 }
2626
2727 Error initialize(BinaryStreamReader Reader);
28 Error initialize(BinaryStreamRef Stream);
2829
2930 FixedStreamArray::Iterator begin() const { return Frames.begin(); }
3031 FixedStreamArray::Iterator end() const { return Frames.end(); }
3132
32 const void *getRelocPtr() const { return RelocPtr; }
33 const uint32_t *getRelocPtr() const { return RelocPtr; }
3334
3435 private:
3536 const uint32_t *RelocPtr = nullptr;
3839
3940 class DebugFrameDataSubsection final : public DebugSubsection {
4041 public:
41 DebugFrameDataSubsection()
42 : DebugSubsection(DebugSubsectionKind::FrameData) {}
42 DebugFrameDataSubsection(bool IncludeRelocPtr)
43 : DebugSubsection(DebugSubsectionKind::FrameData),
44 IncludeRelocPtr(IncludeRelocPtr) {}
4345 static bool classof(const DebugSubsection *S) {
4446 return S->kind() == DebugSubsectionKind::FrameData;
4547 }
5153 void setFrames(ArrayRef Frames);
5254
5355 private:
56 bool IncludeRelocPtr = false;
5457 std::vector Frames;
5558 };
5659 }
1414 #include "llvm/BinaryFormat/COFF.h"
1515 #include "llvm/Support/Error.h"
1616
17 #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
1718 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1819 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
1920 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
2324 #include "llvm/Support/Endian.h"
2425
2526 namespace llvm {
27 namespace codeview {
28 struct FrameData;
29 }
2630 namespace msf {
2731 class MSFBuilder;
2832 }
6468 void setGlobalsStreamIndex(uint32_t Index);
6569 void setPublicsStreamIndex(uint32_t Index);
6670 void setSymbolRecordStreamIndex(uint32_t Index);
71 void addFrameData(const codeview::FrameData &FD);
6772
6873 Expected addModuleInfo(StringRef ModuleName);
6974 Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
8388
8489 private:
8590 struct DebugStream {
86 ArrayRef Data;
91 std::function WriteFn;
92 uint32_t Size = 0;
8793 uint16_t StreamNumber = kInvalidStreamIndex;
8894 };
8995
116122
117123 std::vector> ModiList;
118124
125 Optional FrameData;
126
119127 StringMap SourceFileNames;
120128
121129 PDBStringTableBuilder ECNamesBuilder;
1313 using namespace llvm::codeview;
1414
1515 Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
16 if (auto EC = Reader.readObject(RelocPtr))
17 return EC;
16 if (Reader.bytesRemaining() % sizeof(FrameData) != 0) {
17 if (auto EC = Reader.readObject(RelocPtr))
18 return EC;
19 }
20
1821 if (Reader.bytesRemaining() % sizeof(FrameData) != 0)
1922 return make_error(cv_error_code::corrupt_record,
2023 "Invalid frame data record format!");
2528 return Error::success();
2629 }
2730
31 Error DebugFrameDataSubsectionRef::initialize(BinaryStreamRef Section) {
32 BinaryStreamReader Reader(Section);
33 return initialize(Reader);
34 }
35
2836 uint32_t DebugFrameDataSubsection::calculateSerializedSize() const {
29 return 4 + sizeof(FrameData) * Frames.size();
37 uint32_t Size = sizeof(FrameData) * Frames.size();
38 if (IncludeRelocPtr)
39 Size += sizeof(uint32_t);
40 return Size;
3041 }
3142
3243 Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
33 if (auto EC = Writer.writeInteger(0))
34 return EC;
44 if (IncludeRelocPtr) {
45 if (auto EC = Writer.writeInteger(0))
46 return EC;
47 }
3548
36 if (auto EC = Writer.writeArray(makeArrayRef(Frames)))
49 std::vector SortedFrames(Frames.begin(), Frames.end());
50 std::sort(SortedFrames.begin(), SortedFrames.end(),
51 [](const FrameData &LHS, const FrameData &RHS) {
52 return LHS.RvaStart < RHS.RvaStart;
53 });
54 if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames)))
3755 return EC;
3856 return Error::success();
3957 }
1010
1111 #include "llvm/ADT/ArrayRef.h"
1212 #include "llvm/BinaryFormat/COFF.h"
13 #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
1314 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
1415 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1516 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
7374 PublicsStreamIndex = Index;
7475 }
7576
77 void DbiStreamBuilder::addFrameData(const codeview::FrameData &FD) {
78 if (!FrameData.hasValue())
79 FrameData.emplace(false);
80
81 FrameData->addFrameData(FD);
82 }
83
7684 Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
7785 ArrayRef Data) {
86 assert(Type != DbgHeaderType::NewFPO &&
87 "NewFPO data should be written via addFrameData()!");
88
7889 DbgStreams[(int)Type].emplace();
79 DbgStreams[(int)Type]->Data = Data;
90 DbgStreams[(int)Type]->Size = Data.size();
91 DbgStreams[(int)Type]->WriteFn = [Data](BinaryStreamWriter &Writer) {
92 return Writer.writeArray(Data);
93 };
8094 return Error::success();
8195 }
8296
271285 }
272286
273287 Error DbiStreamBuilder::finalizeMsfLayout() {
288 if (FrameData.hasValue()) {
289 DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
290 DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
291 FrameData->calculateSerializedSize();
292 DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn =
293 [this](BinaryStreamWriter &Writer) {
294 return FrameData->commit(Writer);
295 };
296 }
297
274298 for (auto &S : DbgStreams) {
275299 if (!S.hasValue())
276300 continue;
277 auto ExpectedIndex = Msf.addStream(S->Data.size());
301 auto ExpectedIndex = Msf.addStream(S->Size);
278302 if (!ExpectedIndex)
279303 return ExpectedIndex.takeError();
280304 S->StreamNumber = *ExpectedIndex;
405429 auto WritableStream = WritableMappedBlockStream::createIndexedStream(
406430 Layout, MsfBuffer, Stream->StreamNumber, Allocator);
407431 BinaryStreamWriter DbgStreamWriter(*WritableStream);
408 if (auto EC = DbgStreamWriter.writeArray(Stream->Data))
432
433 if (auto EC = Stream->WriteFn(DbgStreamWriter))
409434 return EC;
410435 }
411436
510510 const codeview::StringsAndChecksums &SC) const {
511511 assert(SC.hasStrings());
512512
513 auto Result = std::make_shared();
513 auto Result = std::make_shared(true);
514514 for (const auto &YF : Frames) {
515515 codeview::FrameData F;
516516 F.CodeSize = YF.CodeSize;
2121 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
2222 #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
2323 #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
24 #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
2425 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
2526 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
2627 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
141142 return EC;
142143 }
143144
145 if (opts::dump::DumpFpo) {
146 if (auto EC = dumpFpo())
147 return EC;
148 }
149
144150 if (File.isObj()) {
145151 if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
146152 opts::dump::DumpTypeExtras)
984990 return Error::success();
985991 }
986992
993 Error DumpOutputStyle::dumpFpo() {
994 printHeader(P, "New FPO Data");
995
996 if (!File.isPdb()) {
997 printStreamNotValidForObj();
998 return Error::success();
999 }
1000
1001 PDBFile &File = getPdb();
1002 if (!File.hasPDBDbiStream()) {
1003 printStreamNotPresent("DBI");
1004 return Error::success();
1005 }
1006
1007 ExitOnError Err("Error dumping fpo data:");
1008
1009 auto &Dbi = Err(File.getPDBDbiStream());
1010
1011 uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO);
1012 if (Index == kInvalidStreamIndex) {
1013 printStreamNotPresent("New FPO");
1014 return Error::success();
1015 }
1016
1017 std::unique_ptr NewFpo = File.createIndexedStream(Index);
1018
1019 DebugFrameDataSubsectionRef FDS;
1020 if (auto EC = FDS.initialize(*NewFpo))
1021 return make_error(raw_error_code::corrupt_file,
1022 "Invalid new fpo stream");
1023
1024 P.printLine(" RVA | Code | Locals | Params | Stack | Prolog | Saved Regs "
1025 "| Has SEH | Has C++EH | Start | Program");
1026 for (const FrameData &FD : FDS) {
1027 bool IsFuncStart = FD.Flags & FrameData::IsFunctionStart;
1028 bool HasEH = FD.Flags & FrameData::HasEH;
1029 bool HasSEH = FD.Flags & FrameData::HasSEH;
1030
1031 auto &StringTable = Err(File.getStringTable());
1032
1033 auto Program = Err(StringTable.getStringForID(FD.FrameFunc));
1034 P.formatLine("{0:X-8} | {1,4} | {2,6} | {3,6} | {4,5} | {5,6} | {6,10} | "
1035 "{7,7} | {8,9} | {9,5} | {10}",
1036 uint32_t(FD.RvaStart), uint32_t(FD.CodeSize),
1037 uint32_t(FD.LocalSize), uint32_t(FD.ParamsSize),
1038 uint32_t(FD.MaxStackSize), uint16_t(FD.PrologSize),
1039 uint16_t(FD.SavedRegsSize), HasSEH, HasEH, IsFuncStart,
1040 Program);
1041 }
1042 return Error::success();
1043 }
1044
9871045 Error DumpOutputStyle::dumpStringTableFromPdb() {
9881046 AutoIndent Indent(P);
9891047 auto IS = getPdb().getStringTable();
8484 Error dumpInlineeLines();
8585 Error dumpXmi();
8686 Error dumpXme();
87 Error dumpFpo();
8788 Error dumpTpiStream(uint32_t StreamIdx);
8889 Error dumpTypesFromObjectFile();
8990 Error dumpModules();
500500 cl::desc("dump CodeView symbol record raw bytes"),
501501 cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
502502
503 cl::opt DumpFpo("fpo", cl::desc("dump FPO records"),
504 cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
505
503506 // MODULE & FILE OPTIONS
504507 cl::opt DumpModules("modules", cl::desc("dump compiland information"),
505508 cl::cat(FileOptions), cl::sub(DumpSubcommand));
13711374 if (opts::DumpSubcommand) {
13721375 if (opts::dump::RawAll) {
13731376 opts::dump::DumpGlobals = true;
1377 opts::dump::DumpFpo = true;
13741378 opts::dump::DumpInlineeLines = true;
13751379 opts::dump::DumpIds = true;
13761380 opts::dump::DumpIdExtras = true;
170170 extern llvm::cl::opt DumpSectionMap;
171171 extern llvm::cl::opt DumpModules;
172172 extern llvm::cl::opt DumpModuleFiles;
173 extern llvm::cl::opt DumpFpo;
173174 extern llvm::cl::opt RawAll;
174175 }
175176