4 use File::Basename qw(&dirname);
12 open F,"$fname" or die $fname;
14 defined(my $r=<F>) or die $fname;
15 close F or die $fname;
20 # ==> build/Cadence-1.0.0-0.12.20200504git5787908.fc33.src.rpm.dtneeded <==
21 # /usr/lib/debug/.dwz/Cadence isdwzcommon 479079 NA
22 # /usr/bin/cadence-jackmeter /usr/lib/debug/.dwz/Cadence 717792 1329040
23 # /usr/bin/cadence-xycontroller /usr/lib/debug/.dwz/Cadence 1763616 2369832
24 # ==> build/CVector-1.0.3.1-21.fc33.src.rpm.dtneeded <==
25 # /usr/lib64/libCVector-1.0.3.so.2.0.0 nodwzcommon 28088 28896
26 for my $dtneededfn (glob "build/*.dtneeded") {
28 open F,$dtneededfn or die "$dtneededfn: $1";
32 my($fn,$dwzcommon,$dwzsize,$dtsize)=/^(\S+) (\S+) (\S+) (\S+)$/ or die "$dtneededfn: $_";
33 die if $dwzcommon eq "isdwzcommon" && $dtsize ne "NA";
36 die if $dwzcommon eq "isdwzcommon";
39 $$ref=[$dwzcommon,$dwzsize,$dtsize];
42 close F or die "close $dtneededfn: $1";
45 chdir "dtneeded.out" or die "dtneeded.out: $!";
53 die $File::Find::dir if $File::Find::dir=~m{/$};
54 my $binfn=$File::Find::name;
56 die $binfn if $binfn!~m{^[.]/};
57 my $bin=readfile $binfn;
58 $binfn=~s{^[.]}{} or die;
59 my $rpath=($bin=~m{^.*\Q(R\E(?:UN)?\QPATH)\E\s*Library r(?:un)?path: \Q[\E(.*)\Q]\E$}m)[0];
61 my $dirname=$File::Find::dir;
62 die if $dirname!~s{^[.]/}{/};
63 $rpath=~s{\$ORIGIN}{$dirname}g;
65 my $soname=($bin=~m{^.*\Q(SONAME)\E\s*Library soname: \Q[\E(.*)\Q]\E$}m)[0];
68 "needed"=>[$bin=~m{^\s*0x0000000000000001\s*\Q(NEEDED)\E\s*\QShared library: [\E(.*)\Q]\E$}gm],
70 $h->{"rpath"}=$rpath if $rpath;
72 # my $total=keys %F; warn "$total...\n" if 0==$total%1000;
74 my $sonamefn=$File::Find::dir."/".$soname;
75 $sonamefn=~s{^[.]/}{/} or die $sonamefn;
76 my $ref=\$SONAME{$sonamefn};
77 # warn "soname=<$sonamefn> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
80 push @DEBUG,$binfn if $bin=~m{ \Q(DEBUG) \E };
86 BINFN: for my $binfn (@DEBUG) {
87 # warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
93 for my $needed (@{$h->{"needed"}}) {
98 # die "$binfn: $l: $needed" if $needed=~m{/};
100 my $rpath=$h->{"rpath"};
101 push @rpath,split /:/,$rpath if $rpath;
102 push @rpath,qw(/lib64 /usr/lib64);
103 for my $rpath (@rpath) {
105 warn "$binfn: $l: $rpath";
108 my $fn="$rpath/$needed";
109 next if !$SONAME{$fn};
113 warn "$binfn: $l: $needed not found; rpath=".join(":",@rpath)."\n" if !$found;
115 push @l,$found if $found&&!$l{$found}++;
118 #warn Dumper $binfn,\%l;
122 for my $l (keys(%l)) {
125 # warn "$binfn: $l: missing\n";
129 warn "$binfn: $l: ambiguous\n";
132 my $dtsize=$ref->[2];
133 die if !defined $dtsize;
135 my $dwzsize=$ref->[1];
136 die if !defined $dwzsize;
137 $dwzsizetot+=$dwzsize;
138 my $dwzcommon=$ref->[0];
139 next if $dwzcommon eq "nodwzcommon";
140 die if $dwzcommon eq "isdwzcommon";
141 next if $dwzcommons{$dwzcommon}++;
142 my $dwzcommonref=$D{$dwzcommon};
143 die if !$dwzcommonref;
144 die if $dwzcommonref->[0] ne "isdwzcommon";
145 die if $dwzcommonref->[2] ne "NA";
146 my $dwzcommonsize=$dwzcommonref->[1];
147 $dwzsizetot+=$dwzcommonsize;
149 print "$binfn: dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot\n";
150 warn "$binfn: ".Dumper(\%dwzcommons);
151 $dwzsizeall+=$dwzsizetot;
152 $dtsizeall+=$dtsizetot;
153 # warn "$binfn done\n".Dumper([sort keys(%l)]);
155 print "dwzsizeall=$dwzsizeall dtsizeall=$dtsizeall\n";