summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorOliver Tappe2007-02-03 16:55:43 +0100
committerOliver Tappe2007-02-03 16:55:43 +0100
commitac7b357d6e8460e6d6c046c21b106f6f24420839 (patch)
tree0af516d30ffdf3cea1ba32992a0a5262673f3fe3 /bin
parent* added support for binaries using rpaths (explicit paths specified at link s... (diff)
downloadcore-ac7b357d6e8460e6d6c046c21b106f6f24420839.tar.gz
core-ac7b357d6e8460e6d6c046c21b106f6f24420839.tar.xz
core-ac7b357d6e8460e6d6c046c21b106f6f24420839.zip
* moved slxldd from config-db to (new) bin folder as it has nothing to do with the config-db
git-svn-id: http://svn.openslx.org/svn/openslx/trunk@671 95ad53e4-c205-0410-b2fa-d234c58c8868
Diffstat (limited to 'bin')
-rwxr-xr-xbin/slxldd273
1 files changed, 273 insertions, 0 deletions
diff --git a/bin/slxldd b/bin/slxldd
new file mode 100755
index 00000000..9117a1aa
--- /dev/null
+++ b/bin/slxldd
@@ -0,0 +1,273 @@
+#! /usr/bin/perl
+#
+# slxldd - OpenSLX-rewrite of ldd that works on multiple architectures.
+#
+# (c) 2006 - OpenSLX.com
+#
+# Oliver Tappe <ot@openslx.com>
+#
+use strict;
+
+my $abstract = q[
+slxldd
+ This script reimplements ldd in a way that should work for all
+ binary formats supported by the binutils installed on the host system.
+
+ An example: if you have a folder containing an ia64 system, you can
+ invoke this script on a ia32-host in order to determine all the libraries
+ required by a binary of the ia64 target system.
+];
+
+use File::Glob ':globally';
+use Getopt::Long;
+use Pod::Usage;
+
+# add the lib-folder to perl's search path for modules:
+use FindBin;
+use lib "$FindBin::RealBin/../lib";
+
+use OpenSLX::Basics;
+
+my (
+ $helpReq,
+ $manReq,
+ $verbose,
+
+ $rootPath,
+ $versionReq,
+
+ @filesToDo,
+
+ @libFolders,
+ @libs,
+ %libInfo,
+);
+
+$rootPath = '/';
+GetOptions(
+ 'help|?' => \$helpReq,
+ 'man' => \$manReq,
+ 'root-path=s' => \$rootPath,
+ 'verbose' => \$verbose,
+ 'version' => \$versionReq,
+) or pod2usage(2);
+pod2usage(-msg => $abstract, -verbose => 0, -exitval => 1) if $helpReq;
+pod2usage(-verbose => 2) if $manReq;
+if ($versionReq) {
+ system('slxversion');
+ exit 1;
+}
+
+openslxInit();
+
+if (!$rootPath) {
+ print _tr("You need to specify the root-path!\n");
+ pod2usage(2);
+}
+
+$rootPath =~ s[/+$][];
+ # remove trailing slashes
+
+if (!@ARGV) {
+ print _tr("You need to specify at least one file!\n");
+ pod2usage(2);
+}
+
+fetchLoaderConfig();
+
+foreach my $file (@ARGV) {
+ if ($file =~ m[^/]) {
+ # force absolute path relative to $rootPath:
+ $file = "$rootPath$file";
+ }
+ if (!-e $file) {
+ die _tr("slxldd: unable to find file '%s'\n", $file);
+ }
+ push @filesToDo, $file;
+}
+
+foreach my $file (@filesToDo) {
+ addLibsForBinary($file);
+}
+
+sub fetchLoaderConfigFile
+{
+ my $ldConfFile = shift;
+
+ open(LDCONF, "< $ldConfFile");
+ while(<LDCONF>) {
+ chomp;
+ if (/^\s*include\s+(.+?)\s*$/i) {
+ foreach my $incFile (<$rootPath$1>) {
+ fetchLoaderConfigFile($incFile);
+ }
+ next;
+ }
+ if (/\S+/i) {
+ s[=.+][];
+ # remove any lib-type specifications (e.g. '=libc5')
+ push @libFolders, "$rootPath$_";
+ }
+ }
+ close LDCONF;
+}
+
+sub fetchLoaderConfig
+{
+ if (!-e "$rootPath/etc/ld.so.conf") {
+ die _tr("$rootPath/etc/ld.so.conf not found, maybe wrong root-path?\n");
+ }
+ fetchLoaderConfigFile("$rootPath/etc/ld.so.conf");
+
+ # add "trusted" folders /lib and /usr/lib if not already in place:
+ if (!grep { m[^$rootPath/lib$]} @libFolders) {
+ push @libFolders, "$rootPath/lib";
+ }
+ if (!grep { m[^$rootPath/usr/lib$] } @libFolders) {
+ push @libFolders, "$rootPath/usr/lib";
+ }
+}
+
+sub addLib
+{
+ my $lib = shift;
+ my $bitwidth = shift;
+ my $rpath = shift;
+
+ if (!exists $libInfo{$lib}) {
+ push @libs, $lib;
+ my $libPath;
+ my @folders = @libFolders;
+ if (defined $rpath) {
+ # add rpath if given (explicit paths set during link stage)
+ push @folders, split ':', $rpath;
+ }
+ foreach my $folder (@folders) {
+ if (-e "$folder/$lib") {
+ # have library matching name, now check if the platform is ok, too:
+ my $libFileInfo = `file --dereference $folder/$lib 2>/dev/null`;
+ if ($?) {
+ die _tr("unable to fetch file info for $folder/$lib, giving up!\n");
+ }
+ my $libBitwidth = ($libFileInfo =~ m[64-bit]i) ? 64 : 32;
+ if ($bitwidth != $libBitwidth) {
+ vlog 0, _tr('%s has wrong bitwidth (%s instead of %s)',
+ "$folder/$lib", $libBitwidth, $bitwidth) if $verbose;
+ next;
+ }
+ $libPath = "$folder/$lib";
+ last;
+ }
+ }
+ if (!defined $libPath) {
+ die _tr("*** unable to find lib %s! ***\n", $lib);
+ }
+ print "$libPath\n";
+ $libInfo{$lib} = $libPath;
+ push @filesToDo, $libPath;
+ }
+}
+
+sub addLibsForBinary
+{
+ my $binary = shift;
+
+ # first do some checks:
+ print STDERR "analyzing '$binary'...\n" if $verbose;
+ my $fileInfo = `file --dereference --brief --mime $binary 2>/dev/null`;
+ chomp $fileInfo;
+ print STDERR "\tinfo is: '$fileInfo'...\n" if $verbose;
+ if ($?) {
+ die _tr("unable to fetch file info for $binary, giving up!\n");
+ }
+ if ($fileInfo !~ m[^application/(x-executable|x-shared)]i) {
+ # ignore anything that's not an executable or a shared library
+ print STDERR "$binary: ignored, as it isn't an executable or a shared library\n";
+ next;
+ }
+
+ my $bitwidth = ($fileInfo =~ m[64-bit]i) ? 64 : 32;
+ # determine whether binary is 32- or 64-bit platform
+
+ # now find out about needed libs, we first try objdump...
+ print STDERR "\ttrying objdump...\n" if $verbose;
+ my $res = `objdump -p $binary 2>/dev/null`;
+ if (!$?) {
+ # find out if rpath is set for binary:
+ my $rpath;
+ if ($res =~ m[^\s*RPATH\s*(\S+)]im) {
+ $rpath = $1;
+ print STDERR "\trpath='$rpath'\n" if $verbose;
+ }
+ while($res =~ m[^\s*NEEDED\s*(.+?)\s*$]gm) {
+ addLib($1, $bitwidth, $rpath);
+ }
+ } else {
+ # ...objdump failed, so we try readelf instead:
+ print STDERR "\ttrying readelf...\n" if $verbose;
+ $res = `readelf -d $binary 2>/dev/null`;
+ if ($?) {
+ die _tr("neither objdump nor readelf seems to be installed, giving up!\n");
+ }
+ # find out if rpath is set for binary:
+ my $rpath;
+ if ($res =~ m/Library\s*rpath:\s*\[([^\]]+)/im) {
+ $rpath = $1;
+ print STDERR "\trpath='$rpath'\n" if $verbose;
+ }
+ while($res =~ m{\(NEEDED\)[^\[]+\[(.+?)\]\s*$}gm) {
+ addLib($1, $bitwidth, $rpath);
+ }
+ }
+}
+
+
+__END__
+
+=head1 NAME
+
+slxldd - OpenSLX-script to determine the libraries required by any given
+binary file.
+
+=head1 SYNOPSIS
+
+slxldd [options] file [...more files]
+
+ Options:
+ --help brief help message
+ --man show full documentation
+ --root-path=<string> path to the root folder for library search
+ --verbose show what's going on during execution
+ --version show version
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<--help>
+
+Prints a brief help message and exits.
+
+=item B<--man>
+
+Prints the manual page and exits.
+
+=item B<--root-path=<string>>
+
+Sets the root folder that is used when searching for libraries. In order to
+collect the loader-settings, etc/ld.so.conf is read relative to this path and
+all libraries are sought relative to this path, too (a.k.a. a virtual chroot).
+
+Defaults to '/'.
+
+=item B<--verbose>
+
+Prints info about the files as they are being scanned.
+
+=item B<--version>
+
+Prints the version and exits.
+
+=back
+
+=cut \ No newline at end of file