X-Git-Url: https://git.jankratochvil.net/?p=massrebuild.git;a=blobdiff_plain;f=dtneededsize;h=7a7120eb48d0fbb0cafe3a29d9a01655050d3600;hp=1354bb8c61f329d41e82803a50860a8edf19e020;hb=2229caba05ab067f60fbf7c3d7e147723216e51a;hpb=2c33c1307fd2902092d469ff172f8dc1aa7a89fe;ds=sidebyside diff --git a/dtneededsize b/dtneededsize old mode 100644 new mode 100755 index 1354bb8..7a7120e --- a/dtneededsize +++ b/dtneededsize @@ -1,7 +1,158 @@ -#! /bin/bash -cd dtneeded.out || exit 1 -for bin in $(grep -rl ' (DEBUG) ' .);do - sed -n 's/^ *0x0000000000000001 *(NEEDED) *Shared library: \[\(.*\)\]$/\1/p' <$bin - rpath="$(sed -n 's/^.*(R\(\|UN\)PATH) *Library r\(\|un\)path: \[\(.*\)\]$/\1/p' <$bin):." - rpath="$(echo "$rpath"|sed 's#[$]ORIGIN#'"$(dirname $bin)"'#g')" -done +#! /usr/bin/perl +use strict; +use warnings; +use File::Basename qw(&dirname); +use File::Find; +use Data::Dumper; + +$|=1; +sub readfile { + my($fname)=@_; + local *F; + open F,"$fname" or die $fname; + local $/=undef(); + defined(my $r=) or die $fname; + close F or die $fname; + 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 () { + 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; +find { + "no_chdir"=>1, + "wanted"=>sub { + die $File::Find::dir if $File::Find::dir=~m{/$}; + my $binfn=$File::Find::name; + 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; + die if $dirname!~s{^[.]/}{/}; + $rpath=~s{\$ORIGIN}{$dirname}g; + } + my $soname=($bin=~m{^.*\Q(SONAME)\E\s*Library soname: \Q[\E(.*)\Q]\E$}m)[0]; + my $h={ + "binfn"=>$binfn, + "needed"=>[$bin=~m{^\s*0x0000000000000001\s*\Q(NEEDED)\E\s*\QShared library: [\E(.*)\Q]\E$}gm], + }; + $h->{"rpath"}=$rpath if $rpath; + $F{$binfn}=$h; +# my $total=keys %F; warn "$total...\n" if 0==$total%1000; + if ($soname) { + 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 }; + }, +},"."; + +my $dwzsizeall=0; +my $dtsizeall=0; +my $computed=0; +BINFN: for my $binfn (@DEBUG) { +# warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]); + my @l=$binfn; + my %l=($binfn=>1); + while (@l) { + my $l=shift @l; + my $h=$F{$l}; + for my $needed (@{$h->{"needed"}}) { + my $found; + if ($needed=~m{^/}) { + $found=$needed; + } else { +# die "$binfn: $l: $needed" if $needed=~m{/}; + my @rpath; + my $rpath=$h->{"rpath"}; + push @rpath,split /:/,$rpath if $rpath; + push @rpath,qw(/lib64 /usr/lib64); + for my $rpath (@rpath) { + if ($rpath!~m{^/}) { + warn "$binfn: $l: $rpath"; + next; + } + my $fn="$rpath/$needed"; + next if !$SONAME{$fn}; + $found=$fn; + last; + } + warn "$binfn: $l: $needed not found; rpath=".join(":",@rpath)."\n" if !$found; + } + 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\n"; +print "computed=$computed of DEBUG=".(0+@DEBUG)."\n";