}
namespace object {
struct coff_section;
+struct FpoData;
}
namespace pdb {
class DbiStream;
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<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
std::vector<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiList;
- Optional<codeview::DebugFrameDataSubsection> FrameData;
+ Optional<codeview::DebugFrameDataSubsection> NewFpoData;
+ std::vector<object::FpoData> OldFpoData;
StringMap<uint32_t> SourceFileNames;
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;
bool useBP() const { return (Attributes >> 10) & 1; }
// cbFrame: frame pointer
- int getFP() const { return Attributes >> 14; }
+ frame_type getFP() const { return static_cast<frame_type>(Attributes >> 14); }
};
} // end namespace object
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,
}
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));
};
}
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 "<unknown>";
+}
- 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<MappedBlockStream> OldFpo = File.createIndexedStream(Index);
+ BinaryStreamReader Reader(*OldFpo);
+ FixedStreamArray<object::FpoData> 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);
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();