summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp51
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h6
-rw-r--r--llvm/lib/DebugInfo/CodeView/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp127
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp6
-rw-r--r--llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp8
6 files changed, 186 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 4c215932d62..97b59491c3d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -67,10 +67,12 @@
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Target/TargetMachine.h"
@@ -88,6 +90,9 @@
using namespace llvm;
using namespace llvm::codeview;
+static cl::opt<bool> EmitDebugGlobalHashes("emit-codeview-ghash-section",
+ cl::ReallyHidden, cl::init(false));
+
CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
: DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {
// If module doesn't have named metadata anchors or COFF debug section
@@ -486,10 +491,13 @@ void CodeViewDebug::endModule() {
OS.AddComment("String table");
OS.EmitCVStringTableDirective();
- // Emit type information last, so that any types we translate while emitting
- // function info are included.
+ // Emit type information and hashes last, so that any types we translate while
+ // emitting function info are included.
emitTypeInformation();
+ if (EmitDebugGlobalHashes)
+ emitTypeGlobalHashes();
+
clear();
}
@@ -506,11 +514,6 @@ static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) {
}
void CodeViewDebug::emitTypeInformation() {
- // Do nothing if we have no debug info or if no non-trivial types were emitted
- // to TypeTable during codegen.
- NamedMDNode *CU_Nodes = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
- if (!CU_Nodes)
- return;
if (TypeTable.empty())
return;
@@ -555,6 +558,40 @@ void CodeViewDebug::emitTypeInformation() {
}
}
+void CodeViewDebug::emitTypeGlobalHashes() {
+ if (TypeTable.empty())
+ return;
+
+ // Start the .debug$H section with the version and hash algorithm, currently
+ // hardcoded to version 0, SHA1.
+ OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
+
+ OS.EmitValueToAlignment(4);
+ OS.AddComment("Magic");
+ OS.EmitIntValue(COFF::DEBUG_HASHES_SECTION_MAGIC, 4);
+ OS.AddComment("Section Version");
+ OS.EmitIntValue(0, 2);
+ OS.AddComment("Hash Algorithm");
+ OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1), 2);
+
+ TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
+ for (const auto &GHR : TypeTable.hashes()) {
+ if (OS.isVerboseAsm()) {
+ // Emit an EOL-comment describing which TypeIndex this hash corresponds
+ // to, as well as the stringified SHA1 hash.
+ SmallString<32> Comment;
+ raw_svector_ostream CommentOS(Comment);
+ CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR);
+ OS.AddComment(Comment);
+ ++TI;
+ }
+ assert(GHR.Hash.size() % 20 == 0);
+ StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
+ GHR.Hash.size());
+ OS.EmitBinaryData(S);
+ }
+}
+
static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
switch (DWLang) {
case dwarf::DW_LANG_C:
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 663b9b50c9d..69e93640d7e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -23,7 +23,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/Allocator.h"
@@ -52,7 +52,7 @@ class MachineFunction;
class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
MCStreamer &OS;
BumpPtrAllocator Allocator;
- codeview::MergingTypeTableBuilder TypeTable;
+ codeview::GlobalTypeTableBuilder TypeTable;
/// Represents the most general definition range.
struct LocalVarDefRange {
@@ -219,6 +219,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitTypeInformation();
+ void emitTypeGlobalHashes();
+
void emitCompilerInformation();
void emitInlineeLinesSubsection();
diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
index c3d79c0d6e6..0515788d85e 100644
--- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_library(LLVMDebugInfoCodeView
DebugSymbolsSubsection.cpp
EnumTables.cpp
Formatters.cpp
+ GlobalTypeTableBuilder.cpp
LazyRandomTypeCollection.cpp
Line.cpp
MergingTypeTableBuilder.cpp
diff --git a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
new file mode 100644
index 00000000000..3ecd684c1e3
--- /dev/null
+++ b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
@@ -0,0 +1,127 @@
+//===- GlobalTypeTableBuilder.cpp -----------------------------------------===//
+//
+// 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/GlobalTypeTableBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+TypeIndex GlobalTypeTableBuilder::nextTypeIndex() const {
+ return TypeIndex::fromArrayIndex(SeenRecords.size());
+}
+
+GlobalTypeTableBuilder::GlobalTypeTableBuilder(BumpPtrAllocator &Storage)
+ : RecordStorage(Storage) {
+ SeenRecords.reserve(4096);
+}
+
+GlobalTypeTableBuilder::~GlobalTypeTableBuilder() = default;
+
+Optional<TypeIndex> GlobalTypeTableBuilder::getFirst() {
+ if (empty())
+ return None;
+
+ return TypeIndex(TypeIndex::FirstNonSimpleIndex);
+}
+
+Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) {
+ if (++Prev == nextTypeIndex())
+ return None;
+ return Prev;
+}
+
+CVType GlobalTypeTableBuilder::getType(TypeIndex Index) {
+ CVType Type;
+ Type.RecordData = SeenRecords[Index.toArrayIndex()];
+ const RecordPrefix *P =
+ reinterpret_cast<const RecordPrefix *>(Type.RecordData.data());
+ Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
+ return Type;
+}
+
+StringRef GlobalTypeTableBuilder::getTypeName(TypeIndex Index) {
+ llvm_unreachable("Method not implemented");
+}
+
+bool GlobalTypeTableBuilder::contains(TypeIndex Index) {
+ if (Index.isSimple() || Index.isNoneType())
+ return false;
+
+ return Index.toArrayIndex() < SeenRecords.size();
+}
+
+uint32_t GlobalTypeTableBuilder::size() { return SeenRecords.size(); }
+
+uint32_t GlobalTypeTableBuilder::capacity() { return SeenRecords.size(); }
+
+ArrayRef<ArrayRef<uint8_t>> GlobalTypeTableBuilder::records() const {
+ return SeenRecords;
+}
+
+ArrayRef<GloballyHashedType> GlobalTypeTableBuilder::hashes() const {
+ return SeenHashes;
+}
+
+void GlobalTypeTableBuilder::reset() {
+ HashedRecords.clear();
+ SeenRecords.clear();
+}
+
+static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
+ ArrayRef<uint8_t> Data) {
+ uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
+ memcpy(Stable, Data.data(), Data.size());
+ return makeArrayRef(Stable, Data.size());
+}
+
+TypeIndex GlobalTypeTableBuilder::insertRecordAs(GloballyHashedType Hash,
+ CreateRecord Create) {
+ auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex());
+
+ if (Result.second) {
+ ArrayRef<uint8_t> RecordData = stabilize(RecordStorage, Create());
+ SeenRecords.push_back(RecordData);
+ SeenHashes.push_back(Hash);
+ }
+
+ // Update the caller's copy of Record to point a stable copy.
+ return Result.first->second;
+}
+
+TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) {
+ GloballyHashedType GHT =
+ GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
+ return insertRecordAs(GHT, [Record]() { return Record; });
+}
+
+TypeIndex
+GlobalTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
+ TypeIndex TI;
+ auto Fragments = Builder.end(nextTypeIndex());
+ assert(!Fragments.empty());
+ for (auto C : Fragments)
+ TI = insertRecordBytes(C.RecordData);
+ return TI;
+}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index ba0146fd9fc..a6b5c43f1d2 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -185,6 +185,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
COFFDebugSymbolsSection = nullptr;
COFFDebugTypesSection = nullptr;
+ COFFGlobalTypeHashesSection = nullptr;
if (useCompactUnwind(T)) {
CompactUnwindSection =
@@ -655,6 +656,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ),
SectionKind::getMetadata());
+ COFFGlobalTypeHashesSection = Ctx->getCOFFSection(
+ ".debug$H",
+ (COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ),
+ SectionKind::getMetadata());
DwarfAbbrevSection = Ctx->getCOFFSection(
".debug_abbrev",
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
index b35e8ab05ad..bbbd7c06772 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
@@ -44,11 +44,11 @@ StringRef ScalarTraits<GlobalHash>::input(StringRef Scalar, void *Ctx,
} // end namespace yaml
} // end namespace llvm
-DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef<uint8_t> DebugT) {
- assert(DebugT.size() >= 8);
- assert((DebugT.size() - 8) % 20 == 0);
+DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef<uint8_t> DebugH) {
+ assert(DebugH.size() >= 8);
+ assert((DebugH.size() - 8) % 20 == 0);
- BinaryStreamReader Reader(DebugT, llvm::support::little);
+ BinaryStreamReader Reader(DebugH, llvm::support::little);
DebugHSection DHS;
cantFail(Reader.readInteger(DHS.Magic));
cantFail(Reader.readInteger(DHS.Version));
OpenPOWER on IntegriCloud