* [committed 5/13][odr] Construct maximal duplicate chains
@ 2020-01-01 0:00 Tom de Vries
0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2020-01-01 0:00 UTC (permalink / raw)
To: dwz, jakub
Hi,
Make sure structs with the same name end up in the same duplicate chain.
Likewise for class and union.
Committed to trunk.
Thanks,
- Tom
[odr] Construct maximal duplicate chains
2020-01-06 Tom de Vries <tdevries@suse.de>
* dwz.c (checksum_die, checksum_ref_die): Make checksum the same for
structs with the same name. Likewise for class and union.
(die_eq_1): Return 1 for structs with the same name. Likewise for
class and union.
---
dwz.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/dwz.c b/dwz.c
index c82f5c9..dab11ad 100644
--- a/dwz.c
+++ b/dwz.c
@@ -2462,6 +2462,8 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
unsigned int i;
unsigned char *ptr;
dw_die_ref child;
+ bool only_hash_name_p;
+ hashval_t die_hash2;
switch (die->die_ck_state)
{
@@ -2487,6 +2489,10 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
read_uleb128 (ptr);
s = die->die_tag;
die->u.p1.die_hash = iterative_hash_object (s, die->u.p1.die_hash);
+ only_hash_name_p = odr && die_odr_state (die_cu (die), die) != ODR_NONE;
+ die_hash2 = 0;
+ if (only_hash_name_p)
+ die_hash2 = die->u.p1.die_hash;
for (i = 0; i < t->nattr; ++i)
{
uint32_t form = t->attr[i].form;
@@ -2786,10 +2792,26 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
}
}
else
- ptr += 4;
+ {
+ ptr += 4;
+ if (only_hash_name_p && t->attr[i].attr == DW_AT_name)
+ {
+ s = t->attr[i].attr;
+ die_hash2 = iterative_hash_object (s, die_hash2);
+ die_hash2
+ = iterative_hash (old_ptr, ptr - old_ptr, die_hash2);
+ }
+ }
break;
case DW_FORM_string:
ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1;
+ if (only_hash_name_p && t->attr[i].attr == DW_AT_name)
+ {
+ s = t->attr[i].attr;
+ die_hash2 = iterative_hash_object (s, die_hash2);
+ die_hash2
+ = iterative_hash (old_ptr, ptr - old_ptr, die_hash2);
+ }
break;
case DW_FORM_indirect:
abort ();
@@ -2901,6 +2923,9 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die)
if (die->die_ck_state == CK_BEING_COMPUTED)
die->die_ck_state = CK_KNOWN;
+ if (only_hash_name_p)
+ die->u.p1.die_hash = die_hash2;
+
return 0;
}
@@ -3006,6 +3031,7 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
unsigned int i, ret = 0;
unsigned char *ptr;
dw_die_ref child;
+ bool only_hash_name_p;
if (top_die == die)
{
@@ -3036,6 +3062,7 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
else
assert (top_die == NULL || die->die_ck_state == CK_KNOWN);
t = die->die_abbrev;
+ only_hash_name_p = odr && die_odr_state (die_cu (die), die) != ODR_NONE;
for (i = 0; i < t->nattr; ++i)
if (t->attr[i].attr != DW_AT_sibling)
switch (t->attr[i].form)
@@ -3214,7 +3241,8 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
}
}
- if (top_die == NULL || top_die->die_ck_state != CK_BAD)
+ if (!only_hash_name_p
+ && (top_die == NULL || top_die->die_ck_state != CK_BAD))
for (child = die->die_child; child; child = child->die_sib)
{
unsigned int r
@@ -3568,6 +3596,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
unsigned char *ptr1, *ptr2;
dw_die_ref ref1, ref2;
dw_die_ref child1, child2;
+ bool only_compare_name_p;
#define FAIL goto fail
if (die1 == die2 || die_safe_dup (die2) == die1)
@@ -3575,8 +3604,8 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
if (die1->u.p1.die_hash != die2->u.p1.die_hash
|| die1->u.p1.die_ref_hash != die2->u.p1.die_ref_hash
|| die1->die_tag != die2->die_tag
- || die1->u.p1.die_exit - die1->u.p1.die_enter
- != die2->u.p1.die_exit - die2->u.p1.die_enter
+ || (!odr && (die1->u.p1.die_exit - die1->u.p1.die_enter
+ != die2->u.p1.die_exit - die2->u.p1.die_enter))
|| die_safe_dup (die2) != NULL
|| die1->die_ck_state != CK_KNOWN
|| die2->die_ck_state != CK_KNOWN
@@ -3584,6 +3613,23 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
return 0;
assert (!die1->die_root && !die2->die_root);
+ only_compare_name_p
+ = odr && die1->die_odr_state != ODR_NONE && die2->die_odr_state != ODR_NONE;
+
+ if (only_compare_name_p)
+ {
+ const char *name1 = get_AT_string (die1, DW_AT_name);
+ const char *name2 = get_AT_string (die2, DW_AT_name);
+ // TODO: Handle DW_AT_linkage_name?
+ if (name1 == NULL || name2 == NULL)
+ return 0;
+ if (strcmp (name1, name2) != 0)
+ return 0;
+ }
+ else if (die1->u.p1.die_exit - die1->u.p1.die_enter
+ != die2->u.p1.die_exit - die2->u.p1.die_enter)
+ return 0;
+
t1 = die1->die_abbrev;
t2 = die2->die_abbrev;
if (likely (!fi_multifile))
@@ -3656,6 +3702,10 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
}
die1->die_nextdup = die2;
}
+
+ if (only_compare_name_p)
+ return 1;
+
while (1)
{
uint32_t form1, form2;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-01-06 16:07 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-01 0:00 [committed 5/13][odr] Construct maximal duplicate chains Tom de Vries
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).