1259698Sdim//===-- llvm/CodeGen/DIEHash.cpp - Dwarf Hashing Framework ----------------===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file contains support for DWARF4 hashing of DIEs. 11259698Sdim// 12259698Sdim//===----------------------------------------------------------------------===// 13259698Sdim 14259698Sdim#define DEBUG_TYPE "dwarfdebug" 15259698Sdim 16259698Sdim#include "DIEHash.h" 17259698Sdim 18259698Sdim#include "DIE.h" 19259698Sdim#include "DwarfCompileUnit.h" 20259698Sdim#include "llvm/ADT/ArrayRef.h" 21259698Sdim#include "llvm/ADT/StringRef.h" 22259698Sdim#include "llvm/Support/Debug.h" 23259698Sdim#include "llvm/Support/Dwarf.h" 24259698Sdim#include "llvm/Support/Endian.h" 25259698Sdim#include "llvm/Support/MD5.h" 26259698Sdim#include "llvm/Support/raw_ostream.h" 27259698Sdim 28259698Sdimusing namespace llvm; 29259698Sdim 30259698Sdim/// \brief Grabs the string in whichever attribute is passed in and returns 31259698Sdim/// a reference to it. 32259698Sdimstatic StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) { 33259698Sdim const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); 34259698Sdim const DIEAbbrev &Abbrevs = Die.getAbbrev(); 35259698Sdim 36259698Sdim // Iterate through all the attributes until we find the one we're 37259698Sdim // looking for, if we can't find it return an empty string. 38259698Sdim for (size_t i = 0; i < Values.size(); ++i) { 39259698Sdim if (Abbrevs.getData()[i].getAttribute() == Attr) { 40259698Sdim DIEValue *V = Values[i]; 41259698Sdim assert(isa<DIEString>(V) && "String requested. Not a string."); 42259698Sdim DIEString *S = cast<DIEString>(V); 43259698Sdim return S->getString(); 44259698Sdim } 45259698Sdim } 46259698Sdim return StringRef(""); 47259698Sdim} 48259698Sdim 49259698Sdim/// \brief Adds the string in \p Str to the hash. This also hashes 50259698Sdim/// a trailing NULL with the string. 51259698Sdimvoid DIEHash::addString(StringRef Str) { 52259698Sdim DEBUG(dbgs() << "Adding string " << Str << " to hash.\n"); 53259698Sdim Hash.update(Str); 54259698Sdim Hash.update(makeArrayRef((uint8_t)'\0')); 55259698Sdim} 56259698Sdim 57259698Sdim// FIXME: The LEB128 routines are copied and only slightly modified out of 58259698Sdim// LEB128.h. 59259698Sdim 60259698Sdim/// \brief Adds the unsigned in \p Value to the hash encoded as a ULEB128. 61259698Sdimvoid DIEHash::addULEB128(uint64_t Value) { 62259698Sdim DEBUG(dbgs() << "Adding ULEB128 " << Value << " to hash.\n"); 63259698Sdim do { 64259698Sdim uint8_t Byte = Value & 0x7f; 65259698Sdim Value >>= 7; 66259698Sdim if (Value != 0) 67259698Sdim Byte |= 0x80; // Mark this byte to show that more bytes will follow. 68259698Sdim Hash.update(Byte); 69259698Sdim } while (Value != 0); 70259698Sdim} 71259698Sdim 72259698Sdimvoid DIEHash::addSLEB128(int64_t Value) { 73259698Sdim DEBUG(dbgs() << "Adding ULEB128 " << Value << " to hash.\n"); 74259698Sdim bool More; 75259698Sdim do { 76259698Sdim uint8_t Byte = Value & 0x7f; 77259698Sdim Value >>= 7; 78259698Sdim More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || 79259698Sdim ((Value == -1) && ((Byte & 0x40) != 0)))); 80259698Sdim if (More) 81259698Sdim Byte |= 0x80; // Mark this byte to show that more bytes will follow. 82259698Sdim Hash.update(Byte); 83259698Sdim } while (More); 84259698Sdim} 85259698Sdim 86259698Sdim/// \brief Including \p Parent adds the context of Parent to the hash.. 87259698Sdimvoid DIEHash::addParentContext(const DIE &Parent) { 88259698Sdim 89259698Sdim DEBUG(dbgs() << "Adding parent context to hash...\n"); 90259698Sdim 91259698Sdim // [7.27.2] For each surrounding type or namespace beginning with the 92259698Sdim // outermost such construct... 93259698Sdim SmallVector<const DIE *, 1> Parents; 94259698Sdim const DIE *Cur = &Parent; 95259698Sdim while (Cur->getTag() != dwarf::DW_TAG_compile_unit) { 96259698Sdim Parents.push_back(Cur); 97259698Sdim Cur = Cur->getParent(); 98259698Sdim } 99259698Sdim 100259698Sdim // Reverse iterate over our list to go from the outermost construct to the 101259698Sdim // innermost. 102259698Sdim for (SmallVectorImpl<const DIE *>::reverse_iterator I = Parents.rbegin(), 103259698Sdim E = Parents.rend(); 104259698Sdim I != E; ++I) { 105259698Sdim const DIE &Die = **I; 106259698Sdim 107259698Sdim // ... Append the letter "C" to the sequence... 108259698Sdim addULEB128('C'); 109259698Sdim 110259698Sdim // ... Followed by the DWARF tag of the construct... 111259698Sdim addULEB128(Die.getTag()); 112259698Sdim 113259698Sdim // ... Then the name, taken from the DW_AT_name attribute. 114259698Sdim StringRef Name = getDIEStringAttr(Die, dwarf::DW_AT_name); 115259698Sdim DEBUG(dbgs() << "... adding context: " << Name << "\n"); 116259698Sdim if (!Name.empty()) 117259698Sdim addString(Name); 118259698Sdim } 119259698Sdim} 120259698Sdim 121259698Sdim// Collect all of the attributes for a particular DIE in single structure. 122259698Sdimvoid DIEHash::collectAttributes(const DIE &Die, DIEAttrs &Attrs) { 123259698Sdim const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); 124259698Sdim const DIEAbbrev &Abbrevs = Die.getAbbrev(); 125259698Sdim 126259698Sdim#define COLLECT_ATTR(NAME) \ 127259698Sdim case dwarf::NAME: \ 128259698Sdim Attrs.NAME.Val = Values[i]; \ 129259698Sdim Attrs.NAME.Desc = &Abbrevs.getData()[i]; \ 130259698Sdim break 131259698Sdim 132259698Sdim for (size_t i = 0, e = Values.size(); i != e; ++i) { 133259698Sdim DEBUG(dbgs() << "Attribute: " 134259698Sdim << dwarf::AttributeString(Abbrevs.getData()[i].getAttribute()) 135259698Sdim << " added.\n"); 136259698Sdim switch (Abbrevs.getData()[i].getAttribute()) { 137259698Sdim COLLECT_ATTR(DW_AT_name); 138259698Sdim COLLECT_ATTR(DW_AT_accessibility); 139259698Sdim COLLECT_ATTR(DW_AT_address_class); 140259698Sdim COLLECT_ATTR(DW_AT_allocated); 141259698Sdim COLLECT_ATTR(DW_AT_artificial); 142259698Sdim COLLECT_ATTR(DW_AT_associated); 143259698Sdim COLLECT_ATTR(DW_AT_binary_scale); 144259698Sdim COLLECT_ATTR(DW_AT_bit_offset); 145259698Sdim COLLECT_ATTR(DW_AT_bit_size); 146259698Sdim COLLECT_ATTR(DW_AT_bit_stride); 147259698Sdim COLLECT_ATTR(DW_AT_byte_size); 148259698Sdim COLLECT_ATTR(DW_AT_byte_stride); 149259698Sdim COLLECT_ATTR(DW_AT_const_expr); 150259698Sdim COLLECT_ATTR(DW_AT_const_value); 151259698Sdim COLLECT_ATTR(DW_AT_containing_type); 152259698Sdim COLLECT_ATTR(DW_AT_count); 153259698Sdim COLLECT_ATTR(DW_AT_data_bit_offset); 154259698Sdim COLLECT_ATTR(DW_AT_data_location); 155259698Sdim COLLECT_ATTR(DW_AT_data_member_location); 156259698Sdim COLLECT_ATTR(DW_AT_decimal_scale); 157259698Sdim COLLECT_ATTR(DW_AT_decimal_sign); 158259698Sdim COLLECT_ATTR(DW_AT_default_value); 159259698Sdim COLLECT_ATTR(DW_AT_digit_count); 160259698Sdim COLLECT_ATTR(DW_AT_discr); 161259698Sdim COLLECT_ATTR(DW_AT_discr_list); 162259698Sdim COLLECT_ATTR(DW_AT_discr_value); 163259698Sdim COLLECT_ATTR(DW_AT_encoding); 164259698Sdim COLLECT_ATTR(DW_AT_enum_class); 165259698Sdim COLLECT_ATTR(DW_AT_endianity); 166259698Sdim COLLECT_ATTR(DW_AT_explicit); 167259698Sdim COLLECT_ATTR(DW_AT_is_optional); 168259698Sdim COLLECT_ATTR(DW_AT_location); 169259698Sdim COLLECT_ATTR(DW_AT_lower_bound); 170259698Sdim COLLECT_ATTR(DW_AT_mutable); 171259698Sdim COLLECT_ATTR(DW_AT_ordering); 172259698Sdim COLLECT_ATTR(DW_AT_picture_string); 173259698Sdim COLLECT_ATTR(DW_AT_prototyped); 174259698Sdim COLLECT_ATTR(DW_AT_small); 175259698Sdim COLLECT_ATTR(DW_AT_segment); 176259698Sdim COLLECT_ATTR(DW_AT_string_length); 177259698Sdim COLLECT_ATTR(DW_AT_threads_scaled); 178259698Sdim COLLECT_ATTR(DW_AT_upper_bound); 179259698Sdim COLLECT_ATTR(DW_AT_use_location); 180259698Sdim COLLECT_ATTR(DW_AT_use_UTF8); 181259698Sdim COLLECT_ATTR(DW_AT_variable_parameter); 182259698Sdim COLLECT_ATTR(DW_AT_virtuality); 183259698Sdim COLLECT_ATTR(DW_AT_visibility); 184259698Sdim COLLECT_ATTR(DW_AT_vtable_elem_location); 185259698Sdim COLLECT_ATTR(DW_AT_type); 186259698Sdim default: 187259698Sdim break; 188259698Sdim } 189259698Sdim } 190259698Sdim} 191259698Sdim 192259698Sdimvoid DIEHash::hashShallowTypeReference(dwarf::Attribute Attribute, 193259698Sdim const DIE &Entry, StringRef Name) { 194259698Sdim // append the letter 'N' 195259698Sdim addULEB128('N'); 196259698Sdim 197259698Sdim // the DWARF attribute code (DW_AT_type or DW_AT_friend), 198259698Sdim addULEB128(Attribute); 199259698Sdim 200259698Sdim // the context of the tag, 201259698Sdim if (const DIE *Parent = Entry.getParent()) 202259698Sdim addParentContext(*Parent); 203259698Sdim 204259698Sdim // the letter 'E', 205259698Sdim addULEB128('E'); 206259698Sdim 207259698Sdim // and the name of the type. 208259698Sdim addString(Name); 209259698Sdim 210259698Sdim // Currently DW_TAG_friends are not used by Clang, but if they do become so, 211259698Sdim // here's the relevant spec text to implement: 212259698Sdim // 213259698Sdim // For DW_TAG_friend, if the referenced entry is the DW_TAG_subprogram, 214259698Sdim // the context is omitted and the name to be used is the ABI-specific name 215259698Sdim // of the subprogram (e.g., the mangled linker name). 216259698Sdim} 217259698Sdim 218259698Sdimvoid DIEHash::hashRepeatedTypeReference(dwarf::Attribute Attribute, 219259698Sdim unsigned DieNumber) { 220259698Sdim // a) If T is in the list of [previously hashed types], use the letter 221259698Sdim // 'R' as the marker 222259698Sdim addULEB128('R'); 223259698Sdim 224259698Sdim addULEB128(Attribute); 225259698Sdim 226259698Sdim // and use the unsigned LEB128 encoding of [the index of T in the 227259698Sdim // list] as the attribute value; 228259698Sdim addULEB128(DieNumber); 229259698Sdim} 230259698Sdim 231259698Sdimvoid DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag, 232259698Sdim const DIE &Entry) { 233259698Sdim assert(Tag != dwarf::DW_TAG_friend && "No current LLVM clients emit friend " 234259698Sdim "tags. Add support here when there's " 235259698Sdim "a use case"); 236259698Sdim // Step 5 237259698Sdim // If the tag in Step 3 is one of [the below tags] 238259698Sdim if ((Tag == dwarf::DW_TAG_pointer_type || 239259698Sdim Tag == dwarf::DW_TAG_reference_type || 240259698Sdim Tag == dwarf::DW_TAG_rvalue_reference_type || 241259698Sdim Tag == dwarf::DW_TAG_ptr_to_member_type) && 242259698Sdim // and the referenced type (via the [below attributes]) 243259698Sdim // FIXME: This seems overly restrictive, and causes hash mismatches 244259698Sdim // there's a decl/def difference in the containing type of a 245259698Sdim // ptr_to_member_type, but it's what DWARF says, for some reason. 246259698Sdim Attribute == dwarf::DW_AT_type) { 247259698Sdim // ... has a DW_AT_name attribute, 248259698Sdim StringRef Name = getDIEStringAttr(Entry, dwarf::DW_AT_name); 249259698Sdim if (!Name.empty()) { 250259698Sdim hashShallowTypeReference(Attribute, Entry, Name); 251259698Sdim return; 252259698Sdim } 253259698Sdim } 254259698Sdim 255259698Sdim unsigned &DieNumber = Numbering[&Entry]; 256259698Sdim if (DieNumber) { 257259698Sdim hashRepeatedTypeReference(Attribute, DieNumber); 258259698Sdim return; 259259698Sdim } 260259698Sdim 261259698Sdim // otherwise, b) use the letter 'T' as a the marker, ... 262259698Sdim addULEB128('T'); 263259698Sdim 264259698Sdim addULEB128(Attribute); 265259698Sdim 266259698Sdim // ... process the type T recursively by performing Steps 2 through 7, and 267259698Sdim // use the result as the attribute value. 268259698Sdim DieNumber = Numbering.size(); 269259698Sdim computeHash(Entry); 270259698Sdim} 271259698Sdim 272259698Sdim// Hash an individual attribute \param Attr based on the type of attribute and 273259698Sdim// the form. 274259698Sdimvoid DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { 275259698Sdim const DIEValue *Value = Attr.Val; 276259698Sdim const DIEAbbrevData *Desc = Attr.Desc; 277259698Sdim dwarf::Attribute Attribute = Desc->getAttribute(); 278259698Sdim 279259698Sdim // 7.27 Step 3 280259698Sdim // ... An attribute that refers to another type entry T is processed as 281259698Sdim // follows: 282259698Sdim if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) { 283259698Sdim hashDIEEntry(Attribute, Tag, *EntryAttr->getEntry()); 284259698Sdim return; 285259698Sdim } 286259698Sdim 287259698Sdim // Other attribute values use the letter 'A' as the marker, ... 288259698Sdim addULEB128('A'); 289259698Sdim 290259698Sdim addULEB128(Attribute); 291259698Sdim 292259698Sdim // ... and the value consists of the form code (encoded as an unsigned LEB128 293259698Sdim // value) followed by the encoding of the value according to the form code. To 294259698Sdim // ensure reproducibility of the signature, the set of forms used in the 295259698Sdim // signature computation is limited to the following: DW_FORM_sdata, 296259698Sdim // DW_FORM_flag, DW_FORM_string, and DW_FORM_block. 297259698Sdim switch (Desc->getForm()) { 298259698Sdim case dwarf::DW_FORM_string: 299259698Sdim llvm_unreachable( 300259698Sdim "Add support for DW_FORM_string if we ever start emitting them again"); 301259698Sdim case dwarf::DW_FORM_GNU_str_index: 302259698Sdim case dwarf::DW_FORM_strp: 303259698Sdim addULEB128(dwarf::DW_FORM_string); 304259698Sdim addString(cast<DIEString>(Value)->getString()); 305259698Sdim break; 306259698Sdim case dwarf::DW_FORM_data1: 307259698Sdim case dwarf::DW_FORM_data2: 308259698Sdim case dwarf::DW_FORM_data4: 309259698Sdim case dwarf::DW_FORM_data8: 310259698Sdim case dwarf::DW_FORM_udata: 311259698Sdim addULEB128(dwarf::DW_FORM_sdata); 312259698Sdim addSLEB128((int64_t)cast<DIEInteger>(Value)->getValue()); 313259698Sdim break; 314259698Sdim default: 315259698Sdim llvm_unreachable("Add support for additional forms"); 316259698Sdim } 317259698Sdim} 318259698Sdim 319259698Sdim// Go through the attributes from \param Attrs in the order specified in 7.27.4 320259698Sdim// and hash them. 321259698Sdimvoid DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) { 322259698Sdim#define ADD_ATTR(ATTR) \ 323259698Sdim { \ 324259698Sdim if (ATTR.Val != 0) \ 325259698Sdim hashAttribute(ATTR, Tag); \ 326259698Sdim } 327259698Sdim 328259698Sdim ADD_ATTR(Attrs.DW_AT_name); 329259698Sdim ADD_ATTR(Attrs.DW_AT_accessibility); 330259698Sdim ADD_ATTR(Attrs.DW_AT_address_class); 331259698Sdim ADD_ATTR(Attrs.DW_AT_allocated); 332259698Sdim ADD_ATTR(Attrs.DW_AT_artificial); 333259698Sdim ADD_ATTR(Attrs.DW_AT_associated); 334259698Sdim ADD_ATTR(Attrs.DW_AT_binary_scale); 335259698Sdim ADD_ATTR(Attrs.DW_AT_bit_offset); 336259698Sdim ADD_ATTR(Attrs.DW_AT_bit_size); 337259698Sdim ADD_ATTR(Attrs.DW_AT_bit_stride); 338259698Sdim ADD_ATTR(Attrs.DW_AT_byte_size); 339259698Sdim ADD_ATTR(Attrs.DW_AT_byte_stride); 340259698Sdim ADD_ATTR(Attrs.DW_AT_const_expr); 341259698Sdim ADD_ATTR(Attrs.DW_AT_const_value); 342259698Sdim ADD_ATTR(Attrs.DW_AT_containing_type); 343259698Sdim ADD_ATTR(Attrs.DW_AT_count); 344259698Sdim ADD_ATTR(Attrs.DW_AT_data_bit_offset); 345259698Sdim ADD_ATTR(Attrs.DW_AT_data_location); 346259698Sdim ADD_ATTR(Attrs.DW_AT_data_member_location); 347259698Sdim ADD_ATTR(Attrs.DW_AT_decimal_scale); 348259698Sdim ADD_ATTR(Attrs.DW_AT_decimal_sign); 349259698Sdim ADD_ATTR(Attrs.DW_AT_default_value); 350259698Sdim ADD_ATTR(Attrs.DW_AT_digit_count); 351259698Sdim ADD_ATTR(Attrs.DW_AT_discr); 352259698Sdim ADD_ATTR(Attrs.DW_AT_discr_list); 353259698Sdim ADD_ATTR(Attrs.DW_AT_discr_value); 354259698Sdim ADD_ATTR(Attrs.DW_AT_encoding); 355259698Sdim ADD_ATTR(Attrs.DW_AT_enum_class); 356259698Sdim ADD_ATTR(Attrs.DW_AT_endianity); 357259698Sdim ADD_ATTR(Attrs.DW_AT_explicit); 358259698Sdim ADD_ATTR(Attrs.DW_AT_is_optional); 359259698Sdim ADD_ATTR(Attrs.DW_AT_location); 360259698Sdim ADD_ATTR(Attrs.DW_AT_lower_bound); 361259698Sdim ADD_ATTR(Attrs.DW_AT_mutable); 362259698Sdim ADD_ATTR(Attrs.DW_AT_ordering); 363259698Sdim ADD_ATTR(Attrs.DW_AT_picture_string); 364259698Sdim ADD_ATTR(Attrs.DW_AT_prototyped); 365259698Sdim ADD_ATTR(Attrs.DW_AT_small); 366259698Sdim ADD_ATTR(Attrs.DW_AT_segment); 367259698Sdim ADD_ATTR(Attrs.DW_AT_string_length); 368259698Sdim ADD_ATTR(Attrs.DW_AT_threads_scaled); 369259698Sdim ADD_ATTR(Attrs.DW_AT_upper_bound); 370259698Sdim ADD_ATTR(Attrs.DW_AT_use_location); 371259698Sdim ADD_ATTR(Attrs.DW_AT_use_UTF8); 372259698Sdim ADD_ATTR(Attrs.DW_AT_variable_parameter); 373259698Sdim ADD_ATTR(Attrs.DW_AT_virtuality); 374259698Sdim ADD_ATTR(Attrs.DW_AT_visibility); 375259698Sdim ADD_ATTR(Attrs.DW_AT_vtable_elem_location); 376259698Sdim ADD_ATTR(Attrs.DW_AT_type); 377259698Sdim 378259698Sdim // FIXME: Add the extended attributes. 379259698Sdim} 380259698Sdim 381259698Sdim// Add all of the attributes for \param Die to the hash. 382259698Sdimvoid DIEHash::addAttributes(const DIE &Die) { 383259698Sdim DIEAttrs Attrs = {}; 384259698Sdim collectAttributes(Die, Attrs); 385259698Sdim hashAttributes(Attrs, Die.getTag()); 386259698Sdim} 387259698Sdim 388259698Sdimvoid DIEHash::hashNestedType(const DIE &Die, StringRef Name) { 389259698Sdim // 7.27 Step 7 390259698Sdim // ... append the letter 'S', 391259698Sdim addULEB128('S'); 392259698Sdim 393259698Sdim // the tag of C, 394259698Sdim addULEB128(Die.getTag()); 395259698Sdim 396259698Sdim // and the name. 397259698Sdim addString(Name); 398259698Sdim} 399259698Sdim 400259698Sdim// Compute the hash of a DIE. This is based on the type signature computation 401259698Sdim// given in section 7.27 of the DWARF4 standard. It is the md5 hash of a 402259698Sdim// flattened description of the DIE. 403259698Sdimvoid DIEHash::computeHash(const DIE &Die) { 404259698Sdim // Append the letter 'D', followed by the DWARF tag of the DIE. 405259698Sdim addULEB128('D'); 406259698Sdim addULEB128(Die.getTag()); 407259698Sdim 408259698Sdim // Add each of the attributes of the DIE. 409259698Sdim addAttributes(Die); 410259698Sdim 411259698Sdim // Then hash each of the children of the DIE. 412259698Sdim for (std::vector<DIE *>::const_iterator I = Die.getChildren().begin(), 413259698Sdim E = Die.getChildren().end(); 414259698Sdim I != E; ++I) { 415259698Sdim // 7.27 Step 7 416259698Sdim // If C is a nested type entry or a member function entry, ... 417259698Sdim if (isType((*I)->getTag()) || (*I)->getTag() == dwarf::DW_TAG_subprogram) { 418259698Sdim StringRef Name = getDIEStringAttr(**I, dwarf::DW_AT_name); 419259698Sdim // ... and has a DW_AT_name attribute 420259698Sdim if (!Name.empty()) { 421259698Sdim hashNestedType(**I, Name); 422259698Sdim continue; 423259698Sdim } 424259698Sdim } 425259698Sdim computeHash(**I); 426259698Sdim } 427259698Sdim 428259698Sdim // Following the last (or if there are no children), append a zero byte. 429259698Sdim Hash.update(makeArrayRef((uint8_t)'\0')); 430259698Sdim} 431259698Sdim 432259698Sdim/// This is based on the type signature computation given in section 7.27 of the 433259698Sdim/// DWARF4 standard. It is the md5 hash of a flattened description of the DIE 434259698Sdim/// with the exception that we are hashing only the context and the name of the 435259698Sdim/// type. 436259698Sdimuint64_t DIEHash::computeDIEODRSignature(const DIE &Die) { 437259698Sdim 438259698Sdim // Add the contexts to the hash. We won't be computing the ODR hash for 439259698Sdim // function local types so it's safe to use the generic context hashing 440259698Sdim // algorithm here. 441259698Sdim // FIXME: If we figure out how to account for linkage in some way we could 442259698Sdim // actually do this with a slight modification to the parent hash algorithm. 443259698Sdim if (const DIE *Parent = Die.getParent()) 444259698Sdim addParentContext(*Parent); 445259698Sdim 446259698Sdim // Add the current DIE information. 447259698Sdim 448259698Sdim // Add the DWARF tag of the DIE. 449259698Sdim addULEB128(Die.getTag()); 450259698Sdim 451259698Sdim // Add the name of the type to the hash. 452259698Sdim addString(getDIEStringAttr(Die, dwarf::DW_AT_name)); 453259698Sdim 454259698Sdim // Now get the result. 455259698Sdim MD5::MD5Result Result; 456259698Sdim Hash.final(Result); 457259698Sdim 458259698Sdim // ... take the least significant 8 bytes and return those. Our MD5 459259698Sdim // implementation always returns its results in little endian, swap bytes 460259698Sdim // appropriately. 461259698Sdim return *reinterpret_cast<support::ulittle64_t *>(Result + 8); 462259698Sdim} 463259698Sdim 464259698Sdim/// This is based on the type signature computation given in section 7.27 of the 465259698Sdim/// DWARF4 standard. It is an md5 hash of the flattened description of the DIE 466259698Sdim/// with the inclusion of the full CU and all top level CU entities. 467259698Sdim// TODO: Initialize the type chain at 0 instead of 1 for CU signatures. 468259698Sdimuint64_t DIEHash::computeCUSignature(const DIE &Die) { 469259698Sdim Numbering.clear(); 470259698Sdim Numbering[&Die] = 1; 471259698Sdim 472259698Sdim // Hash the DIE. 473259698Sdim computeHash(Die); 474259698Sdim 475259698Sdim // Now return the result. 476259698Sdim MD5::MD5Result Result; 477259698Sdim Hash.final(Result); 478259698Sdim 479259698Sdim // ... take the least significant 8 bytes and return those. Our MD5 480259698Sdim // implementation always returns its results in little endian, swap bytes 481259698Sdim // appropriately. 482259698Sdim return *reinterpret_cast<support::ulittle64_t *>(Result + 8); 483259698Sdim} 484259698Sdim 485259698Sdim/// This is based on the type signature computation given in section 7.27 of the 486259698Sdim/// DWARF4 standard. It is an md5 hash of the flattened description of the DIE 487259698Sdim/// with the inclusion of additional forms not specifically called out in the 488259698Sdim/// standard. 489259698Sdimuint64_t DIEHash::computeTypeSignature(const DIE &Die) { 490259698Sdim Numbering.clear(); 491259698Sdim Numbering[&Die] = 1; 492259698Sdim 493259698Sdim if (const DIE *Parent = Die.getParent()) 494259698Sdim addParentContext(*Parent); 495259698Sdim 496259698Sdim // Hash the DIE. 497259698Sdim computeHash(Die); 498259698Sdim 499259698Sdim // Now return the result. 500259698Sdim MD5::MD5Result Result; 501259698Sdim Hash.final(Result); 502259698Sdim 503259698Sdim // ... take the least significant 8 bytes and return those. Our MD5 504259698Sdim // implementation always returns its results in little endian, swap bytes 505259698Sdim // appropriately. 506259698Sdim return *reinterpret_cast<support::ulittle64_t *>(Result + 8); 507259698Sdim} 508