[PATCH] Call reorder_dups ASAP

Tom de Vries tdevries@suse.de
Thu Feb 25 14:45:42 GMT 2021


Hi,

Currently, we call reorder_dups just before partial unit creation, and only for
DIEs that will be copied.

This approach causes a problem with reachable DIE propagation (which is done
in partition_dups after phase 1): when a dup-chain that needs to be reordered
(starts with ODR_DECL but also contains ODR_DEF) is marked as reachable during
this propagation, propagation will stop at the ODR_DECL, while it should
continue at the first ODR_DEF instead.

Fix this by calling reorder_dups ASAP, just after computing the partitions.

The problem can be detected using this assert:
...
@@ -12563,6 +12563,8 @@ write_die
 		    {
 		      dw_cu_ref refdcu = die_cu (refd);
 		      value = refd->u.p2.die_new_offset;
+		      assert (IMPLIES (cu->cu_kind == CU_PU,
+				       die_cu (refd)->cu_kind == CU_PU));
 		      assert (value && refdcu->cu_kind != CU_ALT);
 		      if (t->attr[j].form == DW_FORM_ref_addr)
 			{
...

Any comments?

Thanks,
- Tom

Call reorder_dups ASAP

2020-01-25  Tom de Vries  <tdevries@suse.de>

	PR dwz/25424
	* dwz.c (partition_dups_1): Move calling of reorder_dups ...
	(partition_dups): ... here.

---
 dwz.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/dwz.c b/dwz.c
index f435428..9172011 100644
--- a/dwz.c
+++ b/dwz.c
@@ -8134,13 +8134,6 @@ partition_dups_1 (dw_die_ref *arr, size_t nr_partitions, size_t *partitions,
 		 && (ignore_size || orig_size > new_size));
       if (force)
 	{
-	  if (odr_active_p && odr_mode != ODR_BASIC)
-	    for (k = i; k < j; k++)
-	      {
-		if (second_phase && !arr[k]->die_ref_seen)
-		  continue;
-		arr[k] = reorder_dups (arr[k]);
-	      }
 	  dw_die_ref die, *diep;
 	  dw_cu_ref refcu = die_cu (arr[i]);
 	  dw_cu_ref partial_cu = pool_alloc (dw_cu, sizeof (struct dw_cu));
@@ -8474,6 +8467,9 @@ partition_dups (void)
       if (stats_p)
 	stats->part_cnt += nr_partitions;
 
+      if (odr_active_p && odr_mode != ODR_BASIC)
+	for (i = 0; i < vec_size; ++i)
+	  arr[i] = reorder_dups (arr[i]);
       if (partition_dups_1 (arr, nr_partitions, partitions, &first_partial_cu,
 			    &last_partial_cu, false))
 	{


More information about the Dwz mailing list