diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/MemoryTypeTableBuilder.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 1 |
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); } |