[pdb] Support CoffSymbolRVA debug subsection.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305108 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zachary Turner 2017-06-09 20:46:52 +00:00
parent 6862a2be05
commit bb67f7f534
9 changed files with 169 additions and 0 deletions

View File

@ -27,6 +27,7 @@ class DebugCrossModuleImportsSubsectionRef;
class DebugFrameDataSubsectionRef;
class DebugLinesSubsectionRef;
class DebugStringTableSubsectionRef;
class DebugSymbolRVASubsectionRef;
class DebugSymbolsSubsectionRef;
class DebugUnknownSubsectionRef;
@ -108,6 +109,8 @@ public:
virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
const DebugSubsectionState &State) = 0;
virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
const DebugSubsectionState &State) = 0;
};
Error visitDebugSubsection(const DebugSubsectionRecord &R,

View File

@ -0,0 +1,59 @@
//===- DebugSymbolRVASubsection.h -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLRVASUBSECTION_H
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace codeview {
class DebugSymbolRVASubsectionRef final : public DebugSubsectionRef {
public:
typedef FixedStreamArray<support::ulittle32_t> ArrayType;
DebugSymbolRVASubsectionRef();
static bool classof(const DebugSubsectionRef *S) {
return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
}
ArrayType::Iterator begin() const { return RVAs.begin(); }
ArrayType::Iterator end() const { return RVAs.end(); }
Error initialize(BinaryStreamReader &Reader);
private:
ArrayType RVAs;
};
class DebugSymbolRVASubsection final : public DebugSubsection {
public:
DebugSymbolRVASubsection();
static bool classof(const DebugSubsection *S) {
return S->kind() == DebugSubsectionKind::CoffSymbolRVA;
}
Error commit(BinaryStreamWriter &Writer) const override;
uint32_t calculateSerializedSize() const override;
void addRVA(uint32_t RVA) { RVAs.push_back(support::ulittle32_t(RVA)); }
private:
std::vector<support::ulittle32_t> RVAs;
};
} // namespace codeview
} // namespace llvm
#endif

View File

@ -13,6 +13,7 @@ add_llvm_library(LLVMDebugInfoCodeView
DebugSubsection.cpp
DebugSubsectionRecord.cpp
DebugSubsectionVisitor.cpp
DebugSymbolRVASubsection.cpp
DebugSymbolsSubsection.cpp
EnumTables.cpp
Formatters.cpp

View File

@ -17,6 +17,7 @@
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/Support/BinaryStreamReader.h"
@ -111,6 +112,12 @@ Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
return EC;
return V.visitFrameData(Section, State);
}
case DebugSubsectionKind::CoffSymbolRVA: {
DebugSymbolRVASubsectionRef Section;
if (auto EC = Section.initialize(Reader))
return EC;
return V.visitCOFFSymbolRVAs(Section, State);
}
default: {
DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
return V.visitUnknown(Fragment);

View File

@ -0,0 +1,31 @@
//===- DebugSymbolRVASubsection.cpp ------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
using namespace llvm;
using namespace llvm::codeview;
DebugSymbolRVASubsectionRef::DebugSymbolRVASubsectionRef()
: DebugSubsectionRef(DebugSubsectionKind::CoffSymbolRVA) {}
Error DebugSymbolRVASubsectionRef::initialize(BinaryStreamReader &Reader) {
return Reader.readArray(RVAs, Reader.bytesRemaining() / sizeof(uint32_t));
}
DebugSymbolRVASubsection::DebugSymbolRVASubsection()
: DebugSubsection(DebugSubsectionKind::CoffSymbolRVA) {}
Error DebugSymbolRVASubsection::commit(BinaryStreamWriter &Writer) const {
return Writer.writeArray(makeArrayRef(RVAs));
}
uint32_t DebugSymbolRVASubsection::calculateSerializedSize() const {
return RVAs.size() * sizeof(uint32_t);
}

View File

@ -25,6 +25,7 @@
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@ -208,6 +209,21 @@ struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
std::vector<YAMLFrameData> Frames;
};
struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
YAMLCoffSymbolRVASubsection()
: YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
void map(IO &IO) override;
std::unique_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator &Allocator,
DebugStringTableSubsection *Strings,
DebugChecksumsSubsection *Checksums) const override;
static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
std::vector<uint32_t> RVAs;
};
}
void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
@ -337,6 +353,11 @@ void YAMLFrameDataSubsection::map(IO &IO) {
IO.mapRequired("Frames", Frames);
}
void YAMLCoffSymbolRVASubsection::map(IO &IO) {
IO.mapTag("!COFFSymbolRVAs", true);
IO.mapRequired("RVAs", RVAs);
}
void MappingTraits<YAMLDebugSubsection>::mapping(
IO &IO, YAMLDebugSubsection &Subsection) {
if (!IO.outputting()) {
@ -359,6 +380,8 @@ void MappingTraits<YAMLDebugSubsection>::mapping(
Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
} else if (IO.mapTag("!FrameData")) {
Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
} else if (IO.mapTag("!COFFSymbolRVAs")) {
Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
} else {
llvm_unreachable("Unexpected subsection tag!");
}
@ -502,6 +525,16 @@ std::unique_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
return std::move(Result);
}
std::unique_ptr<DebugSubsection>
YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings,
DebugChecksumsSubsection *Checksums) const {
auto Result = llvm::make_unique<DebugSymbolRVASubsection>();
for (const auto &RVA : RVAs)
Result->addRVA(RVA);
return std::move(Result);
}
static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
const FileChecksumEntry &CS) {
@ -698,6 +731,16 @@ YAMLFrameDataSubsection::fromCodeViewSubsection(
return Result;
}
Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
const DebugSymbolRVASubsectionRef &Section) {
auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
for (const auto &RVA : Section) {
Result->RVAs.push_back(RVA);
}
return Result;
}
Expected<std::vector<std::unique_ptr<DebugSubsection>>>
llvm::CodeViewYAML::toCodeViewSubsectionList(
BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
@ -782,6 +825,8 @@ struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
const DebugSubsectionState &State) override;
Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
const DebugSubsectionState &State) override;
Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
const DebugSubsectionState &State) override;
YAMLDebugSubsection Subsection;
};
@ -871,6 +916,15 @@ Error SubsectionConversionVisitor::visitFrameData(
Subsection.Subsection = *Result;
return Error::success();
}
Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
DebugSymbolRVASubsectionRef &RVAs, const DebugSubsectionState &State) {
auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
if (!Result)
return Result.takeError();
Subsection.Subsection = *Result;
return Error::success();
}
}
Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection(

View File

@ -22,6 +22,7 @@
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
@ -286,6 +287,16 @@ public:
return Error::success();
}
Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
const DebugSubsectionState &State) override {
if (!opts::checkModuleSubsection(opts::ModuleSubsection::CoffSymbolRVAs))
return Error::success();
ListScope D(P, "COFF Symbol RVAs");
P.printHexList("RVAs", RVAs);
return Error::success();
}
private:
Error dumpTypeRecord(StringRef Label, TypeIndex Index) {
CompactTypeDumpVisitor CTDV(IPI, Index, &P);

View File

@ -442,6 +442,8 @@ cl::list<ModuleSubsection> DumpModuleSubsections(
clEnumValN(ModuleSubsection::Symbols, "symbols",
"Symbols (DEBUG_S_SYMBOLS subsection) (not typically "
"present in PDB file)"),
clEnumValN(ModuleSubsection::CoffSymbolRVAs, "rvas",
"COFF Symbol RVAs (DEBUG_S_COFF_SYMBOL_RVA subsection)"),
clEnumValN(ModuleSubsection::Unknown, "unknown",
"Any subsection not covered by another option"),
clEnumValN(ModuleSubsection::All, "all", "All known subsections")),

View File

@ -37,6 +37,7 @@ enum class ModuleSubsection {
StringTable,
Symbols,
FrameData,
CoffSymbolRVAs,
All
};