diff options
-rw-r--r-- | brp-check-elf-files | 122 |
1 files changed, 37 insertions, 85 deletions
diff --git a/brp-check-elf-files b/brp-check-elf-files index c0badf5..d9db6b0 100644 --- a/brp-check-elf-files +++ b/brp-check-elf-files @@ -1,85 +1,37 @@ -#!/usr/bin/perl -# 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>/dev/null | grep "undefined symbol"`; - 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; - } -} +#!/bin/sh +# Check elf files + +if [ -z "$RPM_BUILD_ROOT" ]; then + echo "No build root defined" >&2 + exit 1 +fi + +if [ ! -d "$RPM_BUILD_ROOT" ]; then + echo "Invalid build root" >&2 + exit 1 +fi + +LIB="$(rpm --eval %{_lib})" +export LD_LIBRARY_PATH="$RPM_BUILD_ROOT/$LIB:$RPM_BUILD_ROOT/usr/$LIB" + +find "$RPM_BUILD_ROOT" -type f \( -executable -o -name \*.so\* \) -a \ + \( ! -path $RPM_BUILD_ROOT/usr/lib/debug/\* -a \ + ! -path $RPM_BUILD_ROOT/usr/src/debug/\* \) \ + -print0 | +xargs --no-run-if-empty -0 file -N -L | +grep -e '\.so.*: ELF.*shared' -e ': ELF.*executable' | +while read match; do + path="$(echo $match | cut -d':' -f1)" + syspath="$(echo $path | sed -e "s#^$RPM_BUILD_ROOT##")" + unused_libs="$(ldd -u -r $path 2> /dev/null | grep /)" + if [ -n "$unused_libs" ]; then + printf '%s\n' "Warning: unused libraries in $syspath: " >&2 + printf '%s\n' "$unused_libs" >&2 + fi + if echo $match |grep -q shared; then + undefined_symbols="$(ldd -r $path 2>&1 | grep '^undefined symbol: '| sed -e 's#^undefined symbol:##g' -e "s#($path).*##g" | tr -d '\n' | tr -d '\t')" + if [ -n "$undefined_symbols" ]; then + printf '%s\n' "Warning: undefined symbols in $syspath:$undefined_symbols" >&2 + fi + fi +done |