llvm.org GIT mirror llvm / bd0011c
[NativePDB] Fix access to both old & new fpo data entries from dbi stream Summary: This patch fixes access to fpo streams in native pdb from DbiStream and makes code consistent with DbiStreamBuilder. Patch By: leonid.mashinskiy Reviewers: zturner, aleksandr.urakov Reviewed By: zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D56725 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352615 91177308-0d34-0410-b5e6-96231b3b80d8 Aleksandr Urakov 6 months ago
5 changed file(s) with 109 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
99 #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
1010
1111 #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
12 #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
1213 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1314 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
1415 #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
7879
7980 FixedStreamArray getSectionHeaders() const;
8081
81 FixedStreamArray getFpoRecords();
82 bool hasOldFpoRecords() const;
83 FixedStreamArray getOldFpoRecords() const;
84 bool hasNewFpoRecords() const;
85 const codeview::DebugFrameDataSubsectionRef &getNewFpoRecords() const;
8286
8387 FixedStreamArray getSectionMap() const;
8488 void visitSectionContributions(ISectionContribVisitor &Visitor) const;
8993 Error initializeSectionContributionData();
9094 Error initializeSectionHeadersData(PDBFile *Pdb);
9195 Error initializeSectionMapData();
92 Error initializeFpoRecords(PDBFile *Pdb);
96 Error initializeOldFpoRecords(PDBFile *Pdb);
97 Error initializeNewFpoRecords(PDBFile *Pdb);
98
99 Expected>
100 createIndexedStreamForHeaderType(PDBFile *Pdb, DbgHeaderType Type) const;
93101
94102 std::unique_ptr Stream;
95103
115123 std::unique_ptr SectionHeaderStream;
116124 FixedStreamArray SectionHeaders;
117125
118 std::unique_ptr FpoStream;
119 FixedStreamArray FpoRecords;
126 std::unique_ptr OldFpoStream;
127 FixedStreamArray OldFpoRecords;
128
129 std::unique_ptr NewFpoStream;
130 codeview::DebugFrameDataSubsectionRef NewFpoRecords;
120131
121132 const DbiStreamHeader *Header;
122133 };
125125 return EC;
126126 if (auto EC = initializeSectionMapData())
127127 return EC;
128 if (auto EC = initializeFpoRecords(Pdb))
129 return EC;
128 if (auto EC = initializeOldFpoRecords(Pdb))
129 return EC;
130 if (auto EC = initializeNewFpoRecords(Pdb))
131 return EC;
130132
131133 if (Reader.bytesRemaining() > 0)
132134 return make_error(raw_error_code::corrupt_file,
199201 return SectionHeaders;
200202 }
201203
202 FixedStreamArray DbiStream::getFpoRecords() {
203 return FpoRecords;
204 bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; }
205
206 FixedStreamArray DbiStream::getOldFpoRecords() const {
207 return OldFpoRecords;
208 }
209
210 bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; }
211
212 const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const {
213 return NewFpoRecords;
204214 }
205215
206216 const DbiModuleList &DbiStream::modules() const { return Modules; }
245255
246256 // Initializes this->SectionHeaders.
247257 Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
248 if (!Pdb)
249 return Error::success();
250
251 if (DbgStreams.size() == 0)
252 return Error::success();
253
254 uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
255 if (StreamNum == kInvalidStreamIndex)
256 return Error::success();
257
258 if (StreamNum >= Pdb->getNumStreams())
259 return make_error(raw_error_code::no_stream);
260
261 auto SHS = MappedBlockStream::createIndexedStream(
262 Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
258 Expected> ExpectedStream =
259 createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
260 if (auto EC = ExpectedStream.takeError())
261 return EC;
262
263 auto &SHS = *ExpectedStream;
264 if (!SHS)
265 return Error::success();
263266
264267 size_t StreamLen = SHS->getLength();
265268 if (StreamLen % sizeof(object::coff_section))
277280 }
278281
279282 // Initializes this->Fpos.
280 Error DbiStream::initializeFpoRecords(PDBFile *Pdb) {
283 Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
284 Expected> ExpectedStream =
285 createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
286 if (auto EC = ExpectedStream.takeError())
287 return EC;
288
289 auto &FS = *ExpectedStream;
290 if (!FS)
291 return Error::success();
292
293 size_t StreamLen = FS->getLength();
294 if (StreamLen % sizeof(object::FpoData))
295 return make_error(raw_error_code::corrupt_file,
296 "Corrupted Old FPO stream.");
297
298 size_t NumRecords = StreamLen / sizeof(object::FpoData);
299 BinaryStreamReader Reader(*FS);
300 if (auto EC = Reader.readArray(OldFpoRecords, NumRecords))
301 return make_error(raw_error_code::corrupt_file,
302 "Corrupted Old FPO stream.");
303 OldFpoStream = std::move(FS);
304 return Error::success();
305 }
306
307 Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) {
308 Expected> ExpectedStream =
309 createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO);
310 if (auto EC = ExpectedStream.takeError())
311 return EC;
312
313 auto &FS = *ExpectedStream;
314 if (!FS)
315 return Error::success();
316
317 if (auto EC = NewFpoRecords.initialize(*FS))
318 return EC;
319
320 NewFpoStream = std::move(FS);
321 return Error::success();
322 }
323
324 Expected>
325 DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb,
326 DbgHeaderType Type) const {
281327 if (!Pdb)
282 return Error::success();
283
284 if (DbgStreams.size() == 0)
285 return Error::success();
286
287 uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
288
289 // This means there is no FPO data.
328 return nullptr;
329
330 if (DbgStreams.empty())
331 return nullptr;
332
333 uint32_t StreamNum = getDebugStreamIndex(Type);
334
335 // This means there is no such stream
290336 if (StreamNum == kInvalidStreamIndex)
291 return Error::success();
337 return nullptr;
292338
293339 if (StreamNum >= Pdb->getNumStreams())
294340 return make_error(raw_error_code::no_stream);
295341
296 auto FS = MappedBlockStream::createIndexedStream(
342 return MappedBlockStream::createIndexedStream(
297343 Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
298
299 size_t StreamLen = FS->getLength();
300 if (StreamLen % sizeof(object::FpoData))
301 return make_error(raw_error_code::corrupt_file,
302 "Corrupted New FPO stream.");
303
304 size_t NumRecords = StreamLen / sizeof(object::FpoData);
305 BinaryStreamReader Reader(*FS);
306 if (auto EC = Reader.readArray(FpoRecords, NumRecords))
307 return make_error(raw_error_code::corrupt_file,
308 "Corrupted New FPO stream.");
309 FpoStream = std::move(FS);
310 return Error::success();
311344 }
312345
313346 BinarySubstreamRef DbiStream::getSectionContributionData() const {
0 ; RUN: llvm-pdbutil dump -fpo %p/Inputs/FPOTest.pdb \
1 ; RUN: | FileCheck %s
2
3 CHECK: Old FPO Data
4 CHECK-NEXT: ============================================================
5 CHECK-NEXT: RVA | Code | Locals | Params | Prolog | Saved Regs | Use BP | Has SEH | Frame Type
6 CHECK-NEXT: 0000004E | 19 | 0 | 0 | 0 | 0 | false | false | FPO
7
8 CHECK: New FPO Data
9 CHECK-NEXT: ============================================================
10 CHECK-NEXT: RVA | Code | Locals | Params | Stack | Prolog | Saved Regs | Has SEH | Has C++EH | Start | Program
11 CHECK-NEXT: 00001010 | 18 | 0 | 0 | 0 | 4 | 0 | false | false | true | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + =
12 CHECK-NEXT: 00001011 | 17 | 0 | 0 | 0 | 3 | 4 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
13 CHECK-NEXT: 00001013 | 15 | 0 | 0 | 0 | 1 | 4 | false | false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ =
10091009 ExitOnError Err("Error dumping old fpo data:");
10101010 auto &Dbi = Err(File.getPDBDbiStream());
10111011
1012 uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::FPO);
1013 if (Index == kInvalidStreamIndex) {
1012 if (!Dbi.hasOldFpoRecords()) {
10141013 printStreamNotPresent("FPO");
10151014 return Error::success();
10161015 }
10171016
1018 std::unique_ptr OldFpo = File.createIndexedStream(Index);
1019 BinaryStreamReader Reader(*OldFpo);
1020 FixedStreamArray Records;
1021 Err(Reader.readArray(Records,
1022 Reader.bytesRemaining() / sizeof(object::FpoData)));
1017 const FixedStreamArray& Records = Dbi.getOldFpoRecords();
10231018
10241019 P.printLine(" RVA | Code | Locals | Params | Prolog | Saved Regs | Use "
10251020 "BP | Has SEH | Frame Type");
10411036 ExitOnError Err("Error dumping new fpo data:");
10421037 auto &Dbi = Err(File.getPDBDbiStream());
10431038
1044 uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO);
1045 if (Index == kInvalidStreamIndex) {
1039 if (!Dbi.hasNewFpoRecords()) {
10461040 printStreamNotPresent("New FPO");
10471041 return Error::success();
10481042 }
10491043
1050 std::unique_ptr NewFpo = File.createIndexedStream(Index);
1051
1052 DebugFrameDataSubsectionRef FDS;
1053 if (auto EC = FDS.initialize(*NewFpo))
1054 return make_error(raw_error_code::corrupt_file,
1055 "Invalid new fpo stream");
1044 const DebugFrameDataSubsectionRef& FDS = Dbi.getNewFpoRecords();
10561045
10571046 P.printLine(" RVA | Code | Locals | Params | Stack | Prolog | Saved Regs "
10581047 "| Has SEH | Has C++EH | Start | Program");