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