[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[committed] Fix missing partial unit import



Hi,

In a hello generated on openSUSE Leap 15.0, long double is defined:
...
$ gdb hello -ex "info types" -batch | egrep "long double|^File" \
    | grep -B1 "long double"
File elf-init.c:
        typedef long double;
...

But if we self-dwz-m it, it's gone:
...
$ cp hello.copy
$ dwz -m hello.alt hello hello.copy
$ gdb hello -ex "info types" -batch | egrep "long double|^File" \
    | grep -B1 "long double"
...

The long double type is part of a partial unit at 2b5, which is not imported
by any DW_AT_import.

This happens as follows: the partial unit at 2b5 in the multifile contains as
first die:
...
 <1><2be>: Abbrev Number: 5 (DW_TAG_const_type)
    <2bf>   DW_AT_type        : <0x4c>
...
which refers to:
...
 <1><4c>: Abbrev Number: 18 (DW_TAG_typedef)
    <4d>   DW_AT_name        : (indirect string, offset: 0x54c): size_t
    <51>   DW_AT_decl_file   : 1
    <52>   DW_AT_decl_line   : 216
    <53>   DW_AT_type        : <0x344>
...
in another partial unit in the multifile.

When matching dies in the input file against the dies in the multifile during
finalize_multifile, we compare 2be to 394:
...
 <1><389>: Abbrev Number: 24 (DW_TAG_typedef)
    <38a>   DW_AT_name        : (indirect string, offset: 0x226): size_t
    <38e>   DW_AT_decl_file   : 2
    <38f>   DW_AT_decl_line   : 216
    <390>   DW_AT_type        : <0x14>
 <1><394>: Abbrev Number: 7 (DW_TAG_const_type)
    <395>   DW_AT_type        : <0x389>
...
which then fails because of a mismatch in DW_FORM (DW_FORM_ref_addr vs
DW_FORM_ref_udata).

Subsequently, we hit this in create_import_tree:
...
      if (unlikely (fi_multifile) && rdie->die_nextdup == NULL)
        {
          pu->u1.cu_icu = NULL;
          continue;
        }
...
and skip generating an import for the partial unit due to 2be not having a duplicate.

Fix this by allowing DW_FORM mismatch in die_eq_1 during fi_multifile.

Committed to trunk.

Thanks,
- Tom

Fix missing partial unit import

2019-04-23  Tom de Vries  <tdevries@suse.de>

	PR dwz/24468
	* dwz.c (die_eq_1): Compare references with unequal DW_FORM in
	fi_multifile mode.

---
 dwz.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dwz.c b/dwz.c
index c67fa9d..db5ee10 100644
--- a/dwz.c
+++ b/dwz.c
@@ -3161,7 +3161,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
       switch (form1)
 	{
 	case DW_FORM_ref_addr:
-	  if (likely (!op_multifile && !rd_multifile))
+	  if (likely (!op_multifile && !rd_multifile && !fi_multifile))
 	    {
 	      if (form1 != form2)
 		FAIL;
@@ -3176,7 +3176,7 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2,
 	  switch (form2)
 	    {
 	    case DW_FORM_ref_addr:
-	      if (likely (!op_multifile && !rd_multifile))
+	      if (likely (!op_multifile && !rd_multifile && !fi_multifile))
 		FAIL;
 	      break;
 	    case DW_FORM_ref_udata: