1 //===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/DIE.h" 11 #include "../lib/CodeGen/AsmPrinter/DIEHash.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/CodeGen/DwarfStringPoolEntry.h" 14 #include "llvm/Support/Debug.h" 15 #include "llvm/Support/Dwarf.h" 16 #include "llvm/Support/Format.h" 17 #include "gtest/gtest.h" 18 19 using namespace llvm; 20 21 namespace { 22 23 // Test fixture 24 class DIEHashTest : public testing::Test { 25 StringMap<DwarfStringPoolEntry> Pool; 26 27 public: 28 DIEString getString(StringRef S) { 29 DwarfStringPoolEntry Entry = {nullptr, 1, 1}; 30 return DIEString( 31 DwarfStringPoolEntryRef(*Pool.insert(std::make_pair(S, Entry)).first)); 32 } 33 }; 34 35 TEST_F(DIEHashTest, Data1) { 36 DIEHash Hash; 37 DIE Die(dwarf::DW_TAG_base_type); 38 DIEInteger Size(4); 39 Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size); 40 uint64_t MD5Res = Hash.computeTypeSignature(Die); 41 ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res); 42 } 43 44 // struct {}; 45 TEST_F(DIEHashTest, TrivialType) { 46 DIE Unnamed(dwarf::DW_TAG_structure_type); 47 DIEInteger One(1); 48 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 49 50 // Line and file number are ignored. 51 Unnamed.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 52 Unnamed.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One); 53 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); 54 55 // The exact same hash GCC produces for this DIE. 56 ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res); 57 } 58 59 // struct foo { }; 60 TEST_F(DIEHashTest, NamedType) { 61 DIE Foo(dwarf::DW_TAG_structure_type); 62 DIEInteger One(1); 63 DIEString FooStr = getString("foo"); 64 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 65 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 66 67 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 68 69 // The exact same hash GCC produces for this DIE. 70 ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res); 71 } 72 73 // namespace space { struct foo { }; } 74 TEST_F(DIEHashTest, NamespacedType) { 75 DIE CU(dwarf::DW_TAG_compile_unit); 76 77 auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace); 78 DIEInteger One(1); 79 DIEString SpaceStr = getString("space"); 80 Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr); 81 // DW_AT_declaration is ignored. 82 Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 83 // sibling? 84 85 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type); 86 DIEString FooStr = getString("foo"); 87 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 88 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 89 90 DIE &N = *Foo; 91 Space->addChild(std::move(Foo)); 92 CU.addChild(std::move(Space)); 93 94 uint64_t MD5Res = DIEHash().computeTypeSignature(N); 95 96 // The exact same hash GCC produces for this DIE. 97 ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res); 98 } 99 100 // struct { int member; }; 101 TEST_F(DIEHashTest, TypeWithMember) { 102 DIE Unnamed(dwarf::DW_TAG_structure_type); 103 DIEInteger Four(4); 104 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four); 105 106 DIE Int(dwarf::DW_TAG_base_type); 107 DIEString IntStr = getString("int"); 108 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr); 109 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four); 110 DIEInteger Five(5); 111 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five); 112 113 DIEEntry IntRef(Int); 114 115 auto Member = make_unique<DIE>(dwarf::DW_TAG_member); 116 DIEString MemberStr = getString("member"); 117 Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr); 118 DIEInteger Zero(0); 119 Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 120 Zero); 121 Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef); 122 123 Unnamed.addChild(std::move(Member)); 124 125 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); 126 127 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res); 128 } 129 130 // struct foo { int mem1, mem2; }; 131 TEST_F(DIEHashTest, ReusedType) { 132 DIE Unnamed(dwarf::DW_TAG_structure_type); 133 DIEInteger Eight(8); 134 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 135 136 DIEInteger Four(4); 137 DIE Int(dwarf::DW_TAG_base_type); 138 DIEString IntStr = getString("int"); 139 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr); 140 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four); 141 DIEInteger Five(5); 142 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five); 143 144 DIEEntry IntRef(Int); 145 146 auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member); 147 DIEString Mem1Str = getString("mem1"); 148 Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str); 149 DIEInteger Zero(0); 150 Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 151 Zero); 152 Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef); 153 154 Unnamed.addChild(std::move(Mem1)); 155 156 auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member); 157 DIEString Mem2Str = getString("mem2"); 158 Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str); 159 Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 160 Four); 161 Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef); 162 163 Unnamed.addChild(std::move(Mem2)); 164 165 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); 166 167 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res); 168 } 169 170 // struct foo { static foo f; }; 171 TEST_F(DIEHashTest, RecursiveType) { 172 DIE Foo(dwarf::DW_TAG_structure_type); 173 DIEInteger One(1); 174 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 175 DIEString FooStr = getString("foo"); 176 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 177 178 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 179 DIEString MemStr = getString("mem"); 180 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 181 DIEEntry FooRef(Foo); 182 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef); 183 // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them. 184 185 Foo.addChild(std::move(Mem)); 186 187 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 188 189 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res); 190 } 191 192 // struct foo { foo *mem; }; 193 TEST_F(DIEHashTest, Pointer) { 194 DIE Foo(dwarf::DW_TAG_structure_type); 195 DIEInteger Eight(8); 196 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 197 DIEString FooStr = getString("foo"); 198 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 199 200 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 201 DIEString MemStr = getString("mem"); 202 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 203 DIEInteger Zero(0); 204 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero); 205 206 DIE FooPtr(dwarf::DW_TAG_pointer_type); 207 FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 208 DIEEntry FooRef(Foo); 209 FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef); 210 211 DIEEntry FooPtrRef(FooPtr); 212 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooPtrRef); 213 214 Foo.addChild(std::move(Mem)); 215 216 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 217 218 ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res); 219 } 220 221 // struct foo { foo &mem; }; 222 TEST_F(DIEHashTest, Reference) { 223 DIE Foo(dwarf::DW_TAG_structure_type); 224 DIEInteger Eight(8); 225 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 226 DIEString FooStr = getString("foo"); 227 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 228 229 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 230 DIEString MemStr = getString("mem"); 231 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 232 DIEInteger Zero(0); 233 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero); 234 235 DIE FooRef(dwarf::DW_TAG_reference_type); 236 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 237 DIEEntry FooEntry(Foo); 238 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry); 239 240 DIE FooRefConst(dwarf::DW_TAG_const_type); 241 DIEEntry FooRefRef(FooRef); 242 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef); 243 244 DIEEntry FooRefConstRef(FooRefConst); 245 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef); 246 247 Foo.addChild(std::move(Mem)); 248 249 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 250 251 ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res); 252 } 253 254 // struct foo { foo &&mem; }; 255 TEST_F(DIEHashTest, RValueReference) { 256 DIE Foo(dwarf::DW_TAG_structure_type); 257 DIEInteger Eight(8); 258 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 259 DIEString FooStr = getString("foo"); 260 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 261 262 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 263 DIEString MemStr = getString("mem"); 264 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 265 DIEInteger Zero(0); 266 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero); 267 268 DIE FooRef(dwarf::DW_TAG_rvalue_reference_type); 269 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 270 DIEEntry FooEntry(Foo); 271 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry); 272 273 DIE FooRefConst(dwarf::DW_TAG_const_type); 274 DIEEntry FooRefRef(FooRef); 275 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef); 276 277 DIEEntry FooRefConstRef(FooRefConst); 278 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef); 279 280 Foo.addChild(std::move(Mem)); 281 282 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 283 284 ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res); 285 } 286 287 // struct foo { foo foo::*mem; }; 288 TEST_F(DIEHashTest, PtrToMember) { 289 DIE Foo(dwarf::DW_TAG_structure_type); 290 DIEInteger Eight(8); 291 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 292 DIEString FooStr = getString("foo"); 293 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 294 295 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 296 DIEString MemStr = getString("mem"); 297 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 298 DIEInteger Zero(0); 299 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero); 300 301 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type); 302 DIEEntry FooEntry(Foo); 303 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry); 304 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 305 FooEntry); 306 307 DIEEntry PtrToFooMemRef(PtrToFooMem); 308 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef); 309 310 Foo.addChild(std::move(Mem)); 311 312 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 313 314 ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res); 315 } 316 317 // Check that the hash for a pointer-to-member matches regardless of whether the 318 // pointed-to type is a declaration or a definition. 319 // 320 // struct bar; // { }; 321 // struct foo { bar foo::*mem; }; 322 TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) { 323 DIEInteger Zero(0); 324 DIEInteger One(1); 325 DIEInteger Eight(8); 326 DIEString FooStr = getString("foo"); 327 DIEString BarStr = getString("bar"); 328 DIEString MemStr = getString("mem"); 329 uint64_t MD5ResDecl; 330 { 331 DIE Bar(dwarf::DW_TAG_structure_type); 332 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr); 333 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 334 335 DIE Foo(dwarf::DW_TAG_structure_type); 336 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 337 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 338 339 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 340 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 341 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 342 Zero); 343 344 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type); 345 DIEEntry BarEntry(Bar); 346 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry); 347 DIEEntry FooEntry(Foo); 348 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 349 FooEntry); 350 351 DIEEntry PtrToFooMemRef(PtrToFooMem); 352 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef); 353 354 Foo.addChild(std::move(Mem)); 355 356 MD5ResDecl = DIEHash().computeTypeSignature(Foo); 357 } 358 uint64_t MD5ResDef; 359 { 360 DIE Bar(dwarf::DW_TAG_structure_type); 361 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr); 362 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 363 364 DIE Foo(dwarf::DW_TAG_structure_type); 365 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 366 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 367 368 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 369 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 370 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 371 Zero); 372 373 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type); 374 DIEEntry BarEntry(Bar); 375 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry); 376 DIEEntry FooEntry(Foo); 377 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 378 FooEntry); 379 380 DIEEntry PtrToFooMemRef(PtrToFooMem); 381 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef); 382 383 Foo.addChild(std::move(Mem)); 384 385 MD5ResDef = DIEHash().computeTypeSignature(Foo); 386 } 387 ASSERT_EQ(MD5ResDef, MD5ResDecl); 388 } 389 390 // Check that the hash for a pointer-to-member matches regardless of whether the 391 // pointed-to type is a declaration or a definition. 392 // 393 // struct bar; // { }; 394 // struct foo { bar bar::*mem; }; 395 TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) { 396 DIEInteger Zero(0); 397 DIEInteger One(1); 398 DIEInteger Eight(8); 399 DIEString FooStr = getString("foo"); 400 DIEString BarStr = getString("bar"); 401 DIEString MemStr = getString("mem"); 402 uint64_t MD5ResDecl; 403 { 404 DIE Bar(dwarf::DW_TAG_structure_type); 405 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr); 406 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 407 408 DIE Foo(dwarf::DW_TAG_structure_type); 409 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 410 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 411 412 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 413 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 414 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 415 Zero); 416 417 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type); 418 DIEEntry BarEntry(Bar); 419 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry); 420 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 421 BarEntry); 422 423 DIEEntry PtrToFooMemRef(PtrToFooMem); 424 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef); 425 426 Foo.addChild(std::move(Mem)); 427 428 MD5ResDecl = DIEHash().computeTypeSignature(Foo); 429 } 430 uint64_t MD5ResDef; 431 { 432 DIE Bar(dwarf::DW_TAG_structure_type); 433 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr); 434 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 435 436 DIE Foo(dwarf::DW_TAG_structure_type); 437 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 438 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 439 440 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 441 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 442 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, 443 Zero); 444 445 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type); 446 DIEEntry BarEntry(Bar); 447 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry); 448 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 449 BarEntry); 450 451 DIEEntry PtrToFooMemRef(PtrToFooMem); 452 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef); 453 454 Foo.addChild(std::move(Mem)); 455 456 MD5ResDef = DIEHash().computeTypeSignature(Foo); 457 } 458 // FIXME: This seems to be a bug in the DWARF type hashing specification that 459 // only uses the brief name hashing for types referenced via DW_AT_type. In 460 // this case the type is referenced via DW_AT_containing_type and full hashing 461 // causes a hash to differ when the containing type is a declaration in one TU 462 // and a definition in another. 463 ASSERT_NE(MD5ResDef, MD5ResDecl); 464 } 465 466 // struct { } a; 467 // struct foo { decltype(a) mem; }; 468 TEST_F(DIEHashTest, RefUnnamedType) { 469 DIEInteger Zero(0); 470 DIEInteger One(1); 471 DIEInteger Eight(8); 472 DIEString FooStr = getString("foo"); 473 DIEString MemStr = getString("mem"); 474 475 DIE Unnamed(dwarf::DW_TAG_structure_type); 476 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 477 478 DIE Foo(dwarf::DW_TAG_structure_type); 479 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 480 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 481 482 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member); 483 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr); 484 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero); 485 486 DIE UnnamedPtr(dwarf::DW_TAG_pointer_type); 487 UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight); 488 DIEEntry UnnamedRef(Unnamed); 489 UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedRef); 490 491 DIEEntry UnnamedPtrRef(UnnamedPtr); 492 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedPtrRef); 493 494 Foo.addChild(std::move(Mem)); 495 496 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo); 497 498 ASSERT_EQ(0x954e026f01c02529ULL, MD5Res); 499 } 500 501 // struct { struct foo { }; }; 502 TEST_F(DIEHashTest, NestedType) { 503 DIE Unnamed(dwarf::DW_TAG_structure_type); 504 DIEInteger One(1); 505 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 506 507 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type); 508 DIEString FooStr = getString("foo"); 509 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr); 510 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 511 512 Unnamed.addChild(std::move(Foo)); 513 514 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); 515 516 // The exact same hash GCC produces for this DIE. 517 ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res); 518 } 519 520 // struct { static void func(); }; 521 TEST_F(DIEHashTest, MemberFunc) { 522 DIE Unnamed(dwarf::DW_TAG_structure_type); 523 DIEInteger One(1); 524 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 525 526 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram); 527 DIEString FuncStr = getString("func"); 528 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr); 529 530 Unnamed.addChild(std::move(Func)); 531 532 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed); 533 534 // The exact same hash GCC produces for this DIE. 535 ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res); 536 } 537 538 // struct A { 539 // static void func(); 540 // }; 541 TEST_F(DIEHashTest, MemberFuncFlag) { 542 DIE A(dwarf::DW_TAG_structure_type); 543 DIEInteger One(1); 544 DIEString AStr = getString("A"); 545 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr); 546 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 547 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 548 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One); 549 550 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram); 551 DIEString FuncStr = getString("func"); 552 DIEString FuncLinkage = getString("_ZN1A4funcEv"); 553 DIEInteger Two(2); 554 Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One); 555 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr); 556 Func->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 557 Func->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two); 558 Func->addValue(dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, FuncLinkage); 559 Func->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 560 561 A.addChild(std::move(Func)); 562 563 uint64_t MD5Res = DIEHash().computeTypeSignature(A); 564 565 // The exact same hash GCC produces for this DIE. 566 ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res); 567 } 568 569 // Derived from: 570 // struct A { 571 // const static int PI = -3; 572 // }; 573 // A a; 574 TEST_F(DIEHashTest, MemberSdata) { 575 DIE A(dwarf::DW_TAG_structure_type); 576 DIEInteger One(1); 577 DIEString AStr = getString("A"); 578 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr); 579 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 580 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 581 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One); 582 583 DIEInteger Four(4); 584 DIEInteger Five(5); 585 DIEString FStr = getString("int"); 586 DIE IntTyDIE(dwarf::DW_TAG_base_type); 587 IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four); 588 IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five); 589 IntTyDIE.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr); 590 591 DIEEntry IntTy(IntTyDIE); 592 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type); 593 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy); 594 595 DIEEntry PITy(*PITyDIE); 596 auto PI = make_unique<DIE>(dwarf::DW_TAG_member); 597 DIEString PIStr = getString("PI"); 598 DIEInteger Two(2); 599 DIEInteger NegThree(-3); 600 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr); 601 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 602 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two); 603 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy); 604 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One); 605 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 606 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, NegThree); 607 608 A.addChild(std::move(PI)); 609 610 uint64_t MD5Res = DIEHash().computeTypeSignature(A); 611 ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res); 612 } 613 614 // Derived from: 615 // struct A { 616 // const static float PI = 3.14; 617 // }; 618 // A a; 619 TEST_F(DIEHashTest, MemberBlock) { 620 DIE A(dwarf::DW_TAG_structure_type); 621 DIEInteger One(1); 622 DIEString AStr = getString("A"); 623 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr); 624 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One); 625 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 626 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One); 627 628 DIEInteger Four(4); 629 DIEString FStr = getString("float"); 630 auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type); 631 FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four); 632 FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Four); 633 FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr); 634 635 DIEEntry FloatTy(*FloatTyDIE); 636 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type); 637 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy); 638 639 DIEEntry PITy(*PITyDIE); 640 auto PI = make_unique<DIE>(dwarf::DW_TAG_member); 641 DIEString PIStr = getString("PI"); 642 DIEInteger Two(2); 643 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr); 644 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One); 645 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two); 646 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy); 647 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One); 648 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One); 649 650 DIEBlock PIBlock; 651 DIEInteger Blk1(0xc3); 652 DIEInteger Blk2(0xf5); 653 DIEInteger Blk3(0x48); 654 DIEInteger Blk4(0x40); 655 656 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk1); 657 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk2); 658 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk3); 659 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk4); 660 661 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock); 662 663 A.addChild(std::move(PI)); 664 665 uint64_t MD5Res = DIEHash().computeTypeSignature(A); 666 ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res); 667 } 668 } 669