From d17f6ab61b2492cdf5c1c88c36915456206f84fe Mon Sep 17 00:00:00 2001 From: Aleksandr Urakov Date: Wed, 30 Jan 2019 10:40:45 +0000 Subject: [PATCH] [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 llvm-svn: 352615 --- llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h | 19 +++- llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp | 105 ++++++++++++++------- llvm/test/tools/llvm-pdbdump/Inputs/FPOTest.pdb | Bin 0 -> 110592 bytes llvm/test/tools/llvm-pdbdump/fpo-data.test | 14 +++ llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp | 19 +--- 5 files changed, 102 insertions(+), 55 deletions(-) create mode 100644 llvm/test/tools/llvm-pdbdump/Inputs/FPOTest.pdb create mode 100644 llvm/test/tools/llvm-pdbdump/fpo-data.test diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 438b6e7..7d75c15 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -10,6 +10,7 @@ #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H #include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleList.h" @@ -79,7 +80,10 @@ public: FixedStreamArray getSectionHeaders() const; - FixedStreamArray getFpoRecords(); + bool hasOldFpoRecords() const; + FixedStreamArray getOldFpoRecords() const; + bool hasNewFpoRecords() const; + const codeview::DebugFrameDataSubsectionRef &getNewFpoRecords() const; FixedStreamArray getSectionMap() const; void visitSectionContributions(ISectionContribVisitor &Visitor) const; @@ -90,7 +94,11 @@ private: Error initializeSectionContributionData(); Error initializeSectionHeadersData(PDBFile *Pdb); Error initializeSectionMapData(); - Error initializeFpoRecords(PDBFile *Pdb); + Error initializeOldFpoRecords(PDBFile *Pdb); + Error initializeNewFpoRecords(PDBFile *Pdb); + + Expected> + createIndexedStreamForHeaderType(PDBFile *Pdb, DbgHeaderType Type) const; std::unique_ptr Stream; @@ -116,8 +124,11 @@ private: std::unique_ptr SectionHeaderStream; FixedStreamArray SectionHeaders; - std::unique_ptr FpoStream; - FixedStreamArray FpoRecords; + std::unique_ptr OldFpoStream; + FixedStreamArray OldFpoRecords; + + std::unique_ptr NewFpoStream; + codeview::DebugFrameDataSubsectionRef NewFpoRecords; const DbiStreamHeader *Header; }; diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp index 248477a..ea15bcd 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -126,8 +126,10 @@ Error DbiStream::reload(PDBFile *Pdb) { return EC; if (auto EC = initializeSectionMapData()) return EC; - if (auto EC = initializeFpoRecords(Pdb)) + if (auto EC = initializeOldFpoRecords(Pdb)) return EC; + if (auto EC = initializeNewFpoRecords(Pdb)) + return EC; if (Reader.bytesRemaining() > 0) return make_error(raw_error_code::corrupt_file, @@ -200,8 +202,16 @@ FixedStreamArray DbiStream::getSectionHeaders() const { return SectionHeaders; } -FixedStreamArray DbiStream::getFpoRecords() { - return FpoRecords; +bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; } + +FixedStreamArray DbiStream::getOldFpoRecords() const { + return OldFpoRecords; +} + +bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; } + +const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const { + return NewFpoRecords; } const DbiModuleList &DbiStream::modules() const { return Modules; } @@ -246,22 +256,15 @@ Error DbiStream::initializeSectionContributionData() { // Initializes this->SectionHeaders. Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { - if (!Pdb) - return Error::success(); - - if (DbgStreams.size() == 0) - return Error::success(); + Expected> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr); + if (auto EC = ExpectedStream.takeError()) + return EC; - uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr); - if (StreamNum == kInvalidStreamIndex) + auto &SHS = *ExpectedStream; + if (!SHS) return Error::success(); - if (StreamNum >= Pdb->getNumStreams()) - return make_error(raw_error_code::no_stream); - - auto SHS = MappedBlockStream::createIndexedStream( - Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); - size_t StreamLen = SHS->getLength(); if (StreamLen % sizeof(object::coff_section)) return make_error(raw_error_code::corrupt_file, @@ -278,39 +281,69 @@ Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { } // Initializes this->Fpos. -Error DbiStream::initializeFpoRecords(PDBFile *Pdb) { - if (!Pdb) - return Error::success(); - - if (DbgStreams.size() == 0) - return Error::success(); - - uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO); +Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) { + Expected> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO); + if (auto EC = ExpectedStream.takeError()) + return EC; - // This means there is no FPO data. - if (StreamNum == kInvalidStreamIndex) + auto &FS = *ExpectedStream; + if (!FS) return Error::success(); - if (StreamNum >= Pdb->getNumStreams()) - return make_error(raw_error_code::no_stream); - - auto FS = MappedBlockStream::createIndexedStream( - Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); - size_t StreamLen = FS->getLength(); if (StreamLen % sizeof(object::FpoData)) return make_error(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); + "Corrupted Old FPO stream."); size_t NumRecords = StreamLen / sizeof(object::FpoData); BinaryStreamReader Reader(*FS); - if (auto EC = Reader.readArray(FpoRecords, NumRecords)) + if (auto EC = Reader.readArray(OldFpoRecords, NumRecords)) return make_error(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); - FpoStream = std::move(FS); + "Corrupted Old FPO stream."); + OldFpoStream = std::move(FS); + return Error::success(); +} + +Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) { + Expected> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO); + if (auto EC = ExpectedStream.takeError()) + return EC; + + auto &FS = *ExpectedStream; + if (!FS) + return Error::success(); + + if (auto EC = NewFpoRecords.initialize(*FS)) + return EC; + + NewFpoStream = std::move(FS); return Error::success(); } +Expected> +DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb, + DbgHeaderType Type) const { + if (!Pdb) + return nullptr; + + if (DbgStreams.empty()) + return nullptr; + + uint32_t StreamNum = getDebugStreamIndex(Type); + + // This means there is no such stream + if (StreamNum == kInvalidStreamIndex) + return nullptr; + + if (StreamNum >= Pdb->getNumStreams()) + return make_error(raw_error_code::no_stream); + + return MappedBlockStream::createIndexedStream( + Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); +} + BinarySubstreamRef DbiStream::getSectionContributionData() const { return SecContrSubstream; } diff --git a/llvm/test/tools/llvm-pdbdump/Inputs/FPOTest.pdb b/llvm/test/tools/llvm-pdbdump/Inputs/FPOTest.pdb new file mode 100644 index 0000000000000000000000000000000000000000..7096328b39e6fd8dc889f045914a0a5bf27665bb GIT binary patch literal 110592 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≠hu0-3MBA&-?#*|G#I|z3jiSw_Ga4WLUtvC7=3H>@WAk@&13_ z|G(0*Q!#uCA2YoFUw%EU$bAT{#rFgC#k~KY_y7BSH}d{}br=>j5U>7$?{41z&-?$q z$E7J9^3R}$8Y`f&0OCda2w+-6 zuGMzO3RwSl&bRZ`o_$pu-;{p+CF}ocFE!i$lP4(p%8j(M;v3^5Q5fT5`+wcLaD7G` zB&a_0fxdou|3B~l_l!h1x8ivmevC|A{nKQKzaKmYATO zzIC|^nG}9n?!F(M9BnE;Ebo*NLAw3vH_l@JG|&GV?rHXz^YqohSpR4H|1^f?uCieJ z|7`ys{y)tju>Q~bKimIj`~PhJA2#abIbUr5|KaTa^ZI|9 z$XlD{_5bcT1+V{iZN?sk4o2%*`20UU|F7p{LZ1J}K{b0{|G@MAJpZp&)2n%`;ajwR zkmvt-{{NudLwXYLUOxYi&;O%oMn3~& zo36@+`W@Qmete&_9zdm2DXzP-GcFDsr@H?;NE8voUVNgF?ZTJPfi%zX)#B+$@=6kzytX?ZmqVw~G%|hXTGG?17K}7VtM(iHdC5Jq zd$g>}_WxkssBOR>CIi|2pL=8g+y9pbH*}bpX8Zqa|DWyu-DVv zJBOyR{@-<2o<}`r`~Q6YpF3*C=l}H_E7|ueEuI<*XQ&9)Z8ea|3~A#eE#3Vod3uA z|AFH?|KD*MJkS4Ye&3O;FBU?tK1Vwa-zB-O5tm zVV~}V>hMWSsTayk9NzOwXB}F9U5fR8*8hE0Ub6l_pZ_7XoL`jWUE6%26XXjc zzz8q`i~u9R2rvSS03*N%FanGKBk)Kdu=(FYym(cJ@0=PE|M8cwc80y{>=*$?fDvE> z7y(9r5nu!u0Y-okU<4QeM&Qvxfc5`J>v?i(7y(9r5nu!u0Y-okU<4QeMt~7u1Q-E7 z1itqZA^!Q}ArU+z#9#dYYvJF=%6MJ_;0G1c7y(9r5nu!u0Y-okU<4QeMt~7u1Q>xY zECQ_me_7y(9r5nu!u0Y-ok7#M+Zq`V6MP51`hAnet1Q-EE cfDvE>7y(9r5nu!u0Y-okU<4R}&k+Lu2RG9PGXMYp literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-pdbdump/fpo-data.test b/llvm/test/tools/llvm-pdbdump/fpo-data.test new file mode 100644 index 0000000..ac909cf --- /dev/null +++ b/llvm/test/tools/llvm-pdbdump/fpo-data.test @@ -0,0 +1,14 @@ +; RUN: llvm-pdbutil dump -fpo %p/Inputs/FPOTest.pdb \ +; RUN: | FileCheck %s + +CHECK: Old FPO Data +CHECK-NEXT: ============================================================ +CHECK-NEXT: RVA | Code | Locals | Params | Prolog | Saved Regs | Use BP | Has SEH | Frame Type +CHECK-NEXT: 0000004E | 19 | 0 | 0 | 0 | 0 | false | false | FPO + +CHECK: New FPO Data +CHECK-NEXT: ============================================================ +CHECK-NEXT: RVA | Code | Locals | Params | Stack | Prolog | Saved Regs | Has SEH | Has C++EH | Start | Program +CHECK-NEXT: 00001010 | 18 | 0 | 0 | 0 | 4 | 0 | false | false | true | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +CHECK-NEXT: 00001011 | 17 | 0 | 0 | 0 | 3 | 4 | false | false | false | $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +CHECK-NEXT: 00001013 | 15 | 0 | 0 | 0 | 1 | 4 | false | false | false | $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = \ No newline at end of file diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index 65752ac..23f9af6 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -1010,17 +1010,12 @@ Error DumpOutputStyle::dumpOldFpo(PDBFile &File) { ExitOnError Err("Error dumping old fpo data:"); auto &Dbi = Err(File.getPDBDbiStream()); - uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::FPO); - if (Index == kInvalidStreamIndex) { + if (!Dbi.hasOldFpoRecords()) { printStreamNotPresent("FPO"); return Error::success(); } - std::unique_ptr OldFpo = File.createIndexedStream(Index); - BinaryStreamReader Reader(*OldFpo); - FixedStreamArray Records; - Err(Reader.readArray(Records, - Reader.bytesRemaining() / sizeof(object::FpoData))); + const FixedStreamArray& Records = Dbi.getOldFpoRecords(); P.printLine(" RVA | Code | Locals | Params | Prolog | Saved Regs | Use " "BP | Has SEH | Frame Type"); @@ -1042,18 +1037,12 @@ Error DumpOutputStyle::dumpNewFpo(PDBFile &File) { ExitOnError Err("Error dumping new fpo data:"); auto &Dbi = Err(File.getPDBDbiStream()); - uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO); - if (Index == kInvalidStreamIndex) { + if (!Dbi.hasNewFpoRecords()) { printStreamNotPresent("New FPO"); return Error::success(); } - std::unique_ptr NewFpo = File.createIndexedStream(Index); - - DebugFrameDataSubsectionRef FDS; - if (auto EC = FDS.initialize(*NewFpo)) - return make_error(raw_error_code::corrupt_file, - "Invalid new fpo stream"); + const DebugFrameDataSubsectionRef& FDS = Dbi.getNewFpoRecords(); P.printLine(" RVA | Code | Locals | Params | Stack | Prolog | Saved Regs " "| Has SEH | Has C++EH | Start | Program"); -- 2.7.4