From: David Blaikie Date: Wed, 16 Oct 2013 23:36:20 +0000 (+0000) Subject: DIEHash: Use DW_FORM_sdata for integers, per spec. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c0987082206d202c20ebe1d528c1b28a875160ac;p=oota-llvm.git DIEHash: Use DW_FORM_sdata for integers, per spec. This allows us to produce the same hash as GCC for at least some simple examples. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192855 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index bf02daac517..9a26e727bd9 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/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(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(Value)->getValue()); + addULEB128(dwarf::DW_FORM_sdata); + addSLEB128((int64_t)cast(Value)->getValue()); break; } } diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index b792aeab6ce..78238e19ab3 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/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/test/DebugInfo/X86/fission-hash.ll b/test/DebugInfo/X86/fission-hash.ll index 1cfbf4439fb..969b21c4d8d 100644 --- a/test/DebugInfo/X86/fission-hash.ll +++ b/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/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp index 91b03224f0a..92b6d7686cf 100644 --- a/unittests/CodeGen/DIEHashTest.cpp +++ b/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); } }