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

[Bug default/24477] New: multifile optimization fails if single-file optimization not beneficial



https://sourceware.org/bugzilla/show_bug.cgi?id=24477

            Bug ID: 24477
           Summary: multifile optimization fails if single-file
                    optimization not beneficial
           Product: dwz
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: default
          Assignee: nobody at sourceware dot org
          Reporter: vries at gcc dot gnu.org
                CC: dwz at sourceware dot org
  Target Milestone: ---

Say we multifile-optimize hello:
...
$ rm -f 3
$ cp hello 1
$ cp 1 2
$ dwz -m 3 1 2
...

We find that the multifile is created, and linked to:
...
$ ls 3
3
$ readelf -S 1  | grep alt
  [32] .gnu_debugaltlink PROGBITS         0000000000000000  00001182
...

What happens in dwz for -m, is that first 1 and 2 are optimized in single-file
mode, and then multifile-mode optimization is done.

However, if we try to factor out the single-file mode optimization in a
separate dwz invocation, we get instead:
...
$ rm -f 3
$ cp hello 1
$ dwz 1
$ cp 1 2
$ ./dwz -m 3 1 2
./dwz: 1: DWARF compression not beneficial - old size 436 new size 436
./dwz: 2: DWARF compression not beneficial - old size 436 new size 436
$ ls 3
ls: cannot access '3': No such file or directory
$ readelf -S 1  | grep alt
$
...

In the "DWARF compression not beneficial" code in dwz () we still make an
effort to do the multifile optimization:
...
         if (multifile && !fi_multifile && !low_mem)
            write_multifile (dso);
...
and we count the dwz() invocation in successcount in main (used to determine
whether there are sufficient files for multifile optimization).

But multifile optimization fails because this triggers (on the first part) in
optimize_multifile:
...
  if (multi_ehdr.e_ident[0] == '\0'
      || multi_ptr_size == 0
      || multi_endian == 0)
    return -1;
...

And multi_ehdr.e_ident[0] is only set in write_dso, which is not triggered.

Tentative fix:
...
diff --git a/dwz.c b/dwz.c
index 2ea7c27..acec90a 100644
--- a/dwz.c
+++ b/dwz.c
@@ -10262,8 +10262,6 @@ write_dso (DSO *dso, const char *file, struct stat *st)

   memset (remove_sections, '\0', sizeof (remove_sections));
   ehdr = dso->ehdr;
-  if (multi_ehdr.e_ident[0] == '\0')
-    multi_ehdr = ehdr;

   sort_section_numbers (dso, sorted_section_numbers);
   if (calculate_section_distance (dso, sorted_section_numbers, distance))
@@ -11001,6 +10999,9 @@ write_multifile (DSO *dso)
   unsigned int i;
   int ret = 0;

+  if (multi_ehdr.e_ident[0] == '\0')
+    multi_ehdr = dso->ehdr;
+
   if ((multi_ptr_size && ptr_size != multi_ptr_size)
       || (multi_endian
          && multi_endian != (do_read_32 == buf_read_ule32
...
with which we get:
...
$ rm -f 3
$ cp hello 1
$ dwz 1
$ cp 1 2
$ dwz -m 3 1 2
./dwz: 1: DWARF compression not beneficial - old size 436 new size 436
./dwz: 2: DWARF compression not beneficial - old size 436 new size 436
$ ls 3
3
$ readelf -S 1  | grep alt
  [32] .gnu_debugaltlink PROGBITS         0000000000000000  00001182
...

-- 
You are receiving this mail because:
You are on the CC list for the bug.