1bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher//=-- llvm/CodeGen/DwarfAccelTable.cpp - Dwarf Accelerator Tables -*- C++ -*-=// 2bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// 3bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// The LLVM Compiler Infrastructure 4bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// 5bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// This file is distributed under the University of Illinois Open Source 6bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// License. See LICENSE.TXT for details. 7bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// 8bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher//===----------------------------------------------------------------------===// 9bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// 10bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// This file contains support for writing dwarf accelerator tables. 11bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// 12bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher//===----------------------------------------------------------------------===// 13bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 14f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "DwarfAccelTable.h" 15f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "DIE.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "DwarfDebug.h" 17be3f051c49699a86d526833d7dbe95645680a340Benjamin Kramer#include "llvm/ADT/STLExtras.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h" 19bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#include "llvm/CodeGen/AsmPrinter.h" 20bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#include "llvm/MC/MCExpr.h" 21bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#include "llvm/MC/MCStreamer.h" 22bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#include "llvm/MC/MCSymbol.h" 23bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#include "llvm/Support/Debug.h" 24bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 25bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopherusing namespace llvm; 26bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 27bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopherconst char *DwarfAccelTable::Atom::AtomTypeString(enum AtomType AT) { 28bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher switch (AT) { 29bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeNULL: return "eAtomTypeNULL"; 30bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeDIEOffset: return "eAtomTypeDIEOffset"; 31bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeCUOffset: return "eAtomTypeCUOffset"; 32bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeTag: return "eAtomTypeTag"; 33bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeNameFlags: return "eAtomTypeNameFlags"; 34bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher case eAtomTypeTypeFlags: return "eAtomTypeTypeFlags"; 3572c1655e0af6c87ffe687bed1f4ed263b1165c06Eric Christopher } 362dd674fdce68f8fd59d78a3bbab2cf5b8d220290David Blaikie llvm_unreachable("invalid AtomType!"); 37bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 38bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 39c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher// The length of the header data is always going to be 4 + 4 + 4*NumAtoms. 4036c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin KramerDwarfAccelTable::DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom> atomList) : 41c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher Header(8 + (atomList.size() * 4)), 4236c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer HeaderData(atomList), 4336c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer Entries(Allocator) { } 44c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher 4536c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin KramerDwarfAccelTable::~DwarfAccelTable() { } 46e77546c3c3634863a79ffc3adea52882685db454Eric Christopher 47c36145f19c1e164f7d630b813e9970600d8f2976Eric Christophervoid DwarfAccelTable::AddName(StringRef Name, DIE* die, char Flags) { 4836c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer assert(Data.empty() && "Already finalized!"); 49bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // If the string is in the list already then add this die to the list 50bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // otherwise add a new one. 51c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher DataArray &DIEs = Entries[Name]; 5236c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer DIEs.push_back(new (Allocator) HashDataContents(die, Flags)); 53bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 54bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 55bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::ComputeBucketCount(void) { 56bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // First get the number of unique hashes. 57be3f051c49699a86d526833d7dbe95645680a340Benjamin Kramer std::vector<uint32_t> uniques(Data.size()); 5830b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Data.size(); i < e; ++i) 59bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher uniques[i] = Data[i]->HashValue; 60be3f051c49699a86d526833d7dbe95645680a340Benjamin Kramer array_pod_sort(uniques.begin(), uniques.end()); 61bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher std::vector<uint32_t>::iterator p = 62bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher std::unique(uniques.begin(), uniques.end()); 63bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher uint32_t num = std::distance(uniques.begin(), p); 64bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 65bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Then compute the bucket size, minimum of 1 bucket. 66bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher if (num > 1024) Header.bucket_count = num/4; 67bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher if (num > 16) Header.bucket_count = num/2; 68bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher else Header.bucket_count = num > 0 ? num : 1; 69bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 70bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Header.hashes_count = num; 71bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 72bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 7336c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer// compareDIEs - comparison predicate that sorts DIEs by their offset. 7436c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramerstatic bool compareDIEs(const DwarfAccelTable::HashDataContents *A, 7536c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer const DwarfAccelTable::HashDataContents *B) { 7636c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer return A->Die->getOffset() < B->Die->getOffset(); 778368f74c434db60c36a4044dfe80d4abee49ce27Eric Christopher} 788368f74c434db60c36a4044dfe80d4abee49ce27Eric Christopher 7903406c4f15b3bf0522763fe848cd40f9598b74e8Benjamin Kramervoid DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, StringRef Prefix) { 80bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Create the individual hash data outputs. 81c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher for (StringMap<DataArray>::iterator 82bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { 830ffe2b4dd6f26fa19827f85bf9e4a766539a859cEric Christopher 840ffe2b4dd6f26fa19827f85bf9e4a766539a859cEric Christopher // Unique the entries. 8536c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer std::stable_sort(EI->second.begin(), EI->second.end(), compareDIEs); 86547abbb40bc9d986446fa493b0caae5ed1f346f2Eric Christopher EI->second.erase(std::unique(EI->second.begin(), EI->second.end()), 87547abbb40bc9d986446fa493b0caae5ed1f346f2Eric Christopher EI->second.end()); 880ffe2b4dd6f26fa19827f85bf9e4a766539a859cEric Christopher 8936c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer HashData *Entry = new (Allocator) HashData(EI->getKey(), EI->second); 90bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Data.push_back(Entry); 91bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 92bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 93bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Figure out how many buckets we need, then compute the bucket 94bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // contents and the final ordering. We'll emit the hashes and offsets 95bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // by doing a walk during the emission phase. We add temporary 96bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // symbols to the data so that we can reference them during the offset 97bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // later, we'll emit them when we emit the data. 98bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher ComputeBucketCount(); 99bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 100bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Compute bucket contents and final ordering. 101bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Buckets.resize(Header.bucket_count); 10230b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Data.size(); i < e; ++i) { 103bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher uint32_t bucket = Data[i]->HashValue % Header.bucket_count; 104bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Buckets[bucket].push_back(Data[i]); 105bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Data[i]->Sym = Asm->GetTempSymbol(Prefix, i); 106bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 107bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 108bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 109bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Emits the header for the table via the AsmPrinter. 110bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::EmitHeader(AsmPrinter *Asm) { 111bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Magic"); 112bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(Header.magic); 113bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Version"); 114bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt16(Header.version); 115bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Hash Function"); 116bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt16(Header.hash_function); 117bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Bucket Count"); 118bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(Header.bucket_count); 119bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Hash Count"); 120bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(Header.hashes_count); 121bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Header Data Length"); 122bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(Header.header_data_len); 123bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("HeaderData Die Offset Base"); 124bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(HeaderData.die_offset_base); 125bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("HeaderData Atom Count"); 126bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(HeaderData.Atoms.size()); 127bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (size_t i = 0; i < HeaderData.Atoms.size(); i++) { 128bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Atom A = HeaderData.Atoms[i]; 129bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment(Atom::AtomTypeString(A.type)); 130bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt16(A.type); 131bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment(dwarf::FormEncodingString(A.form)); 132bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt16(A.form); 133bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 134bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 135bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 1362d65efed5357ff1768e0462feffc910809ed1b62Eric Christopher// Walk through and emit the buckets for the table. Each index is 1372d65efed5357ff1768e0462feffc910809ed1b62Eric Christopher// an offset into the list of hashes. 138bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) { 139bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher unsigned index = 0; 14030b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 141c545322c276f933759e4140027e5f84e480d15d6Eric Christopher Asm->OutStreamer.AddComment("Bucket " + Twine(i)); 142bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher if (Buckets[i].size() != 0) 143bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(index); 144bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher else 145bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(UINT32_MAX); 146bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher index += Buckets[i].size(); 147bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 148bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 149bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 150bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Walk through the buckets and emit the individual hashes for each 151bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// bucket. 152bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::EmitHashes(AsmPrinter *Asm) { 15330b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 154bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (HashList::const_iterator HI = Buckets[i].begin(), 155bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher HE = Buckets[i].end(); HI != HE; ++HI) { 156c545322c276f933759e4140027e5f84e480d15d6Eric Christopher Asm->OutStreamer.AddComment("Hash in Bucket " + Twine(i)); 157bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32((*HI)->HashValue); 15872c1655e0af6c87ffe687bed1f4ed263b1165c06Eric Christopher } 159bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 160bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 161bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 162bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Walk through the buckets and emit the individual offsets for each 163bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// element in each bucket. This is done via a symbol subtraction from the 164bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// beginning of the section. The non-section symbol will be output later 165bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// when we emit the actual data. 166bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::EmitOffsets(AsmPrinter *Asm, MCSymbol *SecBegin) { 16730b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 168bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (HashList::const_iterator HI = Buckets[i].begin(), 169bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher HE = Buckets[i].end(); HI != HE; ++HI) { 170c545322c276f933759e4140027e5f84e480d15d6Eric Christopher Asm->OutStreamer.AddComment("Offset in Bucket " + Twine(i)); 171bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher MCContext &Context = Asm->OutStreamer.getContext(); 172bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher const MCExpr *Sub = 173bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create((*HI)->Sym, Context), 174bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher MCSymbolRefExpr::Create(SecBegin, Context), 175bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Context); 1761ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher Asm->OutStreamer.EmitValue(Sub, sizeof(uint32_t)); 177bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 178bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 179bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 180bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 181bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Walk through the buckets and emit the full data for each element in 182bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// the bucket. For the string case emit the dies and the various offsets. 183bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Terminate each HashData bucket with 0. 1842e5d870b384f7cc20ba040e827d54fa473f60800Eric Christophervoid DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfUnits *D) { 185bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher uint64_t PrevHash = UINT64_MAX; 18630b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Buckets.size(); i < e; ++i) { 187bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (HashList::const_iterator HI = Buckets[i].begin(), 188bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher HE = Buckets[i].end(); HI != HE; ++HI) { 189bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Remember to emit the label for our offset. 190bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.EmitLabel((*HI)->Sym); 191bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment((*HI)->Str); 192bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitSectionOffset(D->getStringPoolEntry((*HI)->Str), 1932e5d870b384f7cc20ba040e827d54fa473f60800Eric Christopher D->getStringPoolSym()); 194bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->OutStreamer.AddComment("Num DIEs"); 195c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher Asm->EmitInt32((*HI)->Data.size()); 19636c38b81f0938974c0b1b5fde0b838d51466a94fBenjamin Kramer for (ArrayRef<HashDataContents*>::const_iterator 197c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher DI = (*HI)->Data.begin(), DE = (*HI)->Data.end(); 198bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher DI != DE; ++DI) { 199c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher // Emit the DIE offset 200c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher Asm->EmitInt32((*DI)->Die->getOffset()); 201c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher // If we have multiple Atoms emit that info too. 202c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher // FIXME: A bit of a hack, we either emit only one atom or all info. 203c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher if (HeaderData.Atoms.size() > 1) { 204c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher Asm->EmitInt16((*DI)->Die->getTag()); 205c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher Asm->EmitInt8((*DI)->Flags); 206c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher } 207bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 208bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit a 0 to terminate the data unless we have a hash collision. 209bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher if (PrevHash != (*HI)->HashValue) 210bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Asm->EmitInt32(0); 211bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher PrevHash = (*HI)->HashValue; 212bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 213bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 214bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 215bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 216bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher// Emit the entire data structure to the output file. 217bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::Emit(AsmPrinter *Asm, MCSymbol *SecBegin, 2182e5d870b384f7cc20ba040e827d54fa473f60800Eric Christopher DwarfUnits *D) { 219bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit the header. 220bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EmitHeader(Asm); 221bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 222bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit the buckets. 223bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EmitBuckets(Asm); 224bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 225bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit the hashes. 226bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EmitHashes(Asm); 227bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 228bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit the offsets. 229bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EmitOffsets(Asm, SecBegin); 230bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 231bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher // Emit the hash data. 232bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EmitData(Asm, D); 233bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 234bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 235bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#ifndef NDEBUG 236bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christophervoid DwarfAccelTable::print(raw_ostream &O) { 237bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 238bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher Header.print(O); 239bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher HeaderData.print(O); 240bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 241bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher O << "Entries: \n"; 242c36145f19c1e164f7d630b813e9970600d8f2976Eric Christopher for (StringMap<DataArray>::const_iterator 243bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { 244547abbb40bc9d986446fa493b0caae5ed1f346f2Eric Christopher O << "Name: " << EI->getKeyData() << "\n"; 245547abbb40bc9d986446fa493b0caae5ed1f346f2Eric Christopher for (DataArray::const_iterator DI = EI->second.begin(), 246547abbb40bc9d986446fa493b0caae5ed1f346f2Eric Christopher DE = EI->second.end(); 247bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher DI != DE; ++DI) 248bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher (*DI)->print(O); 249bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher } 250bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 251bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher O << "Buckets and Hashes: \n"; 25230b4d8b83b7b3995ac1b53f35d3110d48676b187Eric Christopher for (size_t i = 0, e = Buckets.size(); i < e; ++i) 253bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (HashList::const_iterator HI = Buckets[i].begin(), 254bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher HE = Buckets[i].end(); HI != HE; ++HI) 255bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher (*HI)->print(O); 256bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 257bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher O << "Data: \n"; 258bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher for (std::vector<HashData*>::const_iterator 259bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher DI = Data.begin(), DE = Data.end(); DI != DE; ++DI) 260bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher (*DI)->print(O); 26172c1655e0af6c87ffe687bed1f4ed263b1165c06Eric Christopher 262bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher 263bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher} 264bcbd3a4637f33036d05833364e180f9dfaabb67cEric Christopher#endif 265