aboutsummaryrefslogtreecommitdiffstats
path: root/check_elf_files
diff options
context:
space:
mode:
Diffstat (limited to 'check_elf_files')
-rwxr-xr-xcheck_elf_files86
1 files changed, 86 insertions, 0 deletions
diff --git a/check_elf_files b/check_elf_files
new file mode 100755
index 0000000..52c8161
--- /dev/null
+++ b/check_elf_files
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+# $Id$
+# Strip files
+
+use strict;
+use warnings;
+use File::Find;
+use File::Basename;
+
+my $buildroot = $ENV{RPM_BUILD_ROOT};
+die "No build root defined" unless $buildroot;
+die "Invalid build root" unless -d $buildroot;
+# normalize build root
+$buildroot =~ s|/$||;
+
+# set LIBRARY_PATH to check libraries in build root
+my $lib = `rpm --eval %_lib`;
+chomp $lib;
+$ENV{LD_LIBRARY_PATH}="$buildroot/$lib:$buildroot/usr/$lib";
+
+my (@shared_libs, @executables, @static_libs);
+find(\&keep_wanted, $buildroot);
+
+check_missing_or_unused_libs();
+
+sub check_missing_or_unused_libs {
+ my $shift = length($buildroot);
+ foreach my $file (@shared_libs, @executables) {
+ my (undef, undef, @l) = `ldd -u -r $file 2>/dev/null`;
+ next unless @l;
+ my $file_ = substr($file, $shift);
+ print STDERR
+ "Warning: unused libraries in $file_: ",
+ join(' ', map { basename($_) } @l), "\n";
+ }
+ foreach my $file (@shared_libs) {
+ my @l = `ldd -r $file 2>&1 >/dev/null`;
+ next unless @l;
+ my $file_ = substr($file, $shift);
+ print STDERR
+ "Warning: undefined symbols in $file_: ",
+ join(' ', map { /undefined symbol: (\S+)/ ? $1 : () } @l), "\n";
+ }
+}
+
+# TODO: we should write a binding for libfile...
+sub expensive_test {
+ my ($file) = @_;
+ my $type = `file -- $file`;
+}
+
+# Check if a file is an elf binary, shared library, or static library,
+# for use by File::Find. It'll fill the following 3 arrays with anything
+# it finds:
+sub keep_wanted() {
+ # skip everything but files
+ return unless -f $_;
+ # skip symlinks
+ return if -l $_;
+ return if $File::Find::dir =~ m!/usr/lib/debug($|/)!;
+
+ # Does its filename look like a shared library?
+ if (m/\.so/) {
+ # Ok, do the expensive test.
+ if (expensive_test($_) =~ m/ELF.*shared/) {
+ push @shared_libs, $File::Find::name;
+ return;
+ }
+ }
+
+ # Is it executable? -x isn't good enough, so we need to use stat.
+ my (undef, undef, $mode, undef) = stat(_);
+ if ($mode & 0111) {
+ # Ok, expensive test.
+ if (expensive_test($_) =~ m/ELF.*executable/) {
+ push @executables, $File::Find::name;
+ return;
+ }
+ }
+
+ # Is it a static library, and not a debug library?
+ if (m/lib.*\.a/ && ! m/_g\.a/) {
+ push @static_libs, $File::Find::name;
+ return;
+ }
+}