From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/btools/libfoo.pl | 408 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100755 release/src/btools/libfoo.pl (limited to 'release/src/btools/libfoo.pl') diff --git a/release/src/btools/libfoo.pl b/release/src/btools/libfoo.pl new file mode 100755 index 00000000..f7025acf --- /dev/null +++ b/release/src/btools/libfoo.pl @@ -0,0 +1,408 @@ +#!/usr/bin/perl +# +# libfoo.pl +# Copyright (C) 2006-2008 Jonathan Zarate +# +# - strip un-needed objects +# - create xref of symbols used +# + +sub error +{ + print STDERR "\n*** ERROR: " . (shift) . "\n\n"; + exit 1; +} + +sub basename +{ + my $fn = shift; + if ($fn =~ /([^\/]+)$/) { + return $1; + } + return $fn; +} + +sub load +{ + my $fname = shift; + + if ((-l $fname) || + ($fname =~ /\/lib\/modules\/\d+\.\d+\.\d+/) || + ($fname =~ /\.(asp|gif|png|svg|js|jsx|css|txt|pat|sh)$/)) { + return; + } + + if (-d $fname) { + my $d; + if (opendir($d, $fname)) { + foreach (readdir($d)) { + if ($_ !~ /^\./) { + load($fname . "/" . $_); + } + } + closedir($d); + } + return; + } + + + my $f; + my $base; + my $ok; + my $s; + + $base = basename($fname); + print LOG "\n\nreadelf $base:\n"; + + open($f, "mipsel-linux-readelf -WhsdD ${fname} 2>&1 |") || error("readelf - $!\n"); + + while (<$f>) { + print LOG; + + if (/\s+Type:\s+(\w+)/) { + $elf_type{$base} = $1; + $ok = 1; + last; + } + } + + if (!$ok) { + close($f); + return; + } + + print "$elf_type{$base} $base", " " x 30, "\r"; + + push(@elfs, $base); + + while (<$f>) { + print LOG; + + if (/\(NEEDED\)\s+Shared library: \[(.+)\]/) { + push(@{$elf_lib{$base}}, $1); + } + elsif (/Symbol table for image:/) { + last; + } + } + + while (<$f>) { + print LOG; + + if (/\s+(WEAK|GLOBAL)\s+(?:DEFAULT|VISIBLE)\s+(\w+)\s+(\w+)/) { + $s = $3; + if ($2 eq 'UND') { + if ($1 eq 'GLOBAL') { + $elf_ext{$base}{$s} = 1; + } + else { + print LOG "*** not GLOBAL\n"; + } + } + elsif ($2 eq 'ABS') { + } + elsif ($2 =~ /^\d+$/) { + $elf_exp{$base}{$s} = 1; + } + else { + print LOG "*** unknown type\n"; + } + } + elsif (!/Num Buc:/) { + print LOG "*** strange line\n"; + } + } + + close($f); +} + +sub fixDynDep +{ + my ($user, $dep) = @_; + + if (!defined $elf_dyn{$user}{$dep}) { + push(@{$elf_lib{$user}}, $dep); + $elf_dyn{$user}{$dep} = 1; + + print LOG "FixDynDep: $user = $dep\n"; + } +} + +sub fixDyn +{ + my $s; + + foreach (@elfs) { + if (/^libipt_.+\.so$/) { + fixDynDep("iptables", $_); + } + elsif (/^CP\d+\.so$/) { + fixDynDep("smbd", $_); + } + } + + fixDynDep("l2tpd", "cmd.so"); + fixDynDep("l2tpd", "sync-pppd.so"); + +# fixDynDep("libbcm.so", "libshared.so"); +# fixDynDep("libbcm.so", "libc.so.0"); +} + +sub usersOf +{ + my $name = shift; + my $sym = shift; + my @x; + my $e; + my $l; + + @x = (); + foreach $e (@elfs) { + foreach $l (@{$elf_lib{$e}}) { + if ($l eq $name) { + if ((!defined $sym) || (defined $elf_ext{$e}{$sym})) { + push(@x, $e); + } + last; + } + } + } + return @x; +} + +sub resolve +{ + my $name = shift; + my $sym = shift; + my $l; + + foreach $l (@{$elf_lib{$name}}) { +# print "\n$l $sym ", $elf_exp{$l}{$sym}, "\n"; + return $l if (defined $elf_exp{$l}{$sym}); + } + return "*** unresolved ***"; +} + +sub fillGaps +{ + my $name; + my $sym; + my @users; + my $u; + my $t; + my $found; + +# print "Resolving implicit links...\n"; + + foreach $name (@elfs) { + foreach $sym (keys %{$elf_ext{$name}}) { + $found = 0; + if (resolve($name, $sym) eq "*** unresolved ***") { + @users = usersOf($name); + foreach $u (@users) { + # if exported by $u + if (defined $elf_exp{$u}{$sym}) { + fixDynDep($name, $u); + $found = 1; + } + # if exported by shared libs of $u + if (($t = resolve($u, $sym)) ne "*** unresolved ***") { + fixDynDep($name, $t); + $found = 1; + } + } + + if ($found == 0) { + print "Unable to resolve $sym used by $name\n", @users; + exit 1; + } + } + } + } +} + +sub tab +{ + my $current = shift; + my $target = shift; + my $s = ""; + my $n; + + while (1) { + $n = $current + (4 - ($current % 4)); + last if ($n > $target); + $s = $s . "\t"; + $current = $n; + } + while ($current < $target) { + $s = $s . " "; + $current++; + } + return $s; +} + +sub genXref +{ + my $f; + my $fname; + my $s; + my @u; + +# print "Generating Xref Report...\n"; + + open($f, ">libfoo_xref.txt"); + foreach $fname (sort keys %elf_type) { + print $f "$fname:\n"; + + if (scalar(@{$elf_lib{$fname}}) > 0) { + print $f "Dependency:\n"; + foreach $s (sort @{$elf_lib{$fname}}) { + print $f "\t$s", defined $elf_dyn{$fname}{$s} ? " (dyn)\n" : "\n"; + } + } + + if (scalar(keys %{$elf_exp{$fname}}) > 0) { + print $f "Export:\n"; + foreach $s (sort keys %{$elf_exp{$fname}}) { + @u = usersOf($fname, $s); + if (scalar(@u) > 0) { + print $f "\t$s", tab(length($s) + 4, 40), " > ", join(",", @u), "\n"; + } + else { + print $f "\t$s\n"; + } + } + } + + if (scalar(keys %{$elf_ext{$fname}}) > 0) { + print $f "External:\n"; + foreach $s (sort keys %{$elf_ext{$fname}}) { + print $f "\t$s", tab(length($s) + 4, 40), " < ", resolve($fname, $s), "\n"; + } + } + + print $f "\n"; + } + close($f); +} + + +sub genSO +{ + my ($so, $arc, $opt) = @_; + my $name = basename($so); + my $sym; + my $fn; + my $inuse; + my @used; + my @unused; + my $cmd; + my $before, $after; + + if (!-f $so) { + print "$name: not found, skipping...\n"; + return 0; + } + + foreach $sym (sort keys %{$elf_exp{$name}}) { + if (scalar(usersOf($name, $sym)) > 0) { + push(@used, $sym); + } + else { + push(@unused, $sym); + } + } + +# print "\n$name: Attempting to link ", scalar(@used), " and remove ", scalar(@unused), " objects...\n"; + + print LOG "\n\n${base}\n"; + + $cmd = "mipsel-uclibc-ld -shared -s -z combreloc --warn-common --fatal-warnings ${opt} -soname ${name} -o ${so}"; + foreach (@{$elf_lib{$name}}) { + if ((!$elf_dyn{$name}{$_}) && (/^lib(.+)\.so/)) { + $cmd .= " -l$1"; + } + else { +# print LOG "Not marking for linkage: $_\n"; + } + } +# print "$cmd -u... ${arc}\n"; + if (scalar(@used) == 0) { + print "\n\n\n$name: WARNING: Library is not used by anything.\n\n\n"; + <>; +# return 0; + } + $cmd .= " -u " . join(" -u ", @used) . " ". $arc; + + print LOG "Command: $cmd\n"; + print LOG "Used: ", join(",", @used), "\n"; + print LOG "Unused: ", join(",", @unused), "\n"; + + $before = -s $so; + + system($cmd); + if ($? != 0) { + error("ld returned $?"); + } + + $after = -s $so; + + print "$name: Attempted to remove ", scalar(@unused), "/", scalar(@unused) + scalar(@used), " symbols. "; + printf "%.2fK - %.2fK = %.2fK\n", $before / 1024, $after / 1024, ($before - $after) / 1024; + +# print "\n$name: Attempting to link ", scalar(@used), " and remove ", scalar(@unused), " objects...\n"; +# printf "Before: %.2fK / After: %.2fK / Removed: %.2fK\n\n", $before / 1024, $after / 1024, ($before - $after) / 1024; + + return ($before > $after) +} + + +## +## +## + +# print "\nlibfoo.pl - fooify shared libraries\n"; +# print "Copyright (C) 2006-2007 Jonathan Zarate\n\n"; + +$root = $ENV{"TARGETDIR"}; +$uclibc = $ENV{"TOOLCHAIN"}; +$router = $ENV{"SRCBASE"} . "/router"; + +if ((!-d $root) || (!-d $uclibc) || (!-d $router)) { + print "Missing or invalid environment variables\n"; + exit(1); +} + +#open(LOG, ">libfoo.debug"); +open(LOG, ">/dev/null"); + +print "Loading...\r"; +load($root); +print "Finished loading files.", " " x 30, "\r"; + +fixDyn(); +fillGaps(); + +genXref(); + + +genSO("${root}/lib/libc.so.0", "${uclibc}/lib/libc.a", "-init __uClibc_init ${uclibc}/lib/optinfo/interp.o"); +genSO("${root}/lib/libresolv.so.0", "${uclibc}/lib/libresolv.a"); +genSO("${root}/lib/libcrypt.so.0", "${uclibc}/lib/libcrypt.a"); +genSO("${root}/lib/libm.so.0", "${uclibc}/lib/libm.a"); +genSO("${root}/lib/libpthread.so.0", "${uclibc}/lib/libpthread.a"); +genSO("${root}/lib/libutil.so.0", "${uclibc}/lib/libutil.a"); +# genSO("${root}/lib/libdl.so.0", "${uclibc}/lib/libdl.a"); +# genSO("${root}/lib/libnsl.so.0", "${uclibc}/lib/libnsl.a"); + +genSO("${root}/usr/lib/libcrypto.so", "${router}/openssl/libcrypto.a"); +genSO("${root}/usr/lib/libzebra.so", "${router}/zebra/lib/libzebra.a"); +# genSO("${root}/usr/lib/libtamba.so", "${router}/samba3/source/bin/libtamba.a"); +# genSO("${root}/usr/lib/libiptc.so", "${router}/iptables/libiptc/libiptc.a"); +# genSO("${root}/usr/lib/libshared.so", "${router}/shared/libshared.a"); +# genSO("${root}/usr/lib/libnvram.so", "${router}/nvram/libnvram.a"); + +print "\n"; + +close(LOG); +exit(0); -- cgit v1.2.3-54-g00ecf