aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DIEHash.cpp
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2013-08-13 01:21:55 +0000
committerEric Christopher <echristo@gmail.com>2013-08-13 01:21:55 +0000
commit0710bfa8667ea08ede15bf4f801f25418b4cefa0 (patch)
treea1907f14c046e40962af8c6260bb4fc2dedc933f /lib/CodeGen/AsmPrinter/DIEHash.cpp
parent72dba254ae65b06062106910a70d46f21e19d55a (diff)
downloadexternal_llvm-0710bfa8667ea08ede15bf4f801f25418b4cefa0.tar.gz
external_llvm-0710bfa8667ea08ede15bf4f801f25418b4cefa0.tar.bz2
external_llvm-0710bfa8667ea08ede15bf4f801f25418b4cefa0.zip
Add the start of DIE hashing for DWARF4 type units and split dwarf
CUs. Currently only hashes the name of CUs and the names of any children, but it's an obvious first step to show the framework. The testcase should continue to be correct, however, as it's an empty TU. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188243 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DIEHash.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 783e2d2b39..c9c4541e93 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -102,6 +102,92 @@ void DIEHash::addParentContext(DIE *Parent) {
}
}
+// Collect all of the attributes for a particular DIE in single structure.
+void DIEHash::collectAttributes(DIE *Die, DIEAttrs Attrs) {
+ const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
+ const DIEAbbrev &Abbrevs = Die->getAbbrev();
+
+#define COLLECT_ATTR(NAME) \
+ Attrs.NAME.Val = Values[i]; \
+ Attrs.NAME.Desc = &Abbrevs.getData()[i];
+
+ for (size_t i = 0, e = Values.size(); i != e; ++i) {
+ DEBUG(dbgs() << "Attribute: "
+ << dwarf::AttributeString(Abbrevs.getData()[i].getAttribute())
+ << " added.\n");
+ switch (Abbrevs.getData()[i].getAttribute()) {
+ case dwarf::DW_AT_name:
+ COLLECT_ATTR(DW_AT_name);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+// Hash an individual attribute \param Attr based on the type of attribute and
+// the form.
+void DIEHash::hashAttribute(AttrEntry Attr) {
+ const DIEValue *Value = Attr.Val;
+ const DIEAbbrevData *Desc = Attr.Desc;
+
+ // TODO: Add support for types.
+
+ // Add the letter A to the hash.
+ addULEB128('A');
+
+ // Then the attribute code and form.
+ addULEB128(Desc->getAttribute());
+ addULEB128(Desc->getForm());
+
+ // TODO: Add support for additional forms.
+ switch (Desc->getForm()) {
+ case dwarf::DW_FORM_strp:
+ addString(cast<DIEString>(Value)->getString());
+ break;
+ }
+}
+
+// Go through the attributes from \param Attrs in the order specified in 7.27.4
+// and hash them.
+void DIEHash::hashAttributes(DIEAttrs Attrs) {
+#define ADD_ATTR(ATTR) \
+ { \
+ if (ATTR.Val != 0) \
+ hashAttribute(ATTR); \
+ }
+
+ // FIXME: Add the rest.
+ ADD_ATTR(Attrs.DW_AT_name);
+}
+
+// Add all of the attributes for \param Die to the hash.
+void DIEHash::addAttributes(DIE *Die) {
+ DIEAttrs Attrs;
+ memset(&Attrs, 0, sizeof(Attrs));
+ collectAttributes(Die, Attrs);
+ hashAttributes(Attrs);
+}
+
+// Compute the hash of a DIE. This is based on the type signature computation
+// given in section 7.27 of the DWARF4 standard. It is the md5 hash of a
+// flattened description of the DIE.
+void DIEHash::computeHash(DIE *Die) {
+
+ // Append the letter 'D', followed by the DWARF tag of the DIE.
+ addULEB128('D');
+ addULEB128(Die->getTag());
+
+ // Add each of the attributes of the DIE.
+ addAttributes(Die);
+
+ // Then hash each of the children of the DIE.
+ for (std::vector<DIE *>::const_iterator I = Die->getChildren().begin(),
+ E = Die->getChildren().end();
+ I != E; ++I)
+ computeHash(*I);
+}
+
/// This is based on the type signature computation given in section 7.27 of the
/// DWARF4 standard. It is the md5 hash of a flattened description of the DIE
/// with the exception that we are hashing only the context and the name of the
@@ -134,3 +220,21 @@ uint64_t DIEHash::computeDIEODRSignature(DIE *Die) {
// appropriately.
return *reinterpret_cast<support::ulittle64_t *>(Result + 8);
}
+
+/// This is based on the type signature computation given in section 7.27 of the
+/// DWARF4 standard. It is an md5 hash of the flattened description of the DIE
+/// with the inclusion of the full CU and all top level CU entities.
+uint64_t DIEHash::computeCUSignature(DIE *Die) {
+
+ // Hash the DIE.
+ computeHash(Die);
+
+ // Now return the result.
+ MD5::MD5Result Result;
+ Hash.final(Result);
+
+ // ... take the least significant 8 bytes and return those. Our MD5
+ // implementation always returns its results in little endian, swap bytes
+ // appropriately.
+ return *reinterpret_cast<support::ulittle64_t *>(Result + 8);
+}