@@ -102,6 +102,92 @@ void DIEHash::addParentContext(DIE *Parent) {
102
102
}
103
103
}
104
104
105
+ // Collect all of the attributes for a particular DIE in single structure.
106
+ void DIEHash::collectAttributes (DIE *Die, DIEAttrs Attrs) {
107
+ const SmallVectorImpl<DIEValue *> &Values = Die->getValues ();
108
+ const DIEAbbrev &Abbrevs = Die->getAbbrev ();
109
+
110
+ #define COLLECT_ATTR (NAME ) \
111
+ Attrs.NAME .Val = Values[i]; \
112
+ Attrs.NAME .Desc = &Abbrevs.getData ()[i];
113
+
114
+ for (size_t i = 0 , e = Values.size (); i != e; ++i) {
115
+ DEBUG (dbgs () << " Attribute: "
116
+ << dwarf::AttributeString (Abbrevs.getData ()[i].getAttribute ())
117
+ << " added.\n " );
118
+ switch (Abbrevs.getData ()[i].getAttribute ()) {
119
+ case dwarf::DW_AT_name:
120
+ COLLECT_ATTR (DW_AT_name);
121
+ break ;
122
+ default :
123
+ break ;
124
+ }
125
+ }
126
+ }
127
+
128
+ // Hash an individual attribute \param Attr based on the type of attribute and
129
+ // the form.
130
+ void DIEHash::hashAttribute (AttrEntry Attr) {
131
+ const DIEValue *Value = Attr.Val ;
132
+ const DIEAbbrevData *Desc = Attr.Desc ;
133
+
134
+ // TODO: Add support for types.
135
+
136
+ // Add the letter A to the hash.
137
+ addULEB128 (' A' );
138
+
139
+ // Then the attribute code and form.
140
+ addULEB128 (Desc->getAttribute ());
141
+ addULEB128 (Desc->getForm ());
142
+
143
+ // TODO: Add support for additional forms.
144
+ switch (Desc->getForm ()) {
145
+ case dwarf::DW_FORM_strp:
146
+ addString (cast<DIEString>(Value)->getString ());
147
+ break ;
148
+ }
149
+ }
150
+
151
+ // Go through the attributes from \param Attrs in the order specified in 7.27.4
152
+ // and hash them.
153
+ void DIEHash::hashAttributes (DIEAttrs Attrs) {
154
+ #define ADD_ATTR (ATTR ) \
155
+ { \
156
+ if (ATTR.Val != 0 ) \
157
+ hashAttribute (ATTR); \
158
+ }
159
+
160
+ // FIXME: Add the rest.
161
+ ADD_ATTR (Attrs.DW_AT_name );
162
+ }
163
+
164
+ // Add all of the attributes for \param Die to the hash.
165
+ void DIEHash::addAttributes (DIE *Die) {
166
+ DIEAttrs Attrs;
167
+ memset (&Attrs, 0 , sizeof (Attrs));
168
+ collectAttributes (Die, Attrs);
169
+ hashAttributes (Attrs);
170
+ }
171
+
172
+ // Compute the hash of a DIE. This is based on the type signature computation
173
+ // given in section 7.27 of the DWARF4 standard. It is the md5 hash of a
174
+ // flattened description of the DIE.
175
+ void DIEHash::computeHash (DIE *Die) {
176
+
177
+ // Append the letter 'D', followed by the DWARF tag of the DIE.
178
+ addULEB128 (' D' );
179
+ addULEB128 (Die->getTag ());
180
+
181
+ // Add each of the attributes of the DIE.
182
+ addAttributes (Die);
183
+
184
+ // Then hash each of the children of the DIE.
185
+ for (std::vector<DIE *>::const_iterator I = Die->getChildren ().begin (),
186
+ E = Die->getChildren ().end ();
187
+ I != E; ++I)
188
+ computeHash (*I);
189
+ }
190
+
105
191
// / This is based on the type signature computation given in section 7.27 of the
106
192
// / DWARF4 standard. It is the md5 hash of a flattened description of the DIE
107
193
// / 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) {
134
220
// appropriately.
135
221
return *reinterpret_cast <support::ulittle64_t *>(Result + 8 );
136
222
}
223
+
224
+ // / This is based on the type signature computation given in section 7.27 of the
225
+ // / DWARF4 standard. It is an md5 hash of the flattened description of the DIE
226
+ // / with the inclusion of the full CU and all top level CU entities.
227
+ uint64_t DIEHash::computeCUSignature (DIE *Die) {
228
+
229
+ // Hash the DIE.
230
+ computeHash (Die);
231
+
232
+ // Now return the result.
233
+ MD5::MD5Result Result;
234
+ Hash.final (Result);
235
+
236
+ // ... take the least significant 8 bytes and return those. Our MD5
237
+ // implementation always returns its results in little endian, swap bytes
238
+ // appropriately.
239
+ return *reinterpret_cast <support::ulittle64_t *>(Result + 8 );
240
+ }
0 commit comments