runone: nc=nocommon
[massrebuild.git] / dtneededsize
index 9cbb467..0b15cc5 100755 (executable)
@@ -16,19 +16,71 @@ sub readfile {
   return $r;
 }
 
+my %D;
+# ==> build/Cadence-1.0.0-0.12.20200504git5787908.fc33.src.rpm.dtneeded <==
+# /usr/lib/debug/.dwz/Cadence isdwzcommon 479079 NA
+# /usr/bin/cadence-jackmeter /usr/lib/debug/.dwz/Cadence 717792 1329040
+# /usr/bin/cadence-xycontroller /usr/lib/debug/.dwz/Cadence 1763616 2369832
+# ==> build/CVector-1.0.3.1-21.fc33.src.rpm.dtneeded <==
+# /usr/lib64/libCVector-1.0.3.so.2.0.0 nodwzcommon 28088 28896
+for my $dtneededfn (glob "build/*.dtneeded") {
+  local *F;
+  open F,$dtneededfn or die "$dtneededfn: $1";
+  local $_;
+  while (<F>) {
+    chomp;
+    my($fn,$dwzcommon,$dwzsize,$dtsize)=/^(\S+) (\S+) (\S+) (\S+)$/ or die "$dtneededfn: $_";
+    die if $dwzcommon eq "isdwzcommon" && $dtsize ne "NA";
+    my $ref=\$D{$fn};
+    if ($$ref) {
+      die if $dwzcommon eq "isdwzcommon";
+      $$ref=[];
+    } else {
+      $$ref=[$dwzcommon,$dwzsize,$dtsize];
+    }
+  }
+  close F or die "close $dtneededfn: $1";
+}
+
 chdir "dtneeded.out" or die "dtneeded.out: $!";
 
 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;
+    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;
     die $binfn if $binfn!~m{^[.]/};
     my $bin=readfile $binfn;
+    $binfn=~s{^[.]}{} or die;
     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;
@@ -42,18 +94,29 @@ find {
     };
     $h->{"rpath"}=$rpath if $rpath;
     $F{$binfn}=$h;
+#warn "$binfn=".Dumper($h)."\n" if $binfn=~/libc.so.6/;
 #    my $total=keys %F; warn "$total...\n" if 0==$total%1000;
     if ($soname) {
-      my $ref=\$SONAME{$File::Find::dir."/".$soname};
-#      warn "soname=<$soname> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
+      my $sonamefn=$File::Find::dir."/".$soname;
+      $sonamefn=~s{^[.]/}{/} or die $sonamefn;
+      my $ref=\$SONAME{$sonamefn};
+#      warn "soname=<$sonamefn> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
       $$ref=$h;
     }
     push @DEBUG,$binfn if $bin=~m{ \Q(DEBUG) \E };
   },
 },".";
 
-for my $binfn (@DEBUG) {
+#while (my($src,$target)=each %SYMLINK) {
+#  die "$src->$target" if exists $SYMLINK{$target};
+#}
+
+my $dwzsizeall=0;
+my $dtsizeall=0;
+my $computed=0;
+BINFN: for my $binfn (@DEBUG) {
 #  warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
+  die $binfn if exists $SYMLINK{$binfn};
   my @l=$binfn;
   my %l=($binfn=>1);
   while (@l) {
@@ -62,6 +125,7 @@ for my $binfn (@DEBUG) {
     for my $needed (@{$h->{"needed"}}) {
       my $found;
       if ($needed=~m{^/}) {
+       $needed=$SYMLINK{$needed} while exists $SYMLINK{$needed};
        $found=$needed;
       } else {
 #      die "$binfn: $l: $needed" if $needed=~m{/};
@@ -74,7 +138,8 @@ for my $binfn (@DEBUG) {
            warn "$binfn: $l: $rpath";
            next;
          }
-         my $fn=".$rpath/$needed";
+         my $fn="$rpath/$needed";
+         $fn=$SYMLINK{$fn} while exists $SYMLINK{$fn};
          next if !$SONAME{$fn};
          $found=$fn;
          last;
@@ -84,5 +149,43 @@ for my $binfn (@DEBUG) {
       push @l,$found if $found&&!$l{$found}++;
     }
   }
+#warn Dumper $binfn,\%l;
+  my $dwzsizetot=0;
+  my $dtsizetot=0;
+  my %dwzcommons;
+  for my $l (keys(%l)) {
+    my $ref=$D{$l};
+    if (!defined $ref) {
+      warn "$binfn: $l: missing\n";
+      next BINFN;
+    }
+    if (0==@$ref) {
+      warn "$binfn: $l: ambiguous\n";
+      next BINFN;
+    }
+    my $dtsize=$ref->[2];
+    die if !defined $dtsize;
+    $dtsizetot+=$dtsize;
+    my $dwzsize=$ref->[1];
+    die if !defined $dwzsize;
+    $dwzsizetot+=$dwzsize;
+    $computed++;
+    my $dwzcommon=$ref->[0];
+    next if $dwzcommon eq "nodwzcommon";
+    die if $dwzcommon eq "isdwzcommon";
+    next if $dwzcommons{$dwzcommon}++;
+    my $dwzcommonref=$D{$dwzcommon};
+    die if !$dwzcommonref;
+    die if $dwzcommonref->[0] ne "isdwzcommon";
+    die if $dwzcommonref->[2] ne "NA";
+    my $dwzcommonsize=$dwzcommonref->[1];
+    $dwzsizetot+=$dwzcommonsize;
+  }
+  print "$binfn: dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot\n";
+warn "$binfn: ".Dumper(\%dwzcommons);
+  $dwzsizeall+=$dwzsizetot;
+  $dtsizeall+=$dtsizetot;
 #  warn "$binfn done\n".Dumper([sort keys(%l)]);
 }
+print "dwzsizeall=$dwzsizeall dtsizeall=$dtsizeall =".$dwzsizeall/$dtsizeall."\n";
+print "computed=$computed of DEBUG=".(0+@DEBUG)."\n";