public inbox for dwz@sourceware.org
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: dwz@sourceware.org, jakub@redhat.com
Subject: [committed 5/13][odr] Construct maximal duplicate chains
Date: Wed, 01 Jan 2020 00:00:00 -0000	[thread overview]
Message-ID: <20200106160731.GA19925@delia> (raw)

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;

                 reply	other threads:[~2020-01-06 16:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200106160731.GA19925@delia \
    --to=tdevries@suse.de \
    --cc=dwz@sourceware.org \
    --cc=jakub@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).