dtneededsize: Fixes.
authorJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 18 Sep 2020 13:24:04 +0000 (15:24 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 18 Sep 2020 13:24:04 +0000 (15:24 +0200)
dtneededsize

index 6603bde..f1d62a6 100755 (executable)
@@ -58,40 +58,19 @@ chdir "dtneeded.out" or die "dtneeded.out: $!";
 my %F;
 my %SONAME;
 my @DEBUG;
 my %F;
 my %SONAME;
 my @DEBUG;
-my %SYMLINK;
 find {
   "no_chdir"=>1,
   "wanted"=>sub {
     die $File::Find::dir if $File::Find::dir=~m{/$};
     my $binfn=$File::Find::name;
 find {
   "no_chdir"=>1,
   "wanted"=>sub {
     die $File::Find::dir if $File::Find::dir=~m{/$};
     my $binfn=$File::Find::name;
-    if (-l $binfn) {
-      my $target=readlink $binfn or die $binfn;
-      $binfn=~s{^[.]}{};
-      my $final;
-      if ($target=~m{^/}) {
-       $final=$target;
-#warn "$binfn,target=rel=$$ref\n";
-      } else {
-       my $base=dirname(".$binfn");
-       my $abs=File::Spec->rel2abs($target,$base);
-       $final="/".File::Spec->abs2rel($abs);
-#warn "$binfn,base=$base,target=$target,abs=$abs,rel=$$ref\n";
-      }
-      1 while $final=~s{/[^/]+/[.][.]/}{/};
-      1 while $final=~s{/[^/]+/[.][.]$}{};
-      if ($final=~m{/[.][.]}) {
-       warn "$binfn,target=$target,final=$final\n";
-       return;
-      }
-      my $ref=\$SYMLINK{$binfn};
-      die if $$ref;
-      $$ref=$final;
-      return;
-    }
-    return if !-f $binfn;
+    return if $binfn eq ".";
     die $binfn if $binfn!~m{^[.]/};
     die $binfn if $binfn!~m{^[.]/};
+    return if -l $binfn;
+    return if !-f $binfn;
     my $bin=readfile $binfn;
     $binfn=~s{^[.]}{} or die;
     my $bin=readfile $binfn;
     $binfn=~s{^[.]}{} or die;
+    return if $bin=~m{^\s*0x0{8}\s+\Q(NULL)\E\s+0x0$}m;
+    return if $bin!~m{^\s*0x0{16}\s+\Q(NULL)\E\s+0x0$}m;
     my $rpath=($bin=~m{^.*\Q(R\E(?:UN)?\QPATH)\E\s*Library r(?:un)?path: \Q[\E(.*)\Q]\E$}m)[0];
     if ($rpath) {
       my $dirname=$File::Find::dir;
     my $rpath=($bin=~m{^.*\Q(R\E(?:UN)?\QPATH)\E\s*Library r(?:un)?path: \Q[\E(.*)\Q]\E$}m)[0];
     if ($rpath) {
       my $dirname=$File::Find::dir;
@@ -110,17 +89,41 @@ find {
     if ($soname) {
       my $sonamefn=$File::Find::dir."/".$soname;
       $sonamefn=~s{^[.]/}{/} or die $sonamefn;
     if ($soname) {
       my $sonamefn=$File::Find::dir."/".$soname;
       $sonamefn=~s{^[.]/}{/} or die $sonamefn;
-      my $ref=\$SONAME{$sonamefn};
+      my $ref=\$SONAME{$binfn};
 #      warn "soname=<$sonamefn> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
 #      warn "soname=<$sonamefn> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
+#warn "soname=<$sonamefn> <$binfn>" if $soname=~/libc/;
       $$ref=$h;
     }
     push @DEBUG,$binfn if $bin=~m{ \Q(DEBUG) \E };
   },
 },".";
 
       $$ref=$h;
     }
     push @DEBUG,$binfn if $bin=~m{ \Q(DEBUG) \E };
   },
 },".";
 
-#while (my($src,$target)=each %SYMLINK) {
-#  die "$src->$target" if exists $SYMLINK{$target};
-#}
+sub resolve($) {
+  my($binfn)=@_;
+  die if $binfn!~m{^/};
+  return $binfn if !-l ".$binfn";
+  $binfn=".$binfn";
+  my $target=readlink $binfn or die $binfn;
+  $binfn=~s{^[.]}{};
+  my $final;
+  if ($target=~m{^/}) {
+    $final=$target;
+#warn "$binfn,target=final=$final\n";
+  } else {
+    my $base=dirname(".$binfn");
+    my $abs=File::Spec->rel2abs($target,$base);
+    $final="/".File::Spec->abs2rel($abs);
+#warn "$binfn,base=$base,target=$target,abs=$abs,final=$final\n";
+  }
+  1 while $final=~s{/[^/]+/[.][.]/}{/};
+  1 while $final=~s{/[^/]+/[.][.]$}{};
+  if ($final=~m{/[.][.]}) {
+    warn "$binfn,target=$target,final=$final\n";
+    return;
+  }
+#warn "$binfn,final=$final\n";
+  return &resolve($final);
+}
 
 my $dwzsizeall=0;
 my $dwzsizeduplall=0;
 
 my $dwzsizeall=0;
 my $dwzsizeduplall=0;
@@ -128,19 +131,20 @@ my $dtsizeall=0;
 my @ratioall;
 my @ratioduplall;
 my $computed=0;
 my @ratioall;
 my @ratioduplall;
 my $computed=0;
+#@DEBUG="/usr/bin/elfedit";
 BINFN: for my $binfn (@DEBUG) {
 #  warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
 BINFN: for my $binfn (@DEBUG) {
 #  warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
-  die $binfn if exists $SYMLINK{$binfn};
+  die $binfn if -l ".$binfn";
   my @l=$binfn;
   my %l=($binfn=>1);
   while (@l) {
     my $l=shift @l;
     my $h=$F{$l};
   my @l=$binfn;
   my %l=($binfn=>1);
   while (@l) {
     my $l=shift @l;
     my $h=$F{$l};
+#warn "$binfn: $l: ".Dumper($h);
     for my $needed (@{$h->{"needed"}}) {
       my $found;
       if ($needed=~m{^/}) {
     for my $needed (@{$h->{"needed"}}) {
       my $found;
       if ($needed=~m{^/}) {
-       $needed=$SYMLINK{$needed} while exists $SYMLINK{$needed};
-       $found=$needed;
+       $found=resolve $needed;
       } else {
 #      die "$binfn: $l: $needed" if $needed=~m{/};
        my @rpath;
       } else {
 #      die "$binfn: $l: $needed" if $needed=~m{/};
        my @rpath;
@@ -153,8 +157,11 @@ BINFN: for my $binfn (@DEBUG) {
            next;
          }
          my $fn="$rpath/$needed";
            next;
          }
          my $fn="$rpath/$needed";
-         $fn=$SYMLINK{$fn} while exists $SYMLINK{$fn};
+#warn "A:$fn\n" if $fn=~/libc/;
+         $fn=resolve $fn;
+#warn "B:$fn\n" if $fn=~/libc/;
          next if !$SONAME{$fn};
          next if !$SONAME{$fn};
+#warn "C:$fn\n" if $fn=~/libc/;
          $found=$fn;
          last;
        }
          $found=$fn;
          last;
        }
@@ -168,6 +175,7 @@ BINFN: for my $binfn (@DEBUG) {
   my $dwzsizedupltot=0;
   my $dtsizetot=0;
   my %dwzcommons;
   my $dwzsizedupltot=0;
   my $dtsizetot=0;
   my %dwzcommons;
+#warn "$binfn: ".Dumper(\%l);
   for my $l (keys(%l)) {
     my $ref=$D{$l};
     if (!defined $ref) {
   for my $l (keys(%l)) {
     my $ref=$D{$l};
     if (!defined $ref) {
@@ -185,7 +193,6 @@ BINFN: for my $binfn (@DEBUG) {
     die if !defined $dwzsize;
     $dwzsizetot+=$dwzsize;
     $dwzsizedupltot+=$dwzsize;
     die if !defined $dwzsize;
     $dwzsizetot+=$dwzsize;
     $dwzsizedupltot+=$dwzsize;
-    $computed++;
     my $dwzcommon=$ref->[0];
     next if $dwzcommon eq "nodwzcommon";
     die if $dwzcommon eq "isdwzcommon";
     my $dwzcommon=$ref->[0];
     next if $dwzcommon eq "nodwzcommon";
     die if $dwzcommon eq "isdwzcommon";
@@ -199,10 +206,12 @@ BINFN: for my $binfn (@DEBUG) {
     $dwzsizedupltot+=$dwzcommonsize;
   }
   print "$binfn: dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot\n";
     $dwzsizedupltot+=$dwzcommonsize;
   }
   print "$binfn: dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot\n";
-warn "$binfn: ".Dumper(\%dwzcommons);
+#warn "$binfn: ".Dumper(\%dwzcommons);
+  $computed++;
   $dwzsizeall+=$dwzsizetot;
   $dwzsizeduplall+=$dwzsizedupltot;
   $dtsizeall+=$dtsizetot;
   $dwzsizeall+=$dwzsizetot;
   $dwzsizeduplall+=$dwzsizedupltot;
   $dtsizeall+=$dtsizetot;
+warn "ratio ".$dwzsizetot    /$dtsizetot." dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot: $binfn\n";
   push @ratioall    ,$dwzsizetot    /$dtsizetot;
   push @ratioduplall,$dwzsizedupltot/$dtsizetot;
 #  warn "$binfn done\n".Dumper([sort keys(%l)]);
   push @ratioall    ,$dwzsizetot    /$dtsizetot;
   push @ratioduplall,$dwzsizedupltot/$dtsizetot;
 #  warn "$binfn done\n".Dumper([sort keys(%l)]);