DIEHashTest.cpp 26 KB

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