mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[PDB] Write FPO Data to the PDB.
llvm-svn: 342003
This commit is contained in:
parent
7cb4830192
commit
43a811852d
@ -26,11 +26,12 @@ public:
|
||||
}
|
||||
|
||||
Error initialize(BinaryStreamReader Reader);
|
||||
Error initialize(BinaryStreamRef Stream);
|
||||
|
||||
FixedStreamArray<FrameData>::Iterator begin() const { return Frames.begin(); }
|
||||
FixedStreamArray<FrameData>::Iterator end() const { return Frames.end(); }
|
||||
|
||||
const void *getRelocPtr() const { return RelocPtr; }
|
||||
const uint32_t *getRelocPtr() const { return RelocPtr; }
|
||||
|
||||
private:
|
||||
const uint32_t *RelocPtr = nullptr;
|
||||
@ -39,8 +40,9 @@ private:
|
||||
|
||||
class DebugFrameDataSubsection final : public DebugSubsection {
|
||||
public:
|
||||
DebugFrameDataSubsection()
|
||||
: DebugSubsection(DebugSubsectionKind::FrameData) {}
|
||||
DebugFrameDataSubsection(bool IncludeRelocPtr)
|
||||
: DebugSubsection(DebugSubsectionKind::FrameData),
|
||||
IncludeRelocPtr(IncludeRelocPtr) {}
|
||||
static bool classof(const DebugSubsection *S) {
|
||||
return S->kind() == DebugSubsectionKind::FrameData;
|
||||
}
|
||||
@ -52,6 +54,7 @@ public:
|
||||
void setFrames(ArrayRef<FrameData> Frames);
|
||||
|
||||
private:
|
||||
bool IncludeRelocPtr = false;
|
||||
std::vector<FrameData> Frames;
|
||||
};
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "llvm/BinaryFormat/COFF.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
|
||||
@ -24,6 +25,9 @@
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
struct FrameData;
|
||||
}
|
||||
namespace msf {
|
||||
class MSFBuilder;
|
||||
}
|
||||
@ -65,6 +69,7 @@ public:
|
||||
void setGlobalsStreamIndex(uint32_t Index);
|
||||
void setPublicsStreamIndex(uint32_t Index);
|
||||
void setSymbolRecordStreamIndex(uint32_t Index);
|
||||
void addFrameData(const codeview::FrameData &FD);
|
||||
|
||||
Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
|
||||
Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
|
||||
@ -84,7 +89,8 @@ public:
|
||||
|
||||
private:
|
||||
struct DebugStream {
|
||||
ArrayRef<uint8_t> Data;
|
||||
std::function<Error(BinaryStreamWriter &)> WriteFn;
|
||||
uint32_t Size = 0;
|
||||
uint16_t StreamNumber = kInvalidStreamIndex;
|
||||
};
|
||||
|
||||
@ -117,6 +123,8 @@ private:
|
||||
|
||||
std::vector<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiList;
|
||||
|
||||
Optional<codeview::DebugFrameDataSubsection> FrameData;
|
||||
|
||||
StringMap<uint32_t> SourceFileNames;
|
||||
|
||||
PDBStringTableBuilder ECNamesBuilder;
|
||||
|
@ -14,8 +14,11 @@ using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
|
||||
Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
|
||||
if (auto EC = Reader.readObject(RelocPtr))
|
||||
return EC;
|
||||
if (Reader.bytesRemaining() % sizeof(FrameData) != 0) {
|
||||
if (auto EC = Reader.readObject(RelocPtr))
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (Reader.bytesRemaining() % sizeof(FrameData) != 0)
|
||||
return make_error<CodeViewError>(cv_error_code::corrupt_record,
|
||||
"Invalid frame data record format!");
|
||||
@ -26,15 +29,30 @@ Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error DebugFrameDataSubsectionRef::initialize(BinaryStreamRef Section) {
|
||||
BinaryStreamReader Reader(Section);
|
||||
return initialize(Reader);
|
||||
}
|
||||
|
||||
uint32_t DebugFrameDataSubsection::calculateSerializedSize() const {
|
||||
return 4 + sizeof(FrameData) * Frames.size();
|
||||
uint32_t Size = sizeof(FrameData) * Frames.size();
|
||||
if (IncludeRelocPtr)
|
||||
Size += sizeof(uint32_t);
|
||||
return Size;
|
||||
}
|
||||
|
||||
Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
|
||||
if (auto EC = Writer.writeInteger<uint32_t>(0))
|
||||
return EC;
|
||||
if (IncludeRelocPtr) {
|
||||
if (auto EC = Writer.writeInteger<uint32_t>(0))
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (auto EC = Writer.writeArray(makeArrayRef(Frames)))
|
||||
std::vector<FrameData> SortedFrames(Frames.begin(), Frames.end());
|
||||
std::sort(SortedFrames.begin(), SortedFrames.end(),
|
||||
[](const FrameData &LHS, const FrameData &RHS) {
|
||||
return LHS.RvaStart < RHS.RvaStart;
|
||||
});
|
||||
if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames)))
|
||||
return EC;
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/BinaryFormat/COFF.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
|
||||
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
|
||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
|
||||
@ -74,10 +75,23 @@ void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
|
||||
PublicsStreamIndex = Index;
|
||||
}
|
||||
|
||||
void DbiStreamBuilder::addFrameData(const codeview::FrameData &FD) {
|
||||
if (!FrameData.hasValue())
|
||||
FrameData.emplace(false);
|
||||
|
||||
FrameData->addFrameData(FD);
|
||||
}
|
||||
|
||||
Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
|
||||
ArrayRef<uint8_t> Data) {
|
||||
assert(Type != DbgHeaderType::NewFPO &&
|
||||
"NewFPO data should be written via addFrameData()!");
|
||||
|
||||
DbgStreams[(int)Type].emplace();
|
||||
DbgStreams[(int)Type]->Data = Data;
|
||||
DbgStreams[(int)Type]->Size = Data.size();
|
||||
DbgStreams[(int)Type]->WriteFn = [Data](BinaryStreamWriter &Writer) {
|
||||
return Writer.writeArray(Data);
|
||||
};
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
@ -272,10 +286,20 @@ Error DbiStreamBuilder::finalize() {
|
||||
}
|
||||
|
||||
Error DbiStreamBuilder::finalizeMsfLayout() {
|
||||
if (FrameData.hasValue()) {
|
||||
DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
|
||||
DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
|
||||
FrameData->calculateSerializedSize();
|
||||
DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn =
|
||||
[this](BinaryStreamWriter &Writer) {
|
||||
return FrameData->commit(Writer);
|
||||
};
|
||||
}
|
||||
|
||||
for (auto &S : DbgStreams) {
|
||||
if (!S.hasValue())
|
||||
continue;
|
||||
auto ExpectedIndex = Msf.addStream(S->Data.size());
|
||||
auto ExpectedIndex = Msf.addStream(S->Size);
|
||||
if (!ExpectedIndex)
|
||||
return ExpectedIndex.takeError();
|
||||
S->StreamNumber = *ExpectedIndex;
|
||||
@ -406,7 +430,8 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
|
||||
auto WritableStream = WritableMappedBlockStream::createIndexedStream(
|
||||
Layout, MsfBuffer, Stream->StreamNumber, Allocator);
|
||||
BinaryStreamWriter DbgStreamWriter(*WritableStream);
|
||||
if (auto EC = DbgStreamWriter.writeArray(Stream->Data))
|
||||
|
||||
if (auto EC = Stream->WriteFn(DbgStreamWriter))
|
||||
return EC;
|
||||
}
|
||||
|
||||
|
@ -511,7 +511,7 @@ std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
|
||||
const codeview::StringsAndChecksums &SC) const {
|
||||
assert(SC.hasStrings());
|
||||
|
||||
auto Result = std::make_shared<DebugFrameDataSubsection>();
|
||||
auto Result = std::make_shared<DebugFrameDataSubsection>(true);
|
||||
for (const auto &YF : Frames) {
|
||||
codeview::FrameData F;
|
||||
F.CodeSize = YF.CodeSize;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
|
||||
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
|
||||
@ -142,6 +143,11 @@ Error DumpOutputStyle::dump() {
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (opts::dump::DumpFpo) {
|
||||
if (auto EC = dumpFpo())
|
||||
return EC;
|
||||
}
|
||||
|
||||
if (File.isObj()) {
|
||||
if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
|
||||
opts::dump::DumpTypeExtras)
|
||||
@ -985,6 +991,58 @@ Error DumpOutputStyle::dumpXme() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error DumpOutputStyle::dumpFpo() {
|
||||
printHeader(P, "New FPO Data");
|
||||
|
||||
if (!File.isPdb()) {
|
||||
printStreamNotValidForObj();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
PDBFile &File = getPdb();
|
||||
if (!File.hasPDBDbiStream()) {
|
||||
printStreamNotPresent("DBI");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
ExitOnError Err("Error dumping fpo data:");
|
||||
|
||||
auto &Dbi = Err(File.getPDBDbiStream());
|
||||
|
||||
uint32_t Index = Dbi.getDebugStreamIndex(DbgHeaderType::NewFPO);
|
||||
if (Index == kInvalidStreamIndex) {
|
||||
printStreamNotPresent("New FPO");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
std::unique_ptr<MappedBlockStream> NewFpo = File.createIndexedStream(Index);
|
||||
|
||||
DebugFrameDataSubsectionRef FDS;
|
||||
if (auto EC = FDS.initialize(*NewFpo))
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Invalid new fpo stream");
|
||||
|
||||
P.printLine(" RVA | Code | Locals | Params | Stack | Prolog | Saved Regs "
|
||||
"| Has SEH | Has C++EH | Start | Program");
|
||||
for (const FrameData &FD : FDS) {
|
||||
bool IsFuncStart = FD.Flags & FrameData::IsFunctionStart;
|
||||
bool HasEH = FD.Flags & FrameData::HasEH;
|
||||
bool HasSEH = FD.Flags & FrameData::HasSEH;
|
||||
|
||||
auto &StringTable = Err(File.getStringTable());
|
||||
|
||||
auto Program = Err(StringTable.getStringForID(FD.FrameFunc));
|
||||
P.formatLine("{0:X-8} | {1,4} | {2,6} | {3,6} | {4,5} | {5,6} | {6,10} | "
|
||||
"{7,7} | {8,9} | {9,5} | {10}",
|
||||
uint32_t(FD.RvaStart), uint32_t(FD.CodeSize),
|
||||
uint32_t(FD.LocalSize), uint32_t(FD.ParamsSize),
|
||||
uint32_t(FD.MaxStackSize), uint16_t(FD.PrologSize),
|
||||
uint16_t(FD.SavedRegsSize), HasSEH, HasEH, IsFuncStart,
|
||||
Program);
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error DumpOutputStyle::dumpStringTableFromPdb() {
|
||||
AutoIndent Indent(P);
|
||||
auto IS = getPdb().getStringTable();
|
||||
|
@ -85,6 +85,7 @@ private:
|
||||
Error dumpInlineeLines();
|
||||
Error dumpXmi();
|
||||
Error dumpXme();
|
||||
Error dumpFpo();
|
||||
Error dumpTpiStream(uint32_t StreamIdx);
|
||||
Error dumpTypesFromObjectFile();
|
||||
Error dumpModules();
|
||||
|
@ -501,6 +501,9 @@ cl::opt<bool>
|
||||
cl::desc("dump CodeView symbol record raw bytes"),
|
||||
cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
|
||||
|
||||
cl::opt<bool> DumpFpo("fpo", cl::desc("dump FPO records"),
|
||||
cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
|
||||
|
||||
// MODULE & FILE OPTIONS
|
||||
cl::opt<bool> DumpModules("modules", cl::desc("dump compiland information"),
|
||||
cl::cat(FileOptions), cl::sub(DumpSubcommand));
|
||||
@ -1372,6 +1375,7 @@ int main(int Argc, const char **Argv) {
|
||||
if (opts::DumpSubcommand) {
|
||||
if (opts::dump::RawAll) {
|
||||
opts::dump::DumpGlobals = true;
|
||||
opts::dump::DumpFpo = true;
|
||||
opts::dump::DumpInlineeLines = true;
|
||||
opts::dump::DumpIds = true;
|
||||
opts::dump::DumpIdExtras = true;
|
||||
|
@ -171,6 +171,7 @@ extern llvm::cl::opt<bool> DumpSectionContribs;
|
||||
extern llvm::cl::opt<bool> DumpSectionMap;
|
||||
extern llvm::cl::opt<bool> DumpModules;
|
||||
extern llvm::cl::opt<bool> DumpModuleFiles;
|
||||
extern llvm::cl::opt<bool> DumpFpo;
|
||||
extern llvm::cl::opt<bool> RawAll;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user