From: Zachary Turner Date: Wed, 12 Sep 2018 21:02:01 +0000 (+0000) Subject: [PDB] Emit old fpo data to the PDB file. X-Git-Tag: android-x86-9.0-r1~13097 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=69d3b58106974e3d93b9be8183d0ce60eef1a3cf;p=android-x86%2Fexternal-llvm.git [PDB] Emit old fpo data to the PDB file. r342003 added support for emitting FPO data from the DEBUG_S_FRAMEDATA subsection of the .debug$S section to the PDB file. However, that is not the end of the story. FPO can end up in two different destinations in a PDB, each corresponding to a different FPO data source. The case handled by r342003 involves copying data from the DEBUG_S_FRAMEDATA subsection of the .debug$S section to the "New FPO" stream in the PDB, which is then referred to by the DBI stream. The case handled by this patch involves copying records from the .debug$F section of an object file to the "FPO" stream (or perhaps more aptly, the "Old FPO" stream) in the PDB file, which is also referred to by the DBI stream. The formats are largely similar, and the difference is mostly only visible in masm generated object files, such as some of the low-level CRT object files like memcpy. MASM doesn't appear to support writing the DEBUG_S_FRAMEDATA subsection, and instead just writes these records to the .debug$F section. Although clang-cl does not emit a .debug$F section ever, lld still needs to support it so we have good debugging for CRT functions. Differential Revision: https://reviews.llvm.org/D51958 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342080 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index 826e0c179cc..b538de57667 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -33,6 +33,7 @@ class MSFBuilder; } namespace object { struct coff_section; +struct FpoData; } namespace pdb { class DbiStream; @@ -69,7 +70,8 @@ public: void setGlobalsStreamIndex(uint32_t Index); void setPublicsStreamIndex(uint32_t Index); void setSymbolRecordStreamIndex(uint32_t Index); - void addFrameData(const codeview::FrameData &FD); + void addNewFpoData(const codeview::FrameData &FD); + void addOldFpoData(const object::FpoData &Fpo); Expected addModuleInfo(StringRef ModuleName); Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File); @@ -123,7 +125,8 @@ private: std::vector> ModiList; - Optional FrameData; + Optional NewFpoData; + std::vector OldFpoData; StringMap SourceFileNames; diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 222ade2bdf9..e39a9b2e31c 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -594,6 +594,8 @@ enum class coff_guard_flags : uint32_t { FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes }; +enum class frame_type : uint16_t { Fpo = 0, Trap = 1, Tss = 2, NonFpo = 3 }; + struct coff_load_config_code_integrity { support::ulittle16_t Flags; support::ulittle16_t Catalog; @@ -1228,7 +1230,7 @@ struct FpoData { bool useBP() const { return (Attributes >> 10) & 1; } // cbFrame: frame pointer - int getFP() const { return Attributes >> 14; } + frame_type getFP() const { return static_cast(Attributes >> 14); } }; } // end namespace object diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp index 9b045f916db..094216ea800 100644 --- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -75,11 +75,15 @@ void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) { PublicsStreamIndex = Index; } -void DbiStreamBuilder::addFrameData(const codeview::FrameData &FD) { - if (!FrameData.hasValue()) - FrameData.emplace(false); +void DbiStreamBuilder::addNewFpoData(const codeview::FrameData &FD) { + if (!NewFpoData.hasValue()) + NewFpoData.emplace(false); - FrameData->addFrameData(FD); + NewFpoData->addFrameData(FD); +} + +void DbiStreamBuilder::addOldFpoData(const object::FpoData &FD) { + OldFpoData.push_back(FD); } Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type, @@ -286,13 +290,23 @@ Error DbiStreamBuilder::finalize() { } Error DbiStreamBuilder::finalizeMsfLayout() { - if (FrameData.hasValue()) { + if (NewFpoData.hasValue()) { DbgStreams[(int)DbgHeaderType::NewFPO].emplace(); DbgStreams[(int)DbgHeaderType::NewFPO]->Size = - FrameData->calculateSerializedSize(); + NewFpoData->calculateSerializedSize(); DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn = [this](BinaryStreamWriter &Writer) { - return FrameData->commit(Writer); + return NewFpoData->commit(Writer); + }; + } + + if (!OldFpoData.empty()) { + DbgStreams[(int)DbgHeaderType::FPO].emplace(); + DbgStreams[(int)DbgHeaderType::FPO]->Size = + sizeof(object::FpoData) * OldFpoData.size(); + DbgStreams[(int)DbgHeaderType::FPO]->WriteFn = + [this](BinaryStreamWriter &Writer) { + return Writer.writeArray(makeArrayRef(OldFpoData)); }; } diff --git a/tools/llvm-pdbutil/DumpOutputStyle.cpp b/tools/llvm-pdbutil/DumpOutputStyle.cpp index 60f79f05e01..9869b3ae4d2 100644 --- a/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -991,22 +991,56 @@ Error DumpOutputStyle::dumpXme() { return Error::success(); } -Error DumpOutputStyle::dumpFpo() { - printHeader(P, "New FPO Data"); +std::string formatFrameType(object::frame_type FT) { + switch (FT) { + case object::frame_type::Fpo: + return "FPO"; + case object::frame_type::NonFpo: + return "Non-FPO"; + case object::frame_type::Trap: + return "Trap"; + case object::frame_type::Tss: + return "TSS"; + } + return ""; +} - if (!File.isPdb()) { - printStreamNotValidForObj(); +Error DumpOutputStyle::dumpOldFpo(PDBFile &File) { + printHeader(P, "Old FPO Data"); + + ExitOnError Err("Error dumping old fpo data:"); + auto &Dbi = Err(File.getPDBDbiStream()); + + uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::FPO); + if (Index == kInvalidStreamIndex) { + printStreamNotPresent("FPO"); return Error::success(); } - PDBFile &File = getPdb(); - if (!File.hasPDBDbiStream()) { - printStreamNotPresent("DBI"); - return Error::success(); + std::unique_ptr OldFpo = File.createIndexedStream(Index); + BinaryStreamReader Reader(*OldFpo); + FixedStreamArray Records; + Err(Reader.readArray(Records, + Reader.bytesRemaining() / sizeof(object::FpoData))); + + P.printLine(" RVA | Code | Locals | Params | Prolog | Saved Regs | Use " + "BP | Has SEH | Frame Type"); + + for (const object::FpoData &FD : Records) { + P.formatLine("{0:X-8} | {1,4} | {2,6} | {3,6} | {4,6} | {5,10} | {6,6} | " + "{7,7} | {8,9}", + uint32_t(FD.Offset), uint32_t(FD.Size), uint32_t(FD.NumLocals), + uint32_t(FD.NumParams), FD.getPrologSize(), + FD.getNumSavedRegs(), FD.useBP(), FD.hasSEH(), + formatFrameType(FD.getFP())); } + return Error::success(); +} - ExitOnError Err("Error dumping fpo data:"); +Error DumpOutputStyle::dumpNewFpo(PDBFile &File) { + printHeader(P, "New FPO Data"); + ExitOnError Err("Error dumping new fpo data:"); auto &Dbi = Err(File.getPDBDbiStream()); uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO); @@ -1043,6 +1077,25 @@ Error DumpOutputStyle::dumpFpo() { return Error::success(); } +Error DumpOutputStyle::dumpFpo() { + if (!File.isPdb()) { + printStreamNotValidForObj(); + return Error::success(); + } + + PDBFile &File = getPdb(); + if (!File.hasPDBDbiStream()) { + printStreamNotPresent("DBI"); + return Error::success(); + } + + if (auto EC = dumpOldFpo(File)) + return EC; + if (auto EC = dumpNewFpo(File)) + return EC; + return Error::success(); +} + Error DumpOutputStyle::dumpStringTableFromPdb() { AutoIndent Indent(P); auto IS = getPdb().getStringTable(); diff --git a/tools/llvm-pdbutil/DumpOutputStyle.h b/tools/llvm-pdbutil/DumpOutputStyle.h index 946a30539a8..9b3a85587bd 100644 --- a/tools/llvm-pdbutil/DumpOutputStyle.h +++ b/tools/llvm-pdbutil/DumpOutputStyle.h @@ -86,6 +86,8 @@ private: Error dumpXmi(); Error dumpXme(); Error dumpFpo(); + Error dumpOldFpo(PDBFile &File); + Error dumpNewFpo(PDBFile &File); Error dumpTpiStream(uint32_t StreamIdx); Error dumpTypesFromObjectFile(); Error dumpModules();