diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DIEHash.h | 3 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/X86/fission-hash.ll | 4 | ||||
| -rw-r--r-- | llvm/unittests/CodeGen/DIEHashTest.cpp | 18 | 
4 files changed, 47 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp index bf02daac517..9a26e727bd9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -68,6 +68,20 @@ void DIEHash::addULEB128(uint64_t Value) {    } while (Value != 0);  } +void DIEHash::addSLEB128(int64_t Value) { +  DEBUG(dbgs() << "Adding ULEB128 " << Value << " to hash.\n"); +  bool More; +  do { +    uint8_t Byte = Value & 0x7f; +    Value >>= 7; +    More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || +              ((Value == -1) && ((Byte & 0x40) != 0)))); +    if (More) +      Byte |= 0x80; // Mark this byte to show that more bytes will follow. +    Hash.update(Byte); +  } while (More); +} +  /// \brief Including \p Parent adds the context of Parent to the hash..  void DIEHash::addParentContext(DIE *Parent) { @@ -277,15 +291,20 @@ void DIEHash::hashAttribute(AttrEntry Attr) {    // Add the letter A to the hash.    addULEB128('A'); -  // Then the attribute code and form. +  // Then the attribute code.    addULEB128(Desc->getAttribute()); -  addULEB128(Desc->getForm()); + +  // To ensure reproducibility of the signature, the set of forms used in the +  // signature computation is limited to the following: DW_FORM_sdata, +  // DW_FORM_flag, DW_FORM_string, and DW_FORM_block.    // TODO: Add support for additional forms.    switch (Desc->getForm()) { -  // TODO: We'll want to add DW_FORM_string here if we start emitting them -  // again. +  case dwarf::DW_FORM_string: +    llvm_unreachable( +        "Add support for DW_FORM_string if we ever start emitting them again");    case dwarf::DW_FORM_strp: +    addULEB128(dwarf::DW_FORM_string);      addString(cast<DIEString>(Value)->getString());      break;    case dwarf::DW_FORM_data1: @@ -293,7 +312,8 @@ void DIEHash::hashAttribute(AttrEntry Attr) {    case dwarf::DW_FORM_data4:    case dwarf::DW_FORM_data8:    case dwarf::DW_FORM_udata: -    addULEB128(cast<DIEInteger>(Value)->getValue()); +    addULEB128(dwarf::DW_FORM_sdata); +    addSLEB128((int64_t)cast<DIEInteger>(Value)->getValue());      break;    }  } diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h index b792aeab6ce..78238e19ab3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h @@ -106,6 +106,9 @@ private:    /// \brief Encodes and adds \param Value to the hash as a ULEB128.    void addULEB128(uint64_t Value); +  /// \brief Encodes and adds \param Value to the hash as a SLEB128. +  void addSLEB128(int64_t Value); +    /// \brief Adds \param Str to the hash and includes a NULL byte.    void addString(StringRef Str); diff --git a/llvm/test/DebugInfo/X86/fission-hash.ll b/llvm/test/DebugInfo/X86/fission-hash.ll index 1cfbf4439fb..969b21c4d8d 100644 --- a/llvm/test/DebugInfo/X86/fission-hash.ll +++ b/llvm/test/DebugInfo/X86/fission-hash.ll @@ -3,8 +3,8 @@  ; The source is an empty file. -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x2410f0bbc44241ed) -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x2410f0bbc44241ed) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x63fc20b98dd69e2d) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x63fc20b98dd69e2d)  !llvm.dbg.cu = !{!0}  !llvm.module.flags = !{!3} diff --git a/llvm/unittests/CodeGen/DIEHashTest.cpp b/llvm/unittests/CodeGen/DIEHashTest.cpp index 91b03224f0a..92b6d7686cf 100644 --- a/llvm/unittests/CodeGen/DIEHashTest.cpp +++ b/llvm/unittests/CodeGen/DIEHashTest.cpp @@ -23,6 +23,22 @@ TEST(DIEHashData1Test, DIEHash) {    DIEInteger Size(4);    Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Size);    uint64_t MD5Res = Hash.computeTypeSignature(&Die); -  ASSERT_EQ(0x4F68EF1039F8D2BULL, MD5Res); +  ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res); +} + +TEST(DIEHashTrivialTypeTest, DIEHash) { +  // A complete, but simple, type containing no members and defined on the first +  // line of a file. +  DIE FooType(dwarf::DW_TAG_structure_type); +  DIEInteger One(1); +  FooType.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One); + +  // Line and file number are ignored. +  FooType.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One); +  FooType.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One); +  uint64_t MD5Res = DIEHash().computeTypeSignature(&FooType); + +  // The exact same hash GCC produces for this DIE. +  ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);  }  }  | 

