summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj/COFFDumper.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-05-14 00:02:53 +0000
committerReid Kleckner <rnk@google.com>2016-05-14 00:02:53 +0000
commit0b269748a6592c263394123a0de15740ad19c152 (patch)
tree5cd58f5a187c9d10b89a60b354007f207313b65c /llvm/tools/llvm-readobj/COFFDumper.cpp
parent32b2897af6101e843f8fa90750e0de2a8a84d1cd (diff)
downloadbcm5719-llvm-0b269748a6592c263394123a0de15740ad19c152.tar.gz
bcm5719-llvm-0b269748a6592c263394123a0de15740ad19c152.zip
[codeview] Add type stream merging prototype
Summary: This code is intended to be used as part of LLD's PDB writing. Until that exists, this is exposed via llvm-readobj for testing purposes. Type stream merging uses the following algorithm: - Begin with a new empty stream, and a new empty hash table that maps from type record contents to new type index. - For each new type stream, maintain a map from source type index to destination type index. - For each record, copy it and rewrite its type indices to be valid in the destination type stream. - If the new type record is not already present in the destination stream hash table, append it to the destination type stream, assign it the next type index, and update the two hash tables. - If the type record already exists in the destination stream, discard it and update the type index map to forward the source type index to the existing destination type index. Reviewers: zturner, ruiu Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D20122 llvm-svn: 269521
Diffstat (limited to 'llvm/tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 6cb543b4251..af3a79d3d1e 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -25,11 +25,13 @@
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDumper.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeStream.h"
+#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/COFF.h"
@@ -71,6 +73,8 @@ public:
void printCOFFDirectives() override;
void printCOFFBaseReloc() override;
void printCodeViewDebugInfo() override;
+ void
+ mergeCodeViewTypes(llvm::codeview::MemoryTypeTableBuilder &CVTypes) override;
void printStackMap() const override;
private:
void printSymbol(const SymbolRef &Sym);
@@ -1621,6 +1625,25 @@ void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) {
W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset);
}
+void COFFDumper::mergeCodeViewTypes(MemoryTypeTableBuilder &CVTypes) {
+ for (const SectionRef &S : Obj->sections()) {
+ StringRef SectionName;
+ error(S.getName(SectionName));
+ if (SectionName == ".debug$T") {
+ StringRef Data;
+ error(S.getContents(Data));
+ unsigned Magic = *reinterpret_cast<const ulittle32_t *>(Data.data());
+ if (Magic != 4)
+ error(object_error::parse_failed);
+ Data = Data.drop_front(4);
+ ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
+ Data.size());
+ if (!mergeTypeStreams(CVTypes, Bytes))
+ return error(object_error::parse_failed);
+ }
+ }
+}
+
void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
const SectionRef &Section) {
ListScope D(W, "CodeViewTypes");
@@ -2076,3 +2099,23 @@ void COFFDumper::printStackMap() const {
prettyPrintStackMap(llvm::outs(),
StackMapV1Parser<support::big>(StackMapContentsArray));
}
+
+void llvm::dumpCodeViewMergedTypes(
+ ScopedPrinter &Writer, llvm::codeview::MemoryTypeTableBuilder &CVTypes) {
+ // Flatten it first, then run our dumper on it.
+ ListScope S(Writer, "MergedTypeStream");
+ SmallString<0> Buf;
+ CVTypes.ForEachRecord([&](TypeIndex TI, MemoryTypeTableBuilder::Record *R) {
+ // The record data doesn't include the 16 bit size.
+ Buf.push_back(R->size() & 0xff);
+ Buf.push_back((R->size() >> 8) & 0xff);
+ Buf.append(R->data(), R->data() + R->size());
+ });
+ CVTypeDumper CVTD(Writer, opts::CodeViewSubsectionBytes);
+ ArrayRef<uint8_t> BinaryData(reinterpret_cast<const uint8_t *>(Buf.data()),
+ Buf.size());
+ if (!CVTD.dump(BinaryData)) {
+ Writer.flush();
+ error(object_error::parse_failed);
+ }
+}
OpenPOWER on IntegriCloud