1855fc3bbSJonas Devlieghere //===- llvm/CodeGen/AsmPrinter/AccelTable.cpp - Accelerator Tables --------===// 2855fc3bbSJonas Devlieghere // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6855fc3bbSJonas Devlieghere // 7855fc3bbSJonas Devlieghere //===----------------------------------------------------------------------===// 8855fc3bbSJonas Devlieghere // 9855fc3bbSJonas Devlieghere // This file contains support for writing accelerator tables. 10855fc3bbSJonas Devlieghere // 11855fc3bbSJonas Devlieghere //===----------------------------------------------------------------------===// 12855fc3bbSJonas Devlieghere 13855fc3bbSJonas Devlieghere #include "llvm/CodeGen/AccelTable.h" 146088c234SPavel Labath #include "DwarfCompileUnit.h" 15855fc3bbSJonas Devlieghere #include "llvm/ADT/STLExtras.h" 16855fc3bbSJonas Devlieghere #include "llvm/ADT/StringMap.h" 17855fc3bbSJonas Devlieghere #include "llvm/ADT/Twine.h" 18855fc3bbSJonas Devlieghere #include "llvm/BinaryFormat/Dwarf.h" 19855fc3bbSJonas Devlieghere #include "llvm/CodeGen/AsmPrinter.h" 20855fc3bbSJonas Devlieghere #include "llvm/CodeGen/DIE.h" 21855fc3bbSJonas Devlieghere #include "llvm/MC/MCExpr.h" 22855fc3bbSJonas Devlieghere #include "llvm/MC/MCStreamer.h" 2398062cb3SJonas Devlieghere #include "llvm/MC/MCSymbol.h" 24855fc3bbSJonas Devlieghere #include "llvm/Support/raw_ostream.h" 2566cf14d0SDavid Blaikie #include "llvm/Target/TargetLoweringObjectFile.h" 26855fc3bbSJonas Devlieghere #include <algorithm> 27855fc3bbSJonas Devlieghere #include <cstddef> 28855fc3bbSJonas Devlieghere #include <cstdint> 29855fc3bbSJonas Devlieghere #include <limits> 30855fc3bbSJonas Devlieghere #include <vector> 31855fc3bbSJonas Devlieghere 32855fc3bbSJonas Devlieghere using namespace llvm; 33855fc3bbSJonas Devlieghere 34a7c457d2SPavel Labath void AccelTableBase::computeBucketCount() { 35a7c457d2SPavel Labath // First get the number of unique hashes. 36a7c457d2SPavel Labath std::vector<uint32_t> Uniques; 37a7c457d2SPavel Labath Uniques.reserve(Entries.size()); 38a7c457d2SPavel Labath for (const auto &E : Entries) 39a7c457d2SPavel Labath Uniques.push_back(E.second.HashValue); 40a7c457d2SPavel Labath array_pod_sort(Uniques.begin(), Uniques.end()); 41a7c457d2SPavel Labath std::vector<uint32_t>::iterator P = 42a7c457d2SPavel Labath std::unique(Uniques.begin(), Uniques.end()); 43a7c457d2SPavel Labath 44a7c457d2SPavel Labath UniqueHashCount = std::distance(Uniques.begin(), P); 45a7c457d2SPavel Labath 46a7c457d2SPavel Labath if (UniqueHashCount > 1024) 47a7c457d2SPavel Labath BucketCount = UniqueHashCount / 4; 48a7c457d2SPavel Labath else if (UniqueHashCount > 16) 49a7c457d2SPavel Labath BucketCount = UniqueHashCount / 2; 50a7c457d2SPavel Labath else 51a7c457d2SPavel Labath BucketCount = std::max<uint32_t>(UniqueHashCount, 1); 52a7c457d2SPavel Labath } 53a7c457d2SPavel Labath 54a7c457d2SPavel Labath void AccelTableBase::finalize(AsmPrinter *Asm, StringRef Prefix) { 55a7c457d2SPavel Labath // Create the individual hash data outputs. 56a7c457d2SPavel Labath for (auto &E : Entries) { 57a7c457d2SPavel Labath // Unique the entries. 58efd94c56SFangrui Song llvm::stable_sort(E.second.Values, 59a7c457d2SPavel Labath [](const AccelTableData *A, const AccelTableData *B) { 60a7c457d2SPavel Labath return *A < *B; 61a7c457d2SPavel Labath }); 62a7c457d2SPavel Labath E.second.Values.erase( 63a7c457d2SPavel Labath std::unique(E.second.Values.begin(), E.second.Values.end()), 64a7c457d2SPavel Labath E.second.Values.end()); 65a7c457d2SPavel Labath } 66a7c457d2SPavel Labath 67a7c457d2SPavel Labath // Figure out how many buckets we need, then compute the bucket contents and 68a7c457d2SPavel Labath // the final ordering. The hashes and offsets can be emitted by walking these 69a7c457d2SPavel Labath // data structures. We add temporary symbols to the data so they can be 70a7c457d2SPavel Labath // referenced when emitting the offsets. 71a7c457d2SPavel Labath computeBucketCount(); 72a7c457d2SPavel Labath 73a7c457d2SPavel Labath // Compute bucket contents and final ordering. 74a7c457d2SPavel Labath Buckets.resize(BucketCount); 75a7c457d2SPavel Labath for (auto &E : Entries) { 76a7c457d2SPavel Labath uint32_t Bucket = E.second.HashValue % BucketCount; 77a7c457d2SPavel Labath Buckets[Bucket].push_back(&E.second); 78a7c457d2SPavel Labath E.second.Sym = Asm->createTempSymbol(Prefix); 79a7c457d2SPavel Labath } 80a7c457d2SPavel Labath 81a7c457d2SPavel Labath // Sort the contents of the buckets by hash value so that hash collisions end 82a7c457d2SPavel Labath // up together. Stable sort makes testing easier and doesn't cost much more. 83a7c457d2SPavel Labath for (auto &Bucket : Buckets) 84efd94c56SFangrui Song llvm::stable_sort(Bucket, [](HashData *LHS, HashData *RHS) { 85a7c457d2SPavel Labath return LHS->HashValue < RHS->HashValue; 86a7c457d2SPavel Labath }); 87a7c457d2SPavel Labath } 88a7c457d2SPavel Labath 89a7c457d2SPavel Labath namespace { 906088c234SPavel Labath /// Base class for writing out Accelerator tables. It holds the common 916088c234SPavel Labath /// functionality for the two Accelerator table types. 92e60ca777SJonas Devlieghere class AccelTableWriter { 93a7c457d2SPavel Labath protected: 94a7c457d2SPavel Labath AsmPrinter *const Asm; ///< Destination. 95a7c457d2SPavel Labath const AccelTableBase &Contents; ///< Data to emit. 96a7c457d2SPavel Labath 97a7c457d2SPavel Labath /// Controls whether to emit duplicate hash and offset table entries for names 98a7c457d2SPavel Labath /// with identical hashes. Apple tables don't emit duplicate entries, DWARF v5 99a7c457d2SPavel Labath /// tables do. 100a7c457d2SPavel Labath const bool SkipIdenticalHashes; 101a7c457d2SPavel Labath 102a7c457d2SPavel Labath void emitHashes() const; 103a7c457d2SPavel Labath 104a7c457d2SPavel Labath /// Emit offsets to lists of entries with identical names. The offsets are 105a7c457d2SPavel Labath /// relative to the Base argument. 106a7c457d2SPavel Labath void emitOffsets(const MCSymbol *Base) const; 107a7c457d2SPavel Labath 108a7c457d2SPavel Labath public: 109e60ca777SJonas Devlieghere AccelTableWriter(AsmPrinter *Asm, const AccelTableBase &Contents, 110a7c457d2SPavel Labath bool SkipIdenticalHashes) 111a7c457d2SPavel Labath : Asm(Asm), Contents(Contents), SkipIdenticalHashes(SkipIdenticalHashes) { 112a7c457d2SPavel Labath } 113a7c457d2SPavel Labath }; 114a7c457d2SPavel Labath 115e60ca777SJonas Devlieghere class AppleAccelTableWriter : public AccelTableWriter { 116a7c457d2SPavel Labath using Atom = AppleAccelTableData::Atom; 117a7c457d2SPavel Labath 118a7c457d2SPavel Labath /// The fixed header of an Apple Accelerator Table. 119a7c457d2SPavel Labath struct Header { 120a7c457d2SPavel Labath uint32_t Magic = MagicHash; 121a7c457d2SPavel Labath uint16_t Version = 1; 122a7c457d2SPavel Labath uint16_t HashFunction = dwarf::DW_hash_function_djb; 123a7c457d2SPavel Labath uint32_t BucketCount; 124a7c457d2SPavel Labath uint32_t HashCount; 125a7c457d2SPavel Labath uint32_t HeaderDataLength; 126a7c457d2SPavel Labath 127a7c457d2SPavel Labath /// 'HASH' magic value to detect endianness. 128a7c457d2SPavel Labath static const uint32_t MagicHash = 0x48415348; 129a7c457d2SPavel Labath 130a7c457d2SPavel Labath Header(uint32_t BucketCount, uint32_t UniqueHashCount, uint32_t DataLength) 131a7c457d2SPavel Labath : BucketCount(BucketCount), HashCount(UniqueHashCount), 132a7c457d2SPavel Labath HeaderDataLength(DataLength) {} 133a7c457d2SPavel Labath 134a7c457d2SPavel Labath void emit(AsmPrinter *Asm) const; 135a7c457d2SPavel Labath #ifndef NDEBUG 136a7c457d2SPavel Labath void print(raw_ostream &OS) const; 137a7c457d2SPavel Labath void dump() const { print(dbgs()); } 138a7c457d2SPavel Labath #endif 139a7c457d2SPavel Labath }; 140a7c457d2SPavel Labath 141a7c457d2SPavel Labath /// The HeaderData describes the structure of an Apple accelerator table 142a7c457d2SPavel Labath /// through a list of Atoms. 143a7c457d2SPavel Labath struct HeaderData { 144a7c457d2SPavel Labath /// In the case of data that is referenced via DW_FORM_ref_* the offset 145a7c457d2SPavel Labath /// base is used to describe the offset for all forms in the list of atoms. 146a7c457d2SPavel Labath uint32_t DieOffsetBase; 147a7c457d2SPavel Labath 148a7c457d2SPavel Labath const SmallVector<Atom, 4> Atoms; 149a7c457d2SPavel Labath 150a7c457d2SPavel Labath HeaderData(ArrayRef<Atom> AtomList, uint32_t Offset = 0) 151a7c457d2SPavel Labath : DieOffsetBase(Offset), Atoms(AtomList.begin(), AtomList.end()) {} 152a7c457d2SPavel Labath 153a7c457d2SPavel Labath void emit(AsmPrinter *Asm) const; 154a7c457d2SPavel Labath #ifndef NDEBUG 155a7c457d2SPavel Labath void print(raw_ostream &OS) const; 156a7c457d2SPavel Labath void dump() const { print(dbgs()); } 157a7c457d2SPavel Labath #endif 158a7c457d2SPavel Labath }; 159a7c457d2SPavel Labath 160a7c457d2SPavel Labath Header Header; 161a7c457d2SPavel Labath HeaderData HeaderData; 162a7c457d2SPavel Labath const MCSymbol *SecBegin; 163a7c457d2SPavel Labath 164a7c457d2SPavel Labath void emitBuckets() const; 165a7c457d2SPavel Labath void emitData() const; 166a7c457d2SPavel Labath 167a7c457d2SPavel Labath public: 168e60ca777SJonas Devlieghere AppleAccelTableWriter(AsmPrinter *Asm, const AccelTableBase &Contents, 169a7c457d2SPavel Labath ArrayRef<Atom> Atoms, const MCSymbol *SecBegin) 170e60ca777SJonas Devlieghere : AccelTableWriter(Asm, Contents, true), 171a7c457d2SPavel Labath Header(Contents.getBucketCount(), Contents.getUniqueHashCount(), 172a7c457d2SPavel Labath 8 + (Atoms.size() * 4)), 173a7c457d2SPavel Labath HeaderData(Atoms), SecBegin(SecBegin) {} 174a7c457d2SPavel Labath 175a7c457d2SPavel Labath void emit() const; 176a7c457d2SPavel Labath 177a7c457d2SPavel Labath #ifndef NDEBUG 178a7c457d2SPavel Labath void print(raw_ostream &OS) const; 179a7c457d2SPavel Labath void dump() const { print(dbgs()); } 180a7c457d2SPavel Labath #endif 181a7c457d2SPavel Labath }; 1826088c234SPavel Labath 18398062cb3SJonas Devlieghere /// Class responsible for emitting a DWARF v5 Accelerator Table. The only 18498062cb3SJonas Devlieghere /// public function is emit(), which performs the actual emission. 18598062cb3SJonas Devlieghere /// 18698062cb3SJonas Devlieghere /// The class is templated in its data type. This allows us to emit both dyamic 18798062cb3SJonas Devlieghere /// and static data entries. A callback abstract the logic to provide a CU 18898062cb3SJonas Devlieghere /// index for a given entry, which is different per data type, but identical 18998062cb3SJonas Devlieghere /// for every entry in the same table. 19098062cb3SJonas Devlieghere template <typename DataT> 191e60ca777SJonas Devlieghere class Dwarf5AccelTableWriter : public AccelTableWriter { 1926088c234SPavel Labath struct Header { 1936088c234SPavel Labath uint32_t UnitLength = 0; 1946088c234SPavel Labath uint16_t Version = 5; 1956088c234SPavel Labath uint16_t Padding = 0; 1966088c234SPavel Labath uint32_t CompUnitCount; 1976088c234SPavel Labath uint32_t LocalTypeUnitCount = 0; 1986088c234SPavel Labath uint32_t ForeignTypeUnitCount = 0; 1996088c234SPavel Labath uint32_t BucketCount; 2006088c234SPavel Labath uint32_t NameCount; 2016088c234SPavel Labath uint32_t AbbrevTableSize = 0; 2026088c234SPavel Labath uint32_t AugmentationStringSize = sizeof(AugmentationString); 2036088c234SPavel Labath char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'}; 2046088c234SPavel Labath 2056088c234SPavel Labath Header(uint32_t CompUnitCount, uint32_t BucketCount, uint32_t NameCount) 2066088c234SPavel Labath : CompUnitCount(CompUnitCount), BucketCount(BucketCount), 2076088c234SPavel Labath NameCount(NameCount) {} 2086088c234SPavel Labath 209e60ca777SJonas Devlieghere void emit(const Dwarf5AccelTableWriter &Ctx) const; 2106088c234SPavel Labath }; 2116088c234SPavel Labath struct AttributeEncoding { 2126088c234SPavel Labath dwarf::Index Index; 2136088c234SPavel Labath dwarf::Form Form; 2146088c234SPavel Labath }; 2156088c234SPavel Labath 2166088c234SPavel Labath Header Header; 2176088c234SPavel Labath DenseMap<uint32_t, SmallVector<AttributeEncoding, 2>> Abbreviations; 21898062cb3SJonas Devlieghere ArrayRef<MCSymbol *> CompUnits; 21998062cb3SJonas Devlieghere llvm::function_ref<unsigned(const DataT &)> getCUIndexForEntry; 2206088c234SPavel Labath MCSymbol *ContributionStart = Asm->createTempSymbol("names_start"); 2216088c234SPavel Labath MCSymbol *ContributionEnd = Asm->createTempSymbol("names_end"); 2226088c234SPavel Labath MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); 2236088c234SPavel Labath MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end"); 2246088c234SPavel Labath MCSymbol *EntryPool = Asm->createTempSymbol("names_entries"); 2256088c234SPavel Labath 2266088c234SPavel Labath DenseSet<uint32_t> getUniqueTags() const; 2276088c234SPavel Labath 2286088c234SPavel Labath // Right now, we emit uniform attributes for all tags. 2296088c234SPavel Labath SmallVector<AttributeEncoding, 2> getUniformAttributes() const; 2306088c234SPavel Labath 2316088c234SPavel Labath void emitCUList() const; 2326088c234SPavel Labath void emitBuckets() const; 2336088c234SPavel Labath void emitStringOffsets() const; 2346088c234SPavel Labath void emitAbbrevs() const; 235cb0bab86SFangrui Song void emitEntry(const DataT &Entry) const; 2366088c234SPavel Labath void emitData() const; 2376088c234SPavel Labath 2386088c234SPavel Labath public: 23998062cb3SJonas Devlieghere Dwarf5AccelTableWriter( 24098062cb3SJonas Devlieghere AsmPrinter *Asm, const AccelTableBase &Contents, 24198062cb3SJonas Devlieghere ArrayRef<MCSymbol *> CompUnits, 24298062cb3SJonas Devlieghere llvm::function_ref<unsigned(const DataT &)> GetCUIndexForEntry); 2436088c234SPavel Labath 2446088c234SPavel Labath void emit() const; 2456088c234SPavel Labath }; 246a7c457d2SPavel Labath } // namespace 247a7c457d2SPavel Labath 248e60ca777SJonas Devlieghere void AccelTableWriter::emitHashes() const { 249a7c457d2SPavel Labath uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); 250a7c457d2SPavel Labath unsigned BucketIdx = 0; 251a7c457d2SPavel Labath for (auto &Bucket : Contents.getBuckets()) { 252a7c457d2SPavel Labath for (auto &Hash : Bucket) { 253a7c457d2SPavel Labath uint32_t HashValue = Hash->HashValue; 254a7c457d2SPavel Labath if (SkipIdenticalHashes && PrevHash == HashValue) 255a7c457d2SPavel Labath continue; 256a7c457d2SPavel Labath Asm->OutStreamer->AddComment("Hash in Bucket " + Twine(BucketIdx)); 2574b4d85fdSRafael Espindola Asm->emitInt32(HashValue); 258a7c457d2SPavel Labath PrevHash = HashValue; 259a7c457d2SPavel Labath } 260a7c457d2SPavel Labath BucketIdx++; 261a7c457d2SPavel Labath } 262a7c457d2SPavel Labath } 263a7c457d2SPavel Labath 264e60ca777SJonas Devlieghere void AccelTableWriter::emitOffsets(const MCSymbol *Base) const { 265a7c457d2SPavel Labath const auto &Buckets = Contents.getBuckets(); 266a7c457d2SPavel Labath uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); 267a7c457d2SPavel Labath for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 268a7c457d2SPavel Labath for (auto *Hash : Buckets[i]) { 269a7c457d2SPavel Labath uint32_t HashValue = Hash->HashValue; 270a7c457d2SPavel Labath if (SkipIdenticalHashes && PrevHash == HashValue) 271a7c457d2SPavel Labath continue; 272a7c457d2SPavel Labath PrevHash = HashValue; 273a7c457d2SPavel Labath Asm->OutStreamer->AddComment("Offset in Bucket " + Twine(i)); 274a7c457d2SPavel Labath Asm->EmitLabelDifference(Hash->Sym, Base, sizeof(uint32_t)); 275a7c457d2SPavel Labath } 276a7c457d2SPavel Labath } 277a7c457d2SPavel Labath } 278a7c457d2SPavel Labath 279e60ca777SJonas Devlieghere void AppleAccelTableWriter::Header::emit(AsmPrinter *Asm) const { 280855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Magic"); 2814b4d85fdSRafael Espindola Asm->emitInt32(Magic); 282855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Version"); 2834b4d85fdSRafael Espindola Asm->emitInt16(Version); 284855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Hash Function"); 2854b4d85fdSRafael Espindola Asm->emitInt16(HashFunction); 286855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Bucket Count"); 2874b4d85fdSRafael Espindola Asm->emitInt32(BucketCount); 288855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Hash Count"); 2894b4d85fdSRafael Espindola Asm->emitInt32(HashCount); 290855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Header Data Length"); 2914b4d85fdSRafael Espindola Asm->emitInt32(HeaderDataLength); 292a7c457d2SPavel Labath } 293855fc3bbSJonas Devlieghere 294e60ca777SJonas Devlieghere void AppleAccelTableWriter::HeaderData::emit(AsmPrinter *Asm) const { 295855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("HeaderData Die Offset Base"); 2964b4d85fdSRafael Espindola Asm->emitInt32(DieOffsetBase); 297855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("HeaderData Atom Count"); 2984b4d85fdSRafael Espindola Asm->emitInt32(Atoms.size()); 299855fc3bbSJonas Devlieghere 300a7c457d2SPavel Labath for (const Atom &A : Atoms) { 301855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment(dwarf::AtomTypeString(A.Type)); 3024b4d85fdSRafael Espindola Asm->emitInt16(A.Type); 303855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment(dwarf::FormEncodingString(A.Form)); 3044b4d85fdSRafael Espindola Asm->emitInt16(A.Form); 305855fc3bbSJonas Devlieghere } 306855fc3bbSJonas Devlieghere } 307855fc3bbSJonas Devlieghere 308e60ca777SJonas Devlieghere void AppleAccelTableWriter::emitBuckets() const { 309a7c457d2SPavel Labath const auto &Buckets = Contents.getBuckets(); 310855fc3bbSJonas Devlieghere unsigned index = 0; 311855fc3bbSJonas Devlieghere for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 312855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Bucket " + Twine(i)); 313855fc3bbSJonas Devlieghere if (!Buckets[i].empty()) 3144b4d85fdSRafael Espindola Asm->emitInt32(index); 315855fc3bbSJonas Devlieghere else 3164b4d85fdSRafael Espindola Asm->emitInt32(std::numeric_limits<uint32_t>::max()); 317855fc3bbSJonas Devlieghere // Buckets point in the list of hashes, not to the data. Do not increment 318855fc3bbSJonas Devlieghere // the index multiple times in case of hash collisions. 319855fc3bbSJonas Devlieghere uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); 320855fc3bbSJonas Devlieghere for (auto *HD : Buckets[i]) { 321855fc3bbSJonas Devlieghere uint32_t HashValue = HD->HashValue; 322855fc3bbSJonas Devlieghere if (PrevHash != HashValue) 323855fc3bbSJonas Devlieghere ++index; 324855fc3bbSJonas Devlieghere PrevHash = HashValue; 325855fc3bbSJonas Devlieghere } 326855fc3bbSJonas Devlieghere } 327855fc3bbSJonas Devlieghere } 328855fc3bbSJonas Devlieghere 329e60ca777SJonas Devlieghere void AppleAccelTableWriter::emitData() const { 330a7c457d2SPavel Labath const auto &Buckets = Contents.getBuckets(); 331855fc3bbSJonas Devlieghere for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 332855fc3bbSJonas Devlieghere uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); 333855fc3bbSJonas Devlieghere for (auto &Hash : Buckets[i]) { 334855fc3bbSJonas Devlieghere // Terminate the previous entry if there is no hash collision with the 335855fc3bbSJonas Devlieghere // current one. 336855fc3bbSJonas Devlieghere if (PrevHash != std::numeric_limits<uint64_t>::max() && 337855fc3bbSJonas Devlieghere PrevHash != Hash->HashValue) 3384b4d85fdSRafael Espindola Asm->emitInt32(0); 339855fc3bbSJonas Devlieghere // Remember to emit the label for our offset. 340855fc3bbSJonas Devlieghere Asm->OutStreamer->EmitLabel(Hash->Sym); 341062eb537SPavel Labath Asm->OutStreamer->AddComment(Hash->Name.getString()); 342062eb537SPavel Labath Asm->emitDwarfStringOffset(Hash->Name); 343855fc3bbSJonas Devlieghere Asm->OutStreamer->AddComment("Num DIEs"); 3444b4d85fdSRafael Espindola Asm->emitInt32(Hash->Values.size()); 345a7c457d2SPavel Labath for (const auto *V : Hash->Values) 346a7c457d2SPavel Labath static_cast<const AppleAccelTableData *>(V)->emit(Asm); 347855fc3bbSJonas Devlieghere PrevHash = Hash->HashValue; 348855fc3bbSJonas Devlieghere } 349855fc3bbSJonas Devlieghere // Emit the final end marker for the bucket. 350855fc3bbSJonas Devlieghere if (!Buckets[i].empty()) 3514b4d85fdSRafael Espindola Asm->emitInt32(0); 352855fc3bbSJonas Devlieghere } 353855fc3bbSJonas Devlieghere } 354855fc3bbSJonas Devlieghere 355e60ca777SJonas Devlieghere void AppleAccelTableWriter::emit() const { 356a7c457d2SPavel Labath Header.emit(Asm); 357a7c457d2SPavel Labath HeaderData.emit(Asm); 358a7c457d2SPavel Labath emitBuckets(); 359a7c457d2SPavel Labath emitHashes(); 360a7c457d2SPavel Labath emitOffsets(SecBegin); 361a7c457d2SPavel Labath emitData(); 362855fc3bbSJonas Devlieghere } 363855fc3bbSJonas Devlieghere 36498062cb3SJonas Devlieghere template <typename DataT> 36598062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::Header::emit( 366e60ca777SJonas Devlieghere const Dwarf5AccelTableWriter &Ctx) const { 367eadfac87SPavel Labath assert(CompUnitCount > 0 && "Index must have at least one CU."); 368eadfac87SPavel Labath 3696088c234SPavel Labath AsmPrinter *Asm = Ctx.Asm; 3706088c234SPavel Labath Asm->OutStreamer->AddComment("Header: unit length"); 3716088c234SPavel Labath Asm->EmitLabelDifference(Ctx.ContributionEnd, Ctx.ContributionStart, 3726088c234SPavel Labath sizeof(uint32_t)); 3736088c234SPavel Labath Asm->OutStreamer->EmitLabel(Ctx.ContributionStart); 3746088c234SPavel Labath Asm->OutStreamer->AddComment("Header: version"); 3756088c234SPavel Labath Asm->emitInt16(Version); 3766088c234SPavel Labath Asm->OutStreamer->AddComment("Header: padding"); 3776088c234SPavel Labath Asm->emitInt16(Padding); 3786088c234SPavel Labath Asm->OutStreamer->AddComment("Header: compilation unit count"); 3796088c234SPavel Labath Asm->emitInt32(CompUnitCount); 3806088c234SPavel Labath Asm->OutStreamer->AddComment("Header: local type unit count"); 3816088c234SPavel Labath Asm->emitInt32(LocalTypeUnitCount); 3826088c234SPavel Labath Asm->OutStreamer->AddComment("Header: foreign type unit count"); 3836088c234SPavel Labath Asm->emitInt32(ForeignTypeUnitCount); 3846088c234SPavel Labath Asm->OutStreamer->AddComment("Header: bucket count"); 3856088c234SPavel Labath Asm->emitInt32(BucketCount); 3866088c234SPavel Labath Asm->OutStreamer->AddComment("Header: name count"); 3876088c234SPavel Labath Asm->emitInt32(NameCount); 3886088c234SPavel Labath Asm->OutStreamer->AddComment("Header: abbreviation table size"); 3896088c234SPavel Labath Asm->EmitLabelDifference(Ctx.AbbrevEnd, Ctx.AbbrevStart, sizeof(uint32_t)); 3906088c234SPavel Labath Asm->OutStreamer->AddComment("Header: augmentation string size"); 3916088c234SPavel Labath assert(AugmentationStringSize % 4 == 0); 3926088c234SPavel Labath Asm->emitInt32(AugmentationStringSize); 3936088c234SPavel Labath Asm->OutStreamer->AddComment("Header: augmentation string"); 3946088c234SPavel Labath Asm->OutStreamer->EmitBytes({AugmentationString, AugmentationStringSize}); 3956088c234SPavel Labath } 3966088c234SPavel Labath 39798062cb3SJonas Devlieghere template <typename DataT> 39898062cb3SJonas Devlieghere DenseSet<uint32_t> Dwarf5AccelTableWriter<DataT>::getUniqueTags() const { 3996088c234SPavel Labath DenseSet<uint32_t> UniqueTags; 4006088c234SPavel Labath for (auto &Bucket : Contents.getBuckets()) { 4016088c234SPavel Labath for (auto *Hash : Bucket) { 4026088c234SPavel Labath for (auto *Value : Hash->Values) { 40398062cb3SJonas Devlieghere unsigned Tag = static_cast<const DataT *>(Value)->getDieTag(); 40498062cb3SJonas Devlieghere UniqueTags.insert(Tag); 4056088c234SPavel Labath } 4066088c234SPavel Labath } 4076088c234SPavel Labath } 4086088c234SPavel Labath return UniqueTags; 4096088c234SPavel Labath } 4106088c234SPavel Labath 41198062cb3SJonas Devlieghere template <typename DataT> 41298062cb3SJonas Devlieghere SmallVector<typename Dwarf5AccelTableWriter<DataT>::AttributeEncoding, 2> 41398062cb3SJonas Devlieghere Dwarf5AccelTableWriter<DataT>::getUniformAttributes() const { 4146088c234SPavel Labath SmallVector<AttributeEncoding, 2> UA; 4153192e35bSJonas Devlieghere if (CompUnits.size() > 1) { 4163192e35bSJonas Devlieghere size_t LargestCUIndex = CompUnits.size() - 1; 4176088c234SPavel Labath dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false, LargestCUIndex); 4186088c234SPavel Labath UA.push_back({dwarf::DW_IDX_compile_unit, Form}); 4196088c234SPavel Labath } 4206088c234SPavel Labath UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); 4216088c234SPavel Labath return UA; 4226088c234SPavel Labath } 4236088c234SPavel Labath 42498062cb3SJonas Devlieghere template <typename DataT> 42598062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::emitCUList() const { 4263192e35bSJonas Devlieghere for (const auto &CU : enumerate(CompUnits)) { 4273192e35bSJonas Devlieghere Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); 42898062cb3SJonas Devlieghere Asm->emitDwarfSymbolReference(CU.value()); 4296088c234SPavel Labath } 4306088c234SPavel Labath } 4316088c234SPavel Labath 43298062cb3SJonas Devlieghere template <typename DataT> 43398062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::emitBuckets() const { 4346088c234SPavel Labath uint32_t Index = 1; 4356088c234SPavel Labath for (const auto &Bucket : enumerate(Contents.getBuckets())) { 4366088c234SPavel Labath Asm->OutStreamer->AddComment("Bucket " + Twine(Bucket.index())); 4376088c234SPavel Labath Asm->emitInt32(Bucket.value().empty() ? 0 : Index); 4386088c234SPavel Labath Index += Bucket.value().size(); 4396088c234SPavel Labath } 4406088c234SPavel Labath } 4416088c234SPavel Labath 44298062cb3SJonas Devlieghere template <typename DataT> 44398062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::emitStringOffsets() const { 4446088c234SPavel Labath for (const auto &Bucket : enumerate(Contents.getBuckets())) { 4456088c234SPavel Labath for (auto *Hash : Bucket.value()) { 4466088c234SPavel Labath DwarfStringPoolEntryRef String = Hash->Name; 4476088c234SPavel Labath Asm->OutStreamer->AddComment("String in Bucket " + Twine(Bucket.index()) + 4486088c234SPavel Labath ": " + String.getString()); 4496088c234SPavel Labath Asm->emitDwarfStringOffset(String); 4506088c234SPavel Labath } 4516088c234SPavel Labath } 4526088c234SPavel Labath } 4536088c234SPavel Labath 45498062cb3SJonas Devlieghere template <typename DataT> 45598062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const { 4566088c234SPavel Labath Asm->OutStreamer->EmitLabel(AbbrevStart); 4576088c234SPavel Labath for (const auto &Abbrev : Abbreviations) { 4586088c234SPavel Labath Asm->OutStreamer->AddComment("Abbrev code"); 4596088c234SPavel Labath assert(Abbrev.first != 0); 4606088c234SPavel Labath Asm->EmitULEB128(Abbrev.first); 4616088c234SPavel Labath Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev.first)); 4626088c234SPavel Labath Asm->EmitULEB128(Abbrev.first); 4636088c234SPavel Labath for (const auto &AttrEnc : Abbrev.second) { 4646088c234SPavel Labath Asm->EmitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data()); 4656088c234SPavel Labath Asm->EmitULEB128(AttrEnc.Form, 4666088c234SPavel Labath dwarf::FormEncodingString(AttrEnc.Form).data()); 4676088c234SPavel Labath } 4686088c234SPavel Labath Asm->EmitULEB128(0, "End of abbrev"); 4696088c234SPavel Labath Asm->EmitULEB128(0, "End of abbrev"); 4706088c234SPavel Labath } 4716088c234SPavel Labath Asm->EmitULEB128(0, "End of abbrev list"); 4726088c234SPavel Labath Asm->OutStreamer->EmitLabel(AbbrevEnd); 4736088c234SPavel Labath } 4746088c234SPavel Labath 47598062cb3SJonas Devlieghere template <typename DataT> 47698062cb3SJonas Devlieghere void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const { 47798062cb3SJonas Devlieghere auto AbbrevIt = Abbreviations.find(Entry.getDieTag()); 4786088c234SPavel Labath assert(AbbrevIt != Abbreviations.end() && 4796088c234SPavel Labath "Why wasn't this abbrev generated?"); 4806088c234SPavel Labath 4816088c234SPavel Labath Asm->EmitULEB128(AbbrevIt->first, "Abbreviation code"); 4826088c234SPavel Labath for (const auto &AttrEnc : AbbrevIt->second) { 4836088c234SPavel Labath Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index)); 4846088c234SPavel Labath switch (AttrEnc.Index) { 4856088c234SPavel Labath case dwarf::DW_IDX_compile_unit: { 48698062cb3SJonas Devlieghere DIEInteger ID(getCUIndexForEntry(Entry)); 4876088c234SPavel Labath ID.EmitValue(Asm, AttrEnc.Form); 4886088c234SPavel Labath break; 4896088c234SPavel Labath } 4906088c234SPavel Labath case dwarf::DW_IDX_die_offset: 4916088c234SPavel Labath assert(AttrEnc.Form == dwarf::DW_FORM_ref4); 49298062cb3SJonas Devlieghere Asm->emitInt32(Entry.getDieOffset()); 4936088c234SPavel Labath break; 4946088c234SPavel Labath default: 4956088c234SPavel Labath llvm_unreachable("Unexpected index attribute!"); 4966088c234SPavel Labath } 4976088c234SPavel Labath } 4986088c234SPavel Labath } 4996088c234SPavel Labath 50098062cb3SJonas Devlieghere template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const { 5016088c234SPavel Labath Asm->OutStreamer->EmitLabel(EntryPool); 5026088c234SPavel Labath for (auto &Bucket : Contents.getBuckets()) { 5036088c234SPavel Labath for (auto *Hash : Bucket) { 5046088c234SPavel Labath // Remember to emit the label for our offset. 5056088c234SPavel Labath Asm->OutStreamer->EmitLabel(Hash->Sym); 5066088c234SPavel Labath for (const auto *Value : Hash->Values) 50798062cb3SJonas Devlieghere emitEntry(*static_cast<const DataT *>(Value)); 5086088c234SPavel Labath Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString()); 5096088c234SPavel Labath Asm->emitInt32(0); 5106088c234SPavel Labath } 5116088c234SPavel Labath } 5126088c234SPavel Labath } 5136088c234SPavel Labath 51498062cb3SJonas Devlieghere template <typename DataT> 51598062cb3SJonas Devlieghere Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter( 51698062cb3SJonas Devlieghere AsmPrinter *Asm, const AccelTableBase &Contents, 51798062cb3SJonas Devlieghere ArrayRef<MCSymbol *> CompUnits, 51898062cb3SJonas Devlieghere llvm::function_ref<unsigned(const DataT &)> getCUIndexForEntry) 519e60ca777SJonas Devlieghere : AccelTableWriter(Asm, Contents, false), 5203192e35bSJonas Devlieghere Header(CompUnits.size(), Contents.getBucketCount(), 5216088c234SPavel Labath Contents.getUniqueNameCount()), 52298062cb3SJonas Devlieghere CompUnits(CompUnits), getCUIndexForEntry(std::move(getCUIndexForEntry)) { 5236088c234SPavel Labath DenseSet<uint32_t> UniqueTags = getUniqueTags(); 5246088c234SPavel Labath SmallVector<AttributeEncoding, 2> UniformAttributes = getUniformAttributes(); 5256088c234SPavel Labath 5266088c234SPavel Labath Abbreviations.reserve(UniqueTags.size()); 5276088c234SPavel Labath for (uint32_t Tag : UniqueTags) 5286088c234SPavel Labath Abbreviations.try_emplace(Tag, UniformAttributes); 5296088c234SPavel Labath } 5306088c234SPavel Labath 53198062cb3SJonas Devlieghere template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() const { 5326088c234SPavel Labath Header.emit(*this); 5336088c234SPavel Labath emitCUList(); 5346088c234SPavel Labath emitBuckets(); 5356088c234SPavel Labath emitHashes(); 5366088c234SPavel Labath emitStringOffsets(); 5376088c234SPavel Labath emitOffsets(EntryPool); 5386088c234SPavel Labath emitAbbrevs(); 5396088c234SPavel Labath emitData(); 5406088c234SPavel Labath Asm->OutStreamer->EmitValueToAlignment(4, 0); 5416088c234SPavel Labath Asm->OutStreamer->EmitLabel(ContributionEnd); 5426088c234SPavel Labath } 5436088c234SPavel Labath 544a7c457d2SPavel Labath void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, 545a7c457d2SPavel Labath StringRef Prefix, const MCSymbol *SecBegin, 546a7c457d2SPavel Labath ArrayRef<AppleAccelTableData::Atom> Atoms) { 547a7c457d2SPavel Labath Contents.finalize(Asm, Prefix); 548e60ca777SJonas Devlieghere AppleAccelTableWriter(Asm, Contents, Atoms, SecBegin).emit(); 549855fc3bbSJonas Devlieghere } 550855fc3bbSJonas Devlieghere 5516088c234SPavel Labath void llvm::emitDWARF5AccelTable( 5526088c234SPavel Labath AsmPrinter *Asm, AccelTable<DWARF5AccelTableData> &Contents, 5536088c234SPavel Labath const DwarfDebug &DD, ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs) { 55498062cb3SJonas Devlieghere std::vector<MCSymbol *> CompUnits; 5556dd452b5SDavid Blaikie SmallVector<unsigned, 1> CUIndex(CUs.size()); 5566dd452b5SDavid Blaikie int Count = 0; 55798062cb3SJonas Devlieghere for (const auto &CU : enumerate(CUs)) { 558*2f511762SDavid Blaikie if (CU.value()->getCUNode()->getNameTableKind() != 559*2f511762SDavid Blaikie DICompileUnit::DebugNameTableKind::Default) 56066cf14d0SDavid Blaikie continue; 5616dd452b5SDavid Blaikie CUIndex[CU.index()] = Count++; 56298062cb3SJonas Devlieghere assert(CU.index() == CU.value()->getUniqueID()); 56398062cb3SJonas Devlieghere const DwarfCompileUnit *MainCU = 56498062cb3SJonas Devlieghere DD.useSplitDwarf() ? CU.value()->getSkeleton() : CU.value().get(); 56598062cb3SJonas Devlieghere CompUnits.push_back(MainCU->getLabelBegin()); 56698062cb3SJonas Devlieghere } 56798062cb3SJonas Devlieghere 56866cf14d0SDavid Blaikie if (CompUnits.empty()) 56966cf14d0SDavid Blaikie return; 57066cf14d0SDavid Blaikie 57166cf14d0SDavid Blaikie Asm->OutStreamer->SwitchSection( 57266cf14d0SDavid Blaikie Asm->getObjFileLowering().getDwarfDebugNamesSection()); 57366cf14d0SDavid Blaikie 5746088c234SPavel Labath Contents.finalize(Asm, "names"); 57598062cb3SJonas Devlieghere Dwarf5AccelTableWriter<DWARF5AccelTableData>( 57698062cb3SJonas Devlieghere Asm, Contents, CompUnits, 5776dd452b5SDavid Blaikie [&](const DWARF5AccelTableData &Entry) { 57898062cb3SJonas Devlieghere const DIE *CUDie = Entry.getDie().getUnitDie(); 5796dd452b5SDavid Blaikie return CUIndex[DD.lookupCU(CUDie)->getUniqueID()]; 58098062cb3SJonas Devlieghere }) 58198062cb3SJonas Devlieghere .emit(); 58298062cb3SJonas Devlieghere } 58398062cb3SJonas Devlieghere 58498062cb3SJonas Devlieghere void llvm::emitDWARF5AccelTable( 58598062cb3SJonas Devlieghere AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents, 58698062cb3SJonas Devlieghere ArrayRef<MCSymbol *> CUs, 58798062cb3SJonas Devlieghere llvm::function_ref<unsigned(const DWARF5AccelTableStaticData &)> 58898062cb3SJonas Devlieghere getCUIndexForEntry) { 58998062cb3SJonas Devlieghere Contents.finalize(Asm, "names"); 59098062cb3SJonas Devlieghere Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(Asm, Contents, CUs, 59198062cb3SJonas Devlieghere getCUIndexForEntry) 59298062cb3SJonas Devlieghere .emit(); 5936088c234SPavel Labath } 5946088c234SPavel Labath 595855fc3bbSJonas Devlieghere void AppleAccelTableOffsetData::emit(AsmPrinter *Asm) const { 5967f7e6069SPavel Labath Asm->emitInt32(Die.getDebugSectionOffset()); 597855fc3bbSJonas Devlieghere } 598855fc3bbSJonas Devlieghere 599855fc3bbSJonas Devlieghere void AppleAccelTableTypeData::emit(AsmPrinter *Asm) const { 6007f7e6069SPavel Labath Asm->emitInt32(Die.getDebugSectionOffset()); 6017f7e6069SPavel Labath Asm->emitInt16(Die.getTag()); 6024b4d85fdSRafael Espindola Asm->emitInt8(0); 603855fc3bbSJonas Devlieghere } 6045ead3a2bSJonas Devlieghere 6055ead3a2bSJonas Devlieghere void AppleAccelTableStaticOffsetData::emit(AsmPrinter *Asm) const { 6064b4d85fdSRafael Espindola Asm->emitInt32(Offset); 6075ead3a2bSJonas Devlieghere } 6085ead3a2bSJonas Devlieghere 6095ead3a2bSJonas Devlieghere void AppleAccelTableStaticTypeData::emit(AsmPrinter *Asm) const { 6104b4d85fdSRafael Espindola Asm->emitInt32(Offset); 6114b4d85fdSRafael Espindola Asm->emitInt16(Tag); 6124b4d85fdSRafael Espindola Asm->emitInt8(ObjCClassIsImplementation ? dwarf::DW_FLAG_type_implementation 6135ead3a2bSJonas Devlieghere : 0); 6144b4d85fdSRafael Espindola Asm->emitInt32(QualifiedNameHash); 6155ead3a2bSJonas Devlieghere } 616073971b2SJonas Devlieghere 617073971b2SJonas Devlieghere #ifndef _MSC_VER 618073971b2SJonas Devlieghere // The lines below are rejected by older versions (TBD) of MSVC. 619a7c457d2SPavel Labath constexpr AppleAccelTableData::Atom AppleAccelTableTypeData::Atoms[]; 620a7c457d2SPavel Labath constexpr AppleAccelTableData::Atom AppleAccelTableOffsetData::Atoms[]; 621a7c457d2SPavel Labath constexpr AppleAccelTableData::Atom AppleAccelTableStaticOffsetData::Atoms[]; 622a7c457d2SPavel Labath constexpr AppleAccelTableData::Atom AppleAccelTableStaticTypeData::Atoms[]; 623073971b2SJonas Devlieghere #else 624073971b2SJonas Devlieghere // FIXME: Erase this path once the minimum MSCV version has been bumped. 625a7c457d2SPavel Labath const SmallVector<AppleAccelTableData::Atom, 4> 626a7c457d2SPavel Labath AppleAccelTableOffsetData::Atoms = { 627a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)}; 628a7c457d2SPavel Labath const SmallVector<AppleAccelTableData::Atom, 4> AppleAccelTableTypeData::Atoms = 629a7c457d2SPavel Labath {Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4), 630a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2), 631a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)}; 632a7c457d2SPavel Labath const SmallVector<AppleAccelTableData::Atom, 4> 633a7c457d2SPavel Labath AppleAccelTableStaticOffsetData::Atoms = { 634a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)}; 635a7c457d2SPavel Labath const SmallVector<AppleAccelTableData::Atom, 4> 636073971b2SJonas Devlieghere AppleAccelTableStaticTypeData::Atoms = { 637a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4), 638a7c457d2SPavel Labath Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2), 639a7c457d2SPavel Labath Atom(5, dwarf::DW_FORM_data1), Atom(6, dwarf::DW_FORM_data4)}; 640073971b2SJonas Devlieghere #endif 6411ce64dccSJonas Devlieghere 6421ce64dccSJonas Devlieghere #ifndef NDEBUG 643e60ca777SJonas Devlieghere void AppleAccelTableWriter::Header::print(raw_ostream &OS) const { 6441ce64dccSJonas Devlieghere OS << "Magic: " << format("0x%x", Magic) << "\n" 6451ce64dccSJonas Devlieghere << "Version: " << Version << "\n" 6461ce64dccSJonas Devlieghere << "Hash Function: " << HashFunction << "\n" 6471ce64dccSJonas Devlieghere << "Bucket Count: " << BucketCount << "\n" 6481ce64dccSJonas Devlieghere << "Header Data Length: " << HeaderDataLength << "\n"; 6491ce64dccSJonas Devlieghere } 6501ce64dccSJonas Devlieghere 651a7c457d2SPavel Labath void AppleAccelTableData::Atom::print(raw_ostream &OS) const { 6521ce64dccSJonas Devlieghere OS << "Type: " << dwarf::AtomTypeString(Type) << "\n" 6531ce64dccSJonas Devlieghere << "Form: " << dwarf::FormEncodingString(Form) << "\n"; 6541ce64dccSJonas Devlieghere } 6551ce64dccSJonas Devlieghere 656e60ca777SJonas Devlieghere void AppleAccelTableWriter::HeaderData::print(raw_ostream &OS) const { 6571ce64dccSJonas Devlieghere OS << "DIE Offset Base: " << DieOffsetBase << "\n"; 6581ce64dccSJonas Devlieghere for (auto Atom : Atoms) 6591ce64dccSJonas Devlieghere Atom.print(OS); 6601ce64dccSJonas Devlieghere } 6611ce64dccSJonas Devlieghere 662e60ca777SJonas Devlieghere void AppleAccelTableWriter::print(raw_ostream &OS) const { 6631ce64dccSJonas Devlieghere Header.print(OS); 6641ce64dccSJonas Devlieghere HeaderData.print(OS); 665a7c457d2SPavel Labath Contents.print(OS); 666a7c457d2SPavel Labath SecBegin->print(OS, nullptr); 6671ce64dccSJonas Devlieghere } 6681ce64dccSJonas Devlieghere 669a7c457d2SPavel Labath void AccelTableBase::HashData::print(raw_ostream &OS) const { 670062eb537SPavel Labath OS << "Name: " << Name.getString() << "\n"; 6711ce64dccSJonas Devlieghere OS << " Hash Value: " << format("0x%x", HashValue) << "\n"; 6721ce64dccSJonas Devlieghere OS << " Symbol: "; 6731ce64dccSJonas Devlieghere if (Sym) 6741ce64dccSJonas Devlieghere OS << *Sym; 6751ce64dccSJonas Devlieghere else 6761ce64dccSJonas Devlieghere OS << "<none>"; 6771ce64dccSJonas Devlieghere OS << "\n"; 678062eb537SPavel Labath for (auto *Value : Values) 6791ce64dccSJonas Devlieghere Value->print(OS); 6801ce64dccSJonas Devlieghere } 6811ce64dccSJonas Devlieghere 682a7c457d2SPavel Labath void AccelTableBase::print(raw_ostream &OS) const { 6831ce64dccSJonas Devlieghere // Print Content. 6841ce64dccSJonas Devlieghere OS << "Entries: \n"; 6851ce64dccSJonas Devlieghere for (const auto &Entry : Entries) { 6861ce64dccSJonas Devlieghere OS << "Name: " << Entry.first() << "\n"; 6871ce64dccSJonas Devlieghere for (auto *V : Entry.second.Values) 6881ce64dccSJonas Devlieghere V->print(OS); 6891ce64dccSJonas Devlieghere } 6901ce64dccSJonas Devlieghere 6911ce64dccSJonas Devlieghere OS << "Buckets and Hashes: \n"; 6921ce64dccSJonas Devlieghere for (auto &Bucket : Buckets) 6931ce64dccSJonas Devlieghere for (auto &Hash : Bucket) 6941ce64dccSJonas Devlieghere Hash->print(OS); 6951ce64dccSJonas Devlieghere 6961ce64dccSJonas Devlieghere OS << "Data: \n"; 697062eb537SPavel Labath for (auto &E : Entries) 698062eb537SPavel Labath E.second.print(OS); 6991ce64dccSJonas Devlieghere } 7001ce64dccSJonas Devlieghere 7016088c234SPavel Labath void DWARF5AccelTableData::print(raw_ostream &OS) const { 70298062cb3SJonas Devlieghere OS << " Offset: " << getDieOffset() << "\n"; 70398062cb3SJonas Devlieghere OS << " Tag: " << dwarf::TagString(getDieTag()) << "\n"; 70498062cb3SJonas Devlieghere } 70598062cb3SJonas Devlieghere 70698062cb3SJonas Devlieghere void DWARF5AccelTableStaticData::print(raw_ostream &OS) const { 70798062cb3SJonas Devlieghere OS << " Offset: " << getDieOffset() << "\n"; 70898062cb3SJonas Devlieghere OS << " Tag: " << dwarf::TagString(getDieTag()) << "\n"; 7096088c234SPavel Labath } 7106088c234SPavel Labath 7111ce64dccSJonas Devlieghere void AppleAccelTableOffsetData::print(raw_ostream &OS) const { 7120120691fSPavel Labath OS << " Offset: " << Die.getOffset() << "\n"; 7131ce64dccSJonas Devlieghere } 7141ce64dccSJonas Devlieghere 7151ce64dccSJonas Devlieghere void AppleAccelTableTypeData::print(raw_ostream &OS) const { 7160120691fSPavel Labath OS << " Offset: " << Die.getOffset() << "\n"; 7170120691fSPavel Labath OS << " Tag: " << dwarf::TagString(Die.getTag()) << "\n"; 7181ce64dccSJonas Devlieghere } 7191ce64dccSJonas Devlieghere 7201ce64dccSJonas Devlieghere void AppleAccelTableStaticOffsetData::print(raw_ostream &OS) const { 7211ce64dccSJonas Devlieghere OS << " Static Offset: " << Offset << "\n"; 7221ce64dccSJonas Devlieghere } 7231ce64dccSJonas Devlieghere 7241ce64dccSJonas Devlieghere void AppleAccelTableStaticTypeData::print(raw_ostream &OS) const { 7251ce64dccSJonas Devlieghere OS << " Static Offset: " << Offset << "\n"; 7261ce64dccSJonas Devlieghere OS << " QualifiedNameHash: " << format("%x\n", QualifiedNameHash) << "\n"; 7271ce64dccSJonas Devlieghere OS << " Tag: " << dwarf::TagString(Tag) << "\n"; 7281ce64dccSJonas Devlieghere OS << " ObjCClassIsImplementation: " 7291ce64dccSJonas Devlieghere << (ObjCClassIsImplementation ? "true" : "false"); 7301ce64dccSJonas Devlieghere OS << "\n"; 7311ce64dccSJonas Devlieghere } 7321ce64dccSJonas Devlieghere #endif 733