mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 23:48:56 +00:00
DWARF type hashing: begin implementing Step 5, summary hashing in declarable contexts
There are several other tag types that need similar handling but to ensure test coverage they'll be coming incrementally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193126 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
65d60c8468
commit
f1545a2197
@ -189,15 +189,47 @@ void DIEHash::collectAttributes(DIE *Die, DIEAttrs &Attrs) {
|
||||
|
||||
// Hash an individual attribute \param Attr based on the type of attribute and
|
||||
// the form.
|
||||
void DIEHash::hashAttribute(AttrEntry Attr) {
|
||||
void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
|
||||
const DIEValue *Value = Attr.Val;
|
||||
const DIEAbbrevData *Desc = Attr.Desc;
|
||||
|
||||
// 7.27s3
|
||||
// 7.27 Step 3
|
||||
// ... An attribute that refers to another type entry T is processed as
|
||||
// follows:
|
||||
if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) {
|
||||
DIE *Entry = EntryAttr->getEntry();
|
||||
|
||||
// Step 5
|
||||
// If the tag in Step 3 is one of ...
|
||||
if (Tag == dwarf::DW_TAG_pointer_type) {
|
||||
// ... and the referenced type (via the DW_AT_type or DW_AT_friend
|
||||
// attribute) ...
|
||||
assert(Desc->getAttribute() == dwarf::DW_AT_type ||
|
||||
Desc->getAttribute() == dwarf::DW_AT_friend);
|
||||
// [FIXME] ... has a DW_AT_name attribute,
|
||||
// append the letter 'N'
|
||||
addULEB128('N');
|
||||
|
||||
// the DWARF attribute code (DW_AT_type or DW_AT_friend),
|
||||
addULEB128(Desc->getAttribute());
|
||||
|
||||
// the context of the tag,
|
||||
if (DIE *Parent = Entry->getParent())
|
||||
addParentContext(Parent);
|
||||
|
||||
// the letter 'E',
|
||||
addULEB128('E');
|
||||
|
||||
// and the name of the type.
|
||||
addString(getDIEStringAttr(Entry, dwarf::DW_AT_name));
|
||||
|
||||
// FIXME:
|
||||
// For DW_TAG_friend, if the referenced entry is the DW_TAG_subprogram,
|
||||
// the context is omitted and the name to be used is the ABI-specific name
|
||||
// of the subprogram (e.g., the mangled linker name).
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned &DieNumber = Numbering[Entry];
|
||||
if (DieNumber) {
|
||||
// a) If T is in the list of [previously hashed types], use the letter
|
||||
@ -258,11 +290,11 @@ void DIEHash::hashAttribute(AttrEntry Attr) {
|
||||
|
||||
// Go through the attributes from \param Attrs in the order specified in 7.27.4
|
||||
// and hash them.
|
||||
void DIEHash::hashAttributes(const DIEAttrs &Attrs) {
|
||||
void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) {
|
||||
#define ADD_ATTR(ATTR) \
|
||||
{ \
|
||||
if (ATTR.Val != 0) \
|
||||
hashAttribute(ATTR); \
|
||||
hashAttribute(ATTR, Tag); \
|
||||
}
|
||||
|
||||
ADD_ATTR(Attrs.DW_AT_name);
|
||||
@ -322,7 +354,7 @@ void DIEHash::hashAttributes(const DIEAttrs &Attrs) {
|
||||
void DIEHash::addAttributes(DIE *Die) {
|
||||
DIEAttrs Attrs = {};
|
||||
collectAttributes(Die, Attrs);
|
||||
hashAttributes(Attrs);
|
||||
hashAttributes(Attrs, Die->getTag());
|
||||
}
|
||||
|
||||
// Compute the hash of a DIE. This is based on the type signature computation
|
||||
|
@ -119,10 +119,10 @@ private:
|
||||
void collectAttributes(DIE *Die, DIEAttrs &Attrs);
|
||||
|
||||
/// \brief Hashes the attributes in \param Attrs in order.
|
||||
void hashAttributes(const DIEAttrs &Attrs);
|
||||
void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag);
|
||||
|
||||
/// \brief Hashes an individual attribute.
|
||||
void hashAttribute(AttrEntry Attr);
|
||||
void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
|
||||
|
||||
private:
|
||||
MD5 Hash;
|
||||
|
@ -26,9 +26,8 @@ TEST(DIEHashTest, Data1) {
|
||||
ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct {};
|
||||
TEST(DIEHashTest, TrivialType) {
|
||||
// A complete, but simple, type containing no members and defined on the first
|
||||
// line of a file.
|
||||
DIE Unnamed(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger One(1);
|
||||
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
|
||||
@ -42,9 +41,8 @@ TEST(DIEHashTest, TrivialType) {
|
||||
ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct foo { };
|
||||
TEST(DIEHashTest, NamedType) {
|
||||
// A complete named type containing no members and defined on the first line
|
||||
// of a file.
|
||||
DIE Foo(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger One(1);
|
||||
DIEString FooStr(&One, "foo");
|
||||
@ -57,9 +55,8 @@ TEST(DIEHashTest, NamedType) {
|
||||
ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
|
||||
}
|
||||
|
||||
// namespace space { struct foo { }; }
|
||||
TEST(DIEHashTest, NamespacedType) {
|
||||
// A complete named type containing no members and defined on the first line
|
||||
// of a file.
|
||||
DIE CU(dwarf::DW_TAG_compile_unit);
|
||||
|
||||
DIE *Space = new DIE(dwarf::DW_TAG_namespace);
|
||||
@ -84,6 +81,7 @@ TEST(DIEHashTest, NamespacedType) {
|
||||
ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct { int member; };
|
||||
TEST(DIEHashTest, TypeWithMember) {
|
||||
DIE Unnamed(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger Four(4);
|
||||
@ -112,6 +110,7 @@ TEST(DIEHashTest, TypeWithMember) {
|
||||
ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct foo { int mem1, mem2; };
|
||||
TEST(DIEHashTest, ReusedType) {
|
||||
DIE Unnamed(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger Eight(8);
|
||||
@ -149,6 +148,7 @@ TEST(DIEHashTest, ReusedType) {
|
||||
ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct foo { static foo f; };
|
||||
TEST(DIEHashTest, RecursiveType) {
|
||||
DIE Foo(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger One(1);
|
||||
@ -169,4 +169,33 @@ TEST(DIEHashTest, RecursiveType) {
|
||||
|
||||
ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
|
||||
}
|
||||
|
||||
// struct foo { foo *mem; };
|
||||
TEST(DIEHashTest, Pointer) {
|
||||
DIE Foo(dwarf::DW_TAG_structure_type);
|
||||
DIEInteger Eight(8);
|
||||
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
|
||||
DIEString FooStr(&Eight, "foo");
|
||||
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
|
||||
|
||||
DIE *Mem = new DIE(dwarf::DW_TAG_member);
|
||||
DIEString MemStr(&Eight, "mem");
|
||||
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
|
||||
DIEInteger Zero(0);
|
||||
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
|
||||
|
||||
DIE FooPtr(dwarf::DW_TAG_pointer_type);
|
||||
FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
|
||||
DIEEntry FooRef(&Foo);
|
||||
FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
|
||||
|
||||
DIEEntry FooPtrRef(&FooPtr);
|
||||
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
|
||||
|
||||
Foo.addChild(Mem);
|
||||
|
||||
uint64_t MD5Res = DIEHash().computeTypeSignature(&Foo);
|
||||
|
||||
ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user