10b57cec5SDimitry Andric //===-- llvm/CodeGen/DIEHash.h - Dwarf Hashing Framework -------*- C++ -*--===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains support for DWARF4 hashing of DIEs.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DIEHASH_H
140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_ASMPRINTER_DIEHASH_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/DIE.h"
180b57cec5SDimitry Andric #include "llvm/Support/MD5.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric class AsmPrinter;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric /// An object containing the capability of hashing and adding hash
250b57cec5SDimitry Andric /// attributes onto a DIE.
260b57cec5SDimitry Andric class DIEHash {
270b57cec5SDimitry Andric   // Collection of all attributes used in hashing a particular DIE.
280b57cec5SDimitry Andric   struct DIEAttrs {
290b57cec5SDimitry Andric #define HANDLE_DIE_HASH_ATTR(NAME) DIEValue NAME;
300b57cec5SDimitry Andric #include "DIEHashAttributes.def"
310b57cec5SDimitry Andric   };
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric public:
34e8d8bef9SDimitry Andric   DIEHash(AsmPrinter *A = nullptr, DwarfCompileUnit *CU = nullptr)
AP(A)35e8d8bef9SDimitry Andric       : AP(A), CU(CU) {}
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   /// Computes the CU signature.
380b57cec5SDimitry Andric   uint64_t computeCUSignature(StringRef DWOName, const DIE &Die);
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   /// Computes the type signature.
410b57cec5SDimitry Andric   uint64_t computeTypeSignature(const DIE &Die);
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   // Helper routines to process parts of a DIE.
440b57cec5SDimitry Andric private:
450b57cec5SDimitry Andric   /// Adds the parent context of \param Parent to the hash.
460b57cec5SDimitry Andric   void addParentContext(const DIE &Parent);
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   /// Adds the attributes of \param Die to the hash.
490b57cec5SDimitry Andric   void addAttributes(const DIE &Die);
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   /// Computes the full DWARF4 7.27 hash of the DIE.
520b57cec5SDimitry Andric   void computeHash(const DIE &Die);
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   // Routines that add DIEValues to the hash.
550b57cec5SDimitry Andric public:
560b57cec5SDimitry Andric   /// Adds \param Value to the hash.
update(uint8_t Value)570b57cec5SDimitry Andric   void update(uint8_t Value) { Hash.update(Value); }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   /// Encodes and adds \param Value to the hash as a ULEB128.
600b57cec5SDimitry Andric   void addULEB128(uint64_t Value);
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   /// Encodes and adds \param Value to the hash as a SLEB128.
630b57cec5SDimitry Andric   void addSLEB128(int64_t Value);
640b57cec5SDimitry Andric 
6504eeddc0SDimitry Andric   void hashRawTypeReference(const DIE &Entry);
6604eeddc0SDimitry Andric 
670b57cec5SDimitry Andric private:
680b57cec5SDimitry Andric   /// Adds \param Str to the hash and includes a NULL byte.
690b57cec5SDimitry Andric   void addString(StringRef Str);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   /// Collects the attributes of DIE \param Die into the \param Attrs
720b57cec5SDimitry Andric   /// structure.
730b57cec5SDimitry Andric   void collectAttributes(const DIE &Die, DIEAttrs &Attrs);
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   /// Hashes the attributes in \param Attrs in order.
760b57cec5SDimitry Andric   void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   /// Hashes the data in a block like DIEValue, e.g. DW_FORM_block or
790b57cec5SDimitry Andric   /// DW_FORM_exprloc.
800b57cec5SDimitry Andric   void hashBlockData(const DIE::const_value_range &Values);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// Hashes the contents pointed to in the .debug_loc section.
830b57cec5SDimitry Andric   void hashLocList(const DIELocList &LocList);
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Hashes an individual attribute.
860b57cec5SDimitry Andric   void hashAttribute(const DIEValue &Value, dwarf::Tag Tag);
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// Hashes an attribute that refers to another DIE.
890b57cec5SDimitry Andric   void hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag,
900b57cec5SDimitry Andric                     const DIE &Entry);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   /// Hashes a reference to a named type in such a way that is
930b57cec5SDimitry Andric   /// independent of whether that type is described by a declaration or a
940b57cec5SDimitry Andric   /// definition.
950b57cec5SDimitry Andric   void hashShallowTypeReference(dwarf::Attribute Attribute, const DIE &Entry,
960b57cec5SDimitry Andric                                 StringRef Name);
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   /// Hashes a reference to a previously referenced type DIE.
990b57cec5SDimitry Andric   void hashRepeatedTypeReference(dwarf::Attribute Attribute,
1000b57cec5SDimitry Andric                                  unsigned DieNumber);
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   void hashNestedType(const DIE &Die, StringRef Name);
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric private:
1050b57cec5SDimitry Andric   MD5 Hash;
1060b57cec5SDimitry Andric   AsmPrinter *AP;
107e8d8bef9SDimitry Andric   DwarfCompileUnit *CU;
1080b57cec5SDimitry Andric   DenseMap<const DIE *, unsigned> Numbering;
1090b57cec5SDimitry Andric };
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric #endif
113