Index: lib/CodeGen/AsmPrinter/DwarfAccelTable.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -15,6 +15,7 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFACCELTABLE_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -65,13 +66,128 @@ namespace llvm { class AsmPrinter; -class DwarfDebug; +class DwarfFile; +class DwarfCompileUnit; -class DwarfAccelTable { +class AccelTable { // Helper function to compute the number of buckets needed based on // the number of unique hashes. - void ComputeBucketCount(); + std::pair ComputeBucketCount(); +private: + // The data itself consists of a str_offset, a count of the DIEs in the + // hash and the offsets to the DIEs themselves. + // On disk each data section is ended with a 0 KeyType as the end of the + // hash chain. + // On output this looks like: + // uint32_t str_offset + // uint32_t hash_data_count + // HashData[hash_data_count] +public: + struct HashDataContents { + const DIE *Die; // Offsets + char Flags; // Specific flags to output + + HashDataContents(const DIE *D, char Flags) : Die(D), Flags(Flags) {} + +#ifndef NDEBUG + void print(raw_ostream &OS) const { + OS << " Offset: " << Die->getOffset() << "\n" + << " Tag: " << dwarf::TagString(Die->getTag()) << "\n" + << " Flags: " << Flags << "\n"; + } +#endif + }; + +private: + // String Data + struct DataArray { + DwarfStringPoolEntryRef Name; + std::vector Values; + }; + +protected: + struct HashData { + StringRef Str; + uint32_t HashValue; + MCSymbol *Sym; + DataArray &Data; // offsets + + HashData(StringRef S, DataArray &Data) + : Str(S), Data(Data) { + HashValue = dwarf::djbHash(S); + } + +#ifndef NDEBUG + void print(raw_ostream &OS) { + OS << "Name: " << Str << "\n"; + OS << " Hash Value: " << format("0x%x", HashValue) << "\n"; + OS << " Symbol: "; + if (Sym) + OS << *Sym; + else + OS << ""; + OS << "\n"; + for (HashDataContents *C : Data.Values) { + OS << " Offset: " << C->Die->getOffset() << "\n"; + OS << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n"; + OS << " Flags: " << C->Flags << "\n"; + } + } + + void dump() { print(dbgs()); } +#endif + }; + +protected: + + // Internal Functions + virtual void finalizeHeader(AsmPrinter *Asm, DwarfFile &DF, + uint32_t bucket_count, uint32_t name_count) = 0; + void finalizeData(); + virtual void EmitHeader(AsmPrinter *Asm) = 0; + void EmitBuckets(AsmPrinter *); + void EmitHashes(AsmPrinter *); + void emitOffsets(AsmPrinter *, const MCSymbol *); + +private: + + // Allocator for HashData and HashDataContents. + BumpPtrAllocator Allocator; + +protected: + // Output Variables + std::vector Data; + + using StringEntries = StringMap; + + StringEntries Entries; + + // Buckets/Hashes/Offsets + using HashList = std::vector; + using BucketList = std::vector; + BucketList Buckets; + HashList Hashes; + const uint32_t EmptyBucket; + + AccelTable(uint32_t EmptyBucket); + + // Public Implementation +public: + virtual ~AccelTable() = default; + AccelTable(const AccelTable &) = delete; + AccelTable &operator=(const AccelTable &) = delete; + + void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags = 0); + virtual void finalizeTable(AsmPrinter *, StringRef, DwarfFile &DF); + virtual void emit(AsmPrinter *, const MCSymbol *, DwarfFile &DF) = 0; +#ifndef NDEBUG + void print(raw_ostream &OS); + void dump() { print(dbgs()); } +#endif +}; + +class AppleAccelTable: public AccelTable { struct TableHeader { uint32_t magic = MagicHash; // 'HASH' magic value to allow endian detection uint16_t version = 1; // Version number. @@ -151,109 +267,75 @@ #endif }; - // The data itself consists of a str_offset, a count of the DIEs in the - // hash and the offsets to the DIEs themselves. - // On disk each data section is ended with a 0 KeyType as the end of the - // hash chain. - // On output this looks like: - // uint32_t str_offset - // uint32_t hash_data_count - // HashData[hash_data_count] -public: - struct HashDataContents { - const DIE *Die; // Offsets - char Flags; // Specific flags to output - - HashDataContents(const DIE *D, char Flags) : Die(D), Flags(Flags) {} - -#ifndef NDEBUG - void print(raw_ostream &OS) const { - OS << " Offset: " << Die->getOffset() << "\n" - << " Tag: " << dwarf::TagString(Die->getTag()) << "\n" - << " Flags: " << Flags << "\n"; - } -#endif - }; + TableHeader Header; + TableHeaderData HeaderData; -private: - // String Data - struct DataArray { - DwarfStringPoolEntryRef Name; - std::vector Values; - }; + void finalizeHeader(AsmPrinter *Asm, DwarfFile &DF, uint32_t bucket_count, + uint32_t name_count) override; + void EmitHeader(AsmPrinter *) override; + void emitData(AsmPrinter *Asm); + void emit(AsmPrinter *, const MCSymbol *, DwarfFile &DF) override; - friend struct HashData; +public: + AppleAccelTable(ArrayRef atomList); - struct HashData { - StringRef Str; - uint32_t HashValue; - MCSymbol *Sym; - DwarfAccelTable::DataArray &Data; // offsets +}; - HashData(StringRef S, DwarfAccelTable::DataArray &Data) - : Str(S), Data(Data) { - HashValue = dwarf::djbHash(S); - } +class Dwarf5AccelTable: public AccelTable { + struct TableHeader { + const uint32_t unit_length = 0; + uint16_t version = 5; + const uint16_t padding = 0; + uint32_t comp_unit_count = 0; + const uint32_t local_type_unit_count = 0; + const uint32_t foreign_type_unit_count = 0; + uint32_t bucket_count = 0; + uint32_t name_count = 0; + const uint32_t abbrev_table_size = 0; + const std::string augmentation_string; // encoded as length+bytes + + TableHeader() = default; #ifndef NDEBUG void print(raw_ostream &OS) { - OS << "Name: " << Str << "\n"; - OS << " Hash Value: " << format("0x%x", HashValue) << "\n"; - OS << " Symbol: "; - if (Sym) - OS << *Sym; - else - OS << ""; - OS << "\n"; - for (HashDataContents *C : Data.Values) { - OS << " Offset: " << C->Die->getOffset() << "\n"; - OS << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n"; - OS << " Flags: " << C->Flags << "\n"; - } + OS << "unit_length: " << unit_length << "\n" + << "version: " << version << "\n" + << "padding: " << padding << "\n" + << "comp_unit_count: " << comp_unit_count << "\n" + << "local_type_unit_count: " << local_type_unit_count << "\n" + << "foreign_type_unit_count: " << foreign_type_unit_count << "\n" + << "bucket_count: " << bucket_count << "\n" + << "name_count: " << name_count << "\n" + << "abbrev_table_size: " << abbrev_table_size << "\n" + << "augmentation_string: " << augmentation_string << "\n"; } - void dump() { print(dbgs()); } + LLVM_DUMP_METHOD void dump() { print(dbgs()); } #endif }; - // Internal Functions - void EmitHeader(AsmPrinter *); - void EmitBuckets(AsmPrinter *); - void EmitHashes(AsmPrinter *); - void emitOffsets(AsmPrinter *, const MCSymbol *); - void EmitData(AsmPrinter *, DwarfDebug *D); - - // Allocator for HashData and HashDataContents. - BumpPtrAllocator Allocator; - - // Output Variables TableHeader Header; - TableHeaderData HeaderData; - std::vector Data; - - using StringEntries = StringMap; - - StringEntries Entries; - - // Buckets/Hashes/Offsets - using HashList = std::vector; - using BucketList = std::vector; - BucketList Buckets; - HashList Hashes; + DenseSet Tags; + MCSymbol *Start = nullptr; + MCSymbol *End = nullptr; + MCSymbol *AbbrevStart = nullptr; + MCSymbol *AbbrevEnd = nullptr; + MCSymbol *EntryPool = nullptr; + + void finalizeHeader(AsmPrinter *Asm, DwarfFile &DF, uint32_t bucket_count, + uint32_t name_count) override; + void finalizeTable(AsmPrinter *, StringRef, DwarfFile &DF) override; + void EmitHeader(AsmPrinter *) override; + void + emitCUList(AsmPrinter *Asm, + const SmallVectorImpl> &CUs); + void emitStringOffsets(AsmPrinter *Asm); + void emitAbbrev(AsmPrinter *Asm, DwarfFile &DF); + void emitData(AsmPrinter *Asm, DwarfFile &DF); + void emit(AsmPrinter *Asm, const MCSymbol *SecBegin, DwarfFile &DF) override; - // Public Implementation public: - DwarfAccelTable(ArrayRef); - DwarfAccelTable(const DwarfAccelTable &) = delete; - DwarfAccelTable &operator=(const DwarfAccelTable &) = delete; - - void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags = 0); - void FinalizeTable(AsmPrinter *, StringRef); - void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *); -#ifndef NDEBUG - void print(raw_ostream &OS); - void dump() { print(dbgs()); } -#endif + Dwarf5AccelTable() : AccelTable(0) {} }; } // end namespace llvm Index: lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "DwarfAccelTable.h" +#include "DwarfCompileUnit.h" +#include "DwarfFile.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" @@ -31,12 +33,15 @@ using namespace llvm; +AccelTable::AccelTable(uint32_t EmptyBucket) + : Entries(Allocator), EmptyBucket(EmptyBucket) {} + // The length of the header data is always going to be 4 + 4 + 4*NumAtoms. -DwarfAccelTable::DwarfAccelTable(ArrayRef atomList) - : Header(8 + (atomList.size() * 4)), HeaderData(atomList), - Entries(Allocator) {} +AppleAccelTable::AppleAccelTable(ArrayRef atomList) + : AccelTable(std::numeric_limits::max()), + Header(8 + (atomList.size() * 4)), HeaderData(atomList) {} -void DwarfAccelTable::AddName(DwarfStringPoolEntryRef Name, const DIE *die, +void AccelTable::AddName(DwarfStringPoolEntryRef Name, const DIE *die, char Flags) { assert(Data.empty() && "Already finalized!"); // If the string is in the list already then add this die to the list @@ -47,7 +52,7 @@ DIEs.Values.push_back(new (Allocator) HashDataContents(die, Flags)); } -void DwarfAccelTable::ComputeBucketCount() { +std::pair AccelTable::ComputeBucketCount() { // First get the number of unique hashes. std::vector uniques(Data.size()); for (size_t i = 0, e = Data.size(); i < e; ++i) @@ -57,24 +62,25 @@ std::unique(uniques.begin(), uniques.end()); uint32_t num = std::distance(uniques.begin(), p); + uint32_t bucket_count; // Then compute the bucket size, minimum of 1 bucket. if (num > 1024) - Header.bucket_count = num / 4; + bucket_count = num / 4; else if (num > 16) - Header.bucket_count = num / 2; + bucket_count = num / 2; else - Header.bucket_count = num > 0 ? num : 1; + bucket_count = num > 0 ? num : 1; - Header.hashes_count = num; + return {bucket_count, num}; } // compareDIEs - comparison predicate that sorts DIEs by their offset. -static bool compareDIEs(const DwarfAccelTable::HashDataContents *A, - const DwarfAccelTable::HashDataContents *B) { +static bool compareDIEs(const AccelTable::HashDataContents *A, + const AccelTable::HashDataContents *B) { return A->Die->getOffset() < B->Die->getOffset(); } -void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, StringRef Prefix) { +void AccelTable::finalizeData() { // Create the individual hash data outputs. Data.reserve(Entries.size()); for (StringMap::iterator EI = Entries.begin(), EE = Entries.end(); @@ -89,18 +95,25 @@ HashData *Entry = new (Allocator) HashData(EI->getKey(), EI->second); Data.push_back(Entry); } +} + +void AccelTable::finalizeTable(AsmPrinter *Asm, StringRef Prefix, + DwarfFile &DF) { + finalizeData(); // Figure out how many buckets we need, then compute the bucket // contents and the final ordering. We'll emit the hashes and offsets // by doing a walk during the emission phase. We add temporary // symbols to the data so that we can reference them during the offset // later, we'll emit them when we emit the data. - ComputeBucketCount(); + uint32_t bucket_count, name_count; + std::tie(bucket_count, name_count) = ComputeBucketCount(); + finalizeHeader(Asm, DF, bucket_count, name_count); // Compute bucket contents and final ordering. - Buckets.resize(Header.bucket_count); + Buckets.resize(bucket_count); for (size_t i = 0, e = Data.size(); i < e; ++i) { - uint32_t bucket = Data[i]->HashValue % Header.bucket_count; + uint32_t bucket = Data[i]->HashValue % bucket_count; Buckets[bucket].push_back(Data[i]); Data[i]->Sym = Asm->createTempSymbol(Prefix); } @@ -115,8 +128,15 @@ }); } +void AppleAccelTable::finalizeHeader(AsmPrinter *, DwarfFile &, + uint32_t bucket_count, + uint32_t name_count) { + Header.bucket_count = bucket_count; + Header.hashes_count = name_count; +} + // Emits the header for the table via the AsmPrinter. -void DwarfAccelTable::EmitHeader(AsmPrinter *Asm) { +void AppleAccelTable::EmitHeader(AsmPrinter *Asm) { Asm->OutStreamer->AddComment("Header Magic"); Asm->EmitInt32(Header.magic); Asm->OutStreamer->AddComment("Header Version"); @@ -144,14 +164,14 @@ // Walk through and emit the buckets for the table. Each index is // an offset into the list of hashes. -void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) { - unsigned index = 0; +void AccelTable::EmitBuckets(AsmPrinter *Asm) { + uint32_t index = EmptyBucket + 1; for (size_t i = 0, e = Buckets.size(); i < e; ++i) { Asm->OutStreamer->AddComment("Bucket " + Twine(i)); if (!Buckets[i].empty()) Asm->EmitInt32(index); else - Asm->EmitInt32(std::numeric_limits::max()); + Asm->EmitInt32(EmptyBucket); // Buckets point in the list of hashes, not to the data. Do not // increment the index multiple times in case of hash collisions. uint64_t PrevHash = std::numeric_limits::max(); @@ -166,7 +186,7 @@ // Walk through the buckets and emit the individual hashes for each // bucket. -void DwarfAccelTable::EmitHashes(AsmPrinter *Asm) { +void AccelTable::EmitHashes(AsmPrinter *Asm) { uint64_t PrevHash = std::numeric_limits::max(); for (size_t i = 0, e = Buckets.size(); i < e; ++i) { for (HashList::const_iterator HI = Buckets[i].begin(), @@ -186,7 +206,7 @@ // element in each bucket. This is done via a symbol subtraction from the // beginning of the section. The non-section symbol will be output later // when we emit the actual data. -void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) { +void AccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) { uint64_t PrevHash = std::numeric_limits::max(); for (size_t i = 0, e = Buckets.size(); i < e; ++i) { for (HashList::const_iterator HI = Buckets[i].begin(), @@ -209,7 +229,7 @@ // Walk through the buckets and emit the full data for each element in // the bucket. For the string case emit the dies and the various offsets. // Terminate each HashData bucket with 0. -void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) { +void AppleAccelTable::emitData(AsmPrinter *Asm) { for (size_t i = 0, e = Buckets.size(); i < e; ++i) { uint64_t PrevHash = std::numeric_limits::max(); for (HashList::const_iterator HI = Buckets[i].begin(), @@ -220,6 +240,7 @@ if (PrevHash != std::numeric_limits::max() && PrevHash != (*HI)->HashValue) Asm->EmitInt32(0); + // Remember to emit the label for our offset. Asm->OutStreamer->EmitLabel((*HI)->Sym); Asm->OutStreamer->AddComment((*HI)->Str); @@ -236,6 +257,7 @@ Asm->EmitInt8(HD->Flags); } } + PrevHash = (*HI)->HashValue; } // Emit the final end marker for the bucket. @@ -245,8 +267,8 @@ } // Emit the entire data structure to the output file. -void DwarfAccelTable::emit(AsmPrinter *Asm, const MCSymbol *SecBegin, - DwarfDebug *D) { +void AppleAccelTable::emit(AsmPrinter *Asm, const MCSymbol *SecBegin, + DwarfFile &DF) { // Emit the header. EmitHeader(Asm); @@ -260,11 +282,11 @@ emitOffsets(Asm, SecBegin); // Emit the hash data. - EmitData(Asm, D); + emitData(Asm); } -#ifndef NDEBUG -void DwarfAccelTable::print(raw_ostream &OS) { +#ifdef NDEBUGa +void AccelTable::print(raw_ostream &OS) { Header.print(OS); HeaderData.print(OS); @@ -291,3 +313,155 @@ (*DI)->print(OS); } #endif + +void Dwarf5AccelTable::finalizeHeader(AsmPrinter *Asm, DwarfFile &DF, + uint32_t bucket_count, + uint32_t name_count) { + Start = Asm->createTempSymbol("names_start"); + End = Asm->createTempSymbol("names_end"); + AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); + AbbrevEnd = Asm->createTempSymbol("names_abbrev_end"); + EntryPool = Asm->createTempSymbol("names_entries"); + + Header.comp_unit_count = DF.getUnits().size(); + Header.bucket_count = bucket_count; + Header.name_count = name_count; +} + +void Dwarf5AccelTable::finalizeTable(AsmPrinter *Asm, StringRef Prefix, + DwarfFile &DF) { + AccelTable::finalizeTable(Asm, Prefix, DF); + + for(const HashData *HD: Data) { + for(const HashDataContents *HDC: HD->Data.Values) + Tags.insert(HDC->Die->getTag()); + } +} + +void Dwarf5AccelTable::EmitHeader(AsmPrinter *Asm) { + MCContext &Context = Asm->OutStreamer->getContext(); + + const MCExpr *Sub = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(End, Context), + MCSymbolRefExpr::create(Start, Context), Context); + Asm->OutStreamer->AddComment("Header: contribution length"); + Asm->OutStreamer->EmitValue(Sub, sizeof(uint32_t)); + + Asm->OutStreamer->EmitLabel(Start); + Asm->OutStreamer->AddComment("Header: version"); + Asm->EmitInt16(Header.version); + Asm->OutStreamer->AddComment("Header: padding"); + Asm->EmitInt16(Header.padding); + Asm->OutStreamer->AddComment("Header: compilation unit count"); + Asm->EmitInt32(Header.comp_unit_count); + Asm->OutStreamer->AddComment("Header: local type unit count"); + Asm->EmitInt32(Header.local_type_unit_count); + Asm->OutStreamer->AddComment("Header: foreign type unit count"); + Asm->EmitInt32(Header.foreign_type_unit_count); + Asm->OutStreamer->AddComment("Header: bucket count"); + Asm->EmitInt32(Header.bucket_count); + Asm->OutStreamer->AddComment("Header: name count"); + Asm->EmitInt32(Header.name_count); + + Asm->OutStreamer->AddComment("Header: abbreviation table size"); + Sub = MCBinaryExpr::createSub(MCSymbolRefExpr::create(AbbrevEnd, Context), + MCSymbolRefExpr::create(AbbrevStart, Context), + Context); + Asm->OutStreamer->EmitValue(Sub, sizeof(uint32_t)); + + Asm->OutStreamer->AddComment("Header: augmentation length"); + Asm->EmitInt32(Header.augmentation_string.length()); + if (!Header.augmentation_string.empty()) { + Asm->OutStreamer->AddComment("Header: augmentation"); + Asm->OutStreamer->EmitBytes(Header.augmentation_string); + Asm->OutStreamer->EmitValueToAlignment(4, 0); + } +} + +void Dwarf5AccelTable::emitCUList(AsmPrinter *Asm, const SmallVectorImpl> &CUs) { + assert(Header.comp_unit_count == CUs.size()); + + size_t Size = CUs.size(); + for(size_t i = 0; iOutStreamer->AddComment("Compilation unit " + Twine(i)); + Asm->emitDwarfSymbolReference(CUs[i]->getLabelBegin()); + } +} + +void Dwarf5AccelTable::emitStringOffsets(AsmPrinter *Asm) { + size_t Ind = 0; + for(const HashList &HL: Buckets) { + for(const HashData *HD: HL) { + DwarfStringPoolEntryRef String = HD->Data.Name; + Asm->OutStreamer->AddComment("String in Bucket " + Twine(Ind) + ": " + + String.getString()); + Asm->emitDwarfStringOffset(String); + } + ++Ind; + } +} + +void Dwarf5AccelTable::emitAbbrev(AsmPrinter *Asm, DwarfFile &DF) { + const bool SingleCU = DF.getUnits().size() == 1; + Asm->OutStreamer->EmitLabel(AbbrevStart); + for(auto T: Tags) { + assert(T != 0); + Asm->OutStreamer->AddComment("Abbrev code"); + Asm->EmitULEB128(T); + Asm->OutStreamer->AddComment(dwarf::TagString(T)); + Asm->EmitULEB128(T); + if(!SingleCU) { + Asm->EmitULEB128(dwarf::DW_IDX_compile_unit, "DW_IDX_compile_unit"); + Asm->EmitULEB128(dwarf::DW_FORM_data4, "DW_FORM_data4"); + } + Asm->EmitULEB128(dwarf::DW_IDX_die_offset, "DW_IDX_die_offset"); + Asm->EmitULEB128(dwarf::DW_FORM_data4, "DW_FORM_data4"); + Asm->EmitULEB128(0, "End of abbrev"); + Asm->EmitULEB128(0, "End of abbrev"); + } + Asm->EmitULEB128(0, "End of abbrev list"); + Asm->OutStreamer->EmitLabel(AbbrevEnd); +} + +// Walk through the buckets and emit the full data for each element in +// the bucket. For the string case emit the dies and the various offsets. +// Terminate each HashData bucket with 0. +void Dwarf5AccelTable::emitData(AsmPrinter *Asm, DwarfFile &DF) { + const bool SingleCU = DF.getUnits().size() == 1; + + Asm->OutStreamer->EmitLabel(EntryPool); + for (const HashList &HL : Buckets) { + for (const HashData *HD : HL) { + // Remember to emit the label for our offset. + Asm->OutStreamer->EmitLabel(HD->Sym); + for (const HashDataContents *HDC : HD->Data.Values) { + Asm->OutStreamer->AddComment("Abbrev code"); + Asm->EmitULEB128(HDC->Die->getTag()); + if (!SingleCU) { + Asm->OutStreamer->AddComment("DW_IDX_compile_unit"); +// DF.lookupCU(HDC->Die) +// HDC->Die->getUnit()-> + // Asm->EmitInt8(); // XXX + } + Asm->OutStreamer->AddComment("DW_IDX_die_offset"); + Asm->EmitInt32(HDC->Die->getOffset()); + } + Asm->OutStreamer->AddComment("End of list: " + HD->Str); + Asm->EmitInt32(0); + } + } +} + +void Dwarf5AccelTable::emit(AsmPrinter *Asm, const MCSymbol *SecBegin, + DwarfFile &DF) { + EmitHeader(Asm); + emitCUList(Asm, DF.getUnits()); + EmitBuckets(Asm); + EmitHashes(Asm); + emitStringOffsets(Asm); + emitOffsets(Asm, EntryPool); + emitAbbrev(Asm, DF); + emitData(Asm, DF); + Asm->OutStreamer->EmitValueToAlignment(4, 0); + Asm->OutStreamer->EmitLabel(End); +} Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -283,10 +283,11 @@ AddressPool AddrPool; - DwarfAccelTable AccelNames; - DwarfAccelTable AccelObjC; - DwarfAccelTable AccelNamespace; - DwarfAccelTable AccelTypes; + AppleAccelTable AccelNames; + AppleAccelTable AccelObjC; + AppleAccelTable AccelNamespace; + AppleAccelTable AccelTypes; + Dwarf5AccelTable AccelNames5; // Identify a debugger for "tuning" the debug info. DebuggerKind DebuggerTuning = DebuggerKind::Default; @@ -325,7 +326,7 @@ void emitAbbreviations(); /// Emit a specified accelerator table. - void emitAccel(DwarfAccelTable &Accel, MCSection *Section, + void emitAccel(AccelTable &Accel, MCSection *Section, StringRef TableName); /// Emit visible names into a hashed accelerator table section. Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -258,21 +258,21 @@ "conflicting locations for variable"); } -static const DwarfAccelTable::Atom TypeAtoms[] = { - DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4), - DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2), - DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)}; +static const AppleAccelTable::Atom TypeAtoms[] = { + AppleAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4), + AppleAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2), + AppleAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)}; DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()), InfoHolder(A, "info_string", DIEValueAllocator), SkeletonHolder(A, "skel_string", DIEValueAllocator), IsDarwin(A->TM.getTargetTriple().isOSDarwin()), - AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, + AccelNames(AppleAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), - AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, + AccelObjC(AppleAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), - AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, + AccelNamespace(AppleAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), AccelTypes(TypeAtoms) { const Triple &TT = Asm->TM.getTargetTriple(); @@ -1401,18 +1401,18 @@ Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection()); } -void DwarfDebug::emitAccel(DwarfAccelTable &Accel, MCSection *Section, +void DwarfDebug::emitAccel(AccelTable &Accel, MCSection *Section, StringRef TableName) { - Accel.FinalizeTable(Asm, TableName); + Accel.finalizeTable(Asm, TableName, InfoHolder); Asm->OutStreamer->SwitchSection(Section); // Emit the full data. - Accel.emit(Asm, Section->getBeginSymbol(), this); + Accel.emit(Asm, Section->getBeginSymbol(), InfoHolder); } // Emit visible names into a hashed accelerator table section. void DwarfDebug::emitAccelNames() { - emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(), + emitAccel(AccelNames5, Asm->getObjFileLowering().getDwarfAccelNamesSection(), "Names"); } @@ -2162,6 +2162,7 @@ if (!useDwarfAccelTables()) return; AccelNames.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die); + AccelNames5.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die); } void DwarfDebug::addAccelObjC(StringRef Name, const DIE &Die) {