aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp44
-rw-r--r--llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp27
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp16
-rw-r--r--llvm/lib/MC/MCStreamer.cpp1
4 files changed, 65 insertions, 23 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 3f3408e..b09925b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -15,12 +15,14 @@
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Line.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/MC/MCExpr.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/COFF.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetFrameLowering.h"
@@ -282,22 +284,34 @@ void CodeViewDebug::emitTypeInformation() {
OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
emitCodeViewMagicVersion();
+ SmallString<8> CommentPrefix;
+ if (OS.isVerboseAsm()) {
+ CommentPrefix += '\t';
+ CommentPrefix += Asm->MAI->getCommentString();
+ CommentPrefix += ' ';
+ }
+
+ CVTypeDumper CVTD(nullptr, /*PrintRecordBytes=*/false);
TypeTable.ForEachRecord(
- [&](TypeIndex Index, const MemoryTypeTableBuilder::Record *R) {
- // Each record should be 4 byte aligned. We achieve that by emitting
- // LF_PAD padding bytes. The on-disk record size includes the padding
- // bytes so that consumers don't have to skip past them.
- uint64_t RecordSize = R->size() + 2;
- uint64_t AlignedSize = alignTo(RecordSize, 4);
- uint64_t AlignedRecordSize = AlignedSize - 2;
- assert(AlignedRecordSize < (1 << 16) && "type record size overflow");
- OS.AddComment("Type record length");
- OS.EmitIntValue(AlignedRecordSize, 2);
- OS.AddComment("Type record data");
- OS.EmitBytes(StringRef(R->data(), R->size()));
- // Pad the record with LF_PAD bytes.
- for (unsigned I = AlignedSize - RecordSize; I > 0; --I)
- OS.EmitIntValue(LF_PAD0 + I, 1);
+ [&](TypeIndex Index, StringRef Record) {
+ if (OS.isVerboseAsm()) {
+ // Emit a block comment describing the type record for readability.
+ SmallString<512> CommentBlock;
+ raw_svector_ostream CommentOS(CommentBlock);
+ ScopedPrinter SP(CommentOS);
+ SP.setPrefix(CommentPrefix);
+ CVTD.setPrinter(&SP);
+ bool DumpSuccess =
+ CVTD.dump({Record.bytes_begin(), Record.bytes_end()});
+ (void)DumpSuccess;
+ assert(DumpSuccess && "produced malformed type record");
+ // emitRawComment will insert its own tab and comment string before
+ // the first line, so strip off our first one. It also prints its own
+ // newline.
+ OS.emitRawComment(
+ CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim());
+ }
+ OS.EmitBinaryData(Record);
});
}
diff --git a/llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp
index 9afce92e..8b9e73b 100644
--- a/llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp
+++ b/llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp
@@ -13,23 +13,34 @@
using namespace llvm;
using namespace codeview;
-MemoryTypeTableBuilder::Record::Record(StringRef RData)
- : Size(RData.size()), Data(new char[RData.size()]) {
- memcpy(Data.get(), RData.data(), RData.size());
-}
-
TypeIndex MemoryTypeTableBuilder::writeRecord(StringRef Data) {
+ assert(Data.size() <= UINT16_MAX);
auto I = HashedRecords.find(Data);
if (I != HashedRecords.end()) {
return I->second;
}
- std::unique_ptr<Record> R(new Record(Data));
+ // The record provided by the user lacks the 2 byte size field prefix and is
+ // not padded to 4 bytes. Ultimately, that is what gets emitted in the object
+ // file, so pad it out now.
+ const int SizeOfRecLen = 2;
+ const int Align = 4;
+ int TotalSize = alignTo(Data.size() + SizeOfRecLen, Align);
+ assert(TotalSize - SizeOfRecLen <= UINT16_MAX);
+ char *Mem =
+ reinterpret_cast<char *>(RecordStorage.Allocate(TotalSize, Align));
+ *reinterpret_cast<ulittle16_t *>(Mem) = uint16_t(TotalSize - SizeOfRecLen);
+ memcpy(Mem + SizeOfRecLen, Data.data(), Data.size());
+ for (int I = Data.size() + SizeOfRecLen; I < TotalSize; ++I)
+ Mem[I] = LF_PAD0 + (TotalSize - I);
TypeIndex TI(static_cast<uint32_t>(Records.size()) +
TypeIndex::FirstNonSimpleIndex);
- HashedRecords.insert(std::make_pair(StringRef(R->data(), R->size()), TI));
- Records.push_back(std::move(R));
+
+ // Use only the data supplied by the user as a key to the hash table, so that
+ // future lookups will succeed.
+ HashedRecords.insert(std::make_pair(StringRef(Mem + SizeOfRecLen, Data.size()), TI));
+ Records.push_back(StringRef(Mem, TotalSize));
return TI;
}
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 5fbecb4..c85ffd5 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -162,6 +162,8 @@ public:
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
+ void EmitBinaryData(StringRef Data) override;
+
void EmitBytes(StringRef Data) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
@@ -709,6 +711,20 @@ void MCAsmStreamer::EmitBytes(StringRef Data) {
EmitEOL();
}
+void MCAsmStreamer::EmitBinaryData(StringRef Data) {
+ // This is binary data. Print it in a grid of hex bytes for readability.
+ const size_t Cols = 4;
+ for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
+ size_t J = I, EJ = std::min(I + Cols, Data.size());
+ assert(EJ > 0);
+ OS << MAI->getData8bitsDirective();
+ for (; J < EJ - 1; ++J)
+ OS << format("0x%02x", uint8_t(Data[J])) << ", ";
+ OS << format("0x%02x", uint8_t(Data[J]));
+ EmitEOL();
+ }
+}
+
void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
EmitValue(MCConstantExpr::create(Value, getContext()), Size);
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 9ed5a5f..8872d32 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -761,6 +761,7 @@ void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
void MCStreamer::EmitBytes(StringRef Data) {}
+void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
visitUsedExpr(*Value);
}