llvm.org GIT mirror llvm / 3baa3c3
DWARF type hashing: Handle multiple (including recursive) references to the same type This uses a map, keeping the type DIE numbering separate from the DIEs themselves - alternatively we could do things the way GCC does if we want to add an integer to the DIE type to record the numbering there. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193105 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 7 years ago
3 changed file(s) with 80 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
195195 // 7.27s3
196196 // ... An attribute that refers to another type entry T is processed as
197197 // follows:
198 // a) If T is in the list of [previously hashed types], use the letter 'R' as
199 // the marker and use the unsigned LEB128 encoding of [the index of T in the
200 // list] as the attribute value; otherwise,
201
202 // [TODO: implement clause (a)]
203
204198 if (const DIEEntry *EntryAttr = dyn_cast(Value)) {
205199 DIE *Entry = EntryAttr->getEntry();
206
207 // b) use the letter 'T' as a the marker, ...
200 unsigned &DieNumber = Numbering[Entry];
201 if (DieNumber) {
202 // a) If T is in the list of [previously hashed types], use the letter
203 // 'R' as the marker
204 addULEB128('R');
205
206 addULEB128(Desc->getAttribute());
207
208 // and use the unsigned LEB128 encoding of [the index of T in the
209 // list] as the attribute value;
210 addULEB128(DieNumber);
211 return;
212 }
213
214 // otherwise, b) use the letter 'T' as a the marker, ...
208215 addULEB128('T');
209216
210217 addULEB128(Desc->getAttribute());
211218
212219 // ... process the type T recursively by performing Steps 2 through 7, and
213220 // use the result as the attribute value.
221 DieNumber = Numbering.size();
214222 computeHash(Entry);
215223 return;
216224 }
320328 // given in section 7.27 of the DWARF4 standard. It is the md5 hash of a
321329 // flattened description of the DIE.
322330 void DIEHash::computeHash(DIE *Die) {
323
324331 // Append the letter 'D', followed by the DWARF tag of the DIE.
325332 addULEB128('D');
326333 addULEB128(Die->getTag());
376383 /// with the inclusion of the full CU and all top level CU entities.
377384 // TODO: Initialize the type chain at 0 instead of 1 for CU signatures.
378385 uint64_t DIEHash::computeCUSignature(DIE *Die) {
386 Numbering.clear();
387 Numbering[Die] = 1;
379388
380389 // Hash the DIE.
381390 computeHash(Die);
395404 /// with the inclusion of additional forms not specifically called out in the
396405 /// standard.
397406 uint64_t DIEHash::computeTypeSignature(DIE *Die) {
407 Numbering.clear();
408 Numbering[Die] = 1;
398409
399410 if (DIE *Parent = Die->getParent())
400411 addParentContext(Parent);
1010 //
1111 //===----------------------------------------------------------------------===//
1212
13 #include "llvm/ADT/DenseMap.h"
1314 #include "llvm/Support/MD5.h"
1415
1516 namespace llvm {
124125
125126 private:
126127 MD5 Hash;
128 DenseMap Numbering;
127129 };
128130 }
9191 DIE *Member = new DIE(dwarf::DW_TAG_member);
9292 DIEString MemberStr(&Four, "member");
9393 Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
94 // type
9594 DIEInteger Zero(0);
9695 Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
9796
111110
112111 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
113112 }
113
114 TEST(ReusedType, DIEHash) {
115 DIE Unnamed(dwarf::DW_TAG_structure_type);
116 DIEInteger Eight(8);
117 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
118
119 DIE *Mem1 = new DIE(dwarf::DW_TAG_member);
120 DIEInteger Four(4);
121 DIEString Mem1Str(&Four, "mem1");
122 Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
123 DIEInteger Zero(0);
124 Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
125
126 Unnamed.addChild(Mem1);
127
128 DIE *Mem2 = new DIE(dwarf::DW_TAG_member);
129 DIEString Mem2Str(&Four, "mem2");
130 Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
131 Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Four);
132
133 Unnamed.addChild(Mem2);
134
135 DIE Int(dwarf::DW_TAG_base_type);
136 DIEString IntStr(&Four, "int");
137 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
138 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
139 DIEInteger Five(5);
140 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
141
142 DIEEntry IntRef(&Int);
143 Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
144 Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
145
146 uint64_t MD5Res = DIEHash().computeTypeSignature(&Unnamed);
147
148 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
114149 }
150
151 TEST(RecursiveType, DIEHash) {
152 DIE Foo(dwarf::DW_TAG_structure_type);
153 DIEInteger One(1);
154 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
155 DIEString FooStr(&One, "foo");
156 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
157
158 DIE *Mem = new DIE(dwarf::DW_TAG_member);
159 DIEString MemStr(&One, "mem");
160 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
161 DIEEntry FooRef(&Foo);
162 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
163 // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
164
165 Foo.addChild(Mem);
166
167 uint64_t MD5Res = DIEHash().computeTypeSignature(&Foo);
168
169 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
170 }
171 }