You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
6.5 KiB

  1. #!/usr/bin/env perl
  2. ###############################################################################
  3. #
  4. # Written by Igor Ljubuncic (igor.ljubuncic@intel.com)
  5. # Yuval Nissan (yuval.nissan@intel.com)
  6. #
  7. # Version 1.0 on Mar 29, 2011
  8. #
  9. # This program performs recursive ldd checks for binaries and libraries
  10. # It recurses through entire ldd tree for every listed binary and library
  11. # It completes when no matches found in the current branch
  12. # Same limitations to standard ldd apply
  13. # ldd cannot check libraries with no permissions
  14. #
  15. ###############################################################################
  16. # /*
  17. #
  18. # This file is provided under a dual BSD/GPLv2 license. When using or
  19. # redistributing this file, you may do so under either license.
  20. #
  21. # GPL LICENSE SUMMARY
  22. #
  23. # Copyright(c) 2011 Intel Corporation. All rights reserved.
  24. #
  25. # This program is free software; you can redistribute it and/or modify
  26. # it under the terms of version 2 of the GNU General Public License as
  27. # published by the Free Software Foundation.
  28. #
  29. # This program is distributed in the hope that it will be useful, but
  30. # WITHOUT ANY WARRANTY; without even the implied warranty of
  31. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  32. # General Public License for more details.
  33. #
  34. # You should have received a copy of the GNU General Public License
  35. # along with this program; if not, write to the Free Software
  36. # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  37. # The full GNU General Public License is included in this distribution
  38. # in the file called LICENSE.GPL.
  39. #
  40. # Contact Information:
  41. # Igor Ljubuncic, igor.ljubuncic@intel.com
  42. # P.O.B 1659, MATAM, 31015 Haifa, Israel
  43. #
  44. # BSD LICENSE
  45. #
  46. # Copyright(c) 2011 Intel Corporation. All rights reserved.
  47. # All rights reserved.
  48. #
  49. # Redistribution and use in source and binary forms, with or without
  50. # modification, are permitted provided that the following conditions
  51. # are met:
  52. #
  53. # * Redistributions of source code must retain the above copyright
  54. # notice, this list of conditions and the following disclaimer.
  55. # * Redistributions in binary form must reproduce the above copyright
  56. # notice, this list of conditions and the following disclaimer in
  57. # the documentation and/or other materials provided with the
  58. # distribution.
  59. # * Neither the name of Intel Corporation nor the names of its
  60. # contributors may be used to endorse or promote products derived
  61. # from this software without specific prior written permission.
  62. #
  63. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  64. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  65. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  66. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  67. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  68. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  69. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  70. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  71. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  73. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74. #
  75. # */
  76. use strict;
  77. use Data::Dumper;
  78. use Getopt::Long;
  79. # global variables
  80. # ----------------
  81. my $result;
  82. my @inputs = ();
  83. my $helpoption=0;
  84. my $debug=0;
  85. my $verbose=0;
  86. my $sep;
  87. my $print_vars;
  88. my $uniq;
  89. my %uniq;
  90. #############################################
  91. #############################################
  92. ### ###
  93. ### FUNCTION MAIN ###
  94. ### ###
  95. #############################################
  96. #############################################
  97. GetOptions(
  98. 'h|help+' => \$helpoption,
  99. 'debug+' => \$verbose,
  100. 't=s' => \$sep,
  101. 'l' => \$print_vars,
  102. 'uniq' => \$uniq
  103. );
  104. if ($verbose==1) {
  105. # Print messages for debug purposes
  106. $debug = 1;
  107. }
  108. if (($helpoption==1) || ($ARGV[0] eq "")) {
  109. print "\nRecursive ldd v1.00\n";
  110. print "Written by Igor Ljubuncic (igor.ljubuncic\@intel.com)\n";
  111. print "Written by Yuval Nissan (yuval.nissan\@intel.com)\n\n";
  112. print "Usage mode:\n\n";
  113. print "-d\t\tverbose output\n";
  114. print "-h|help\t\tprint help\n";
  115. print "-t\t\tdelimiter\n";
  116. print "-l\t\tprint env. variables\n";
  117. print "-uniq\t\tprint unique values only\n\n";
  118. exit 0;
  119. }
  120. $sep ||= "\t";
  121. push @inputs, @ARGV;
  122. if($print_vars) {
  123. print "ldd output can be affected by:\n";
  124. print "\$LD_LIBRARY_PATH = '".$ENV{LD_LIBRARY_PATH}."'\n";
  125. print "\$LD_PRELOAD = '".$ENV{LD_PRELOAD}."'\n\n";
  126. }
  127. &recurseLibs($inputs[0], 0);
  128. delete $uniq{$inputs[0]};
  129. print join("\n", keys(%uniq))."\n" if $uniq;
  130. exit 0;
  131. ##############################
  132. ##############################
  133. ## ##
  134. ## FUNCTIONS ##
  135. ## ##
  136. ##############################
  137. ##############################
  138. sub recurseLibs
  139. {
  140. my $filename=shift;
  141. my $depth = shift;
  142. print "Working on file: $filename\n" if $debug;
  143. print "$sep"x$depth if not $uniq;
  144. ++$depth;
  145. return if $uniq{$filename} and $uniq;
  146. $uniq{$filename} = 1;
  147. print "$filename\n" if not $uniq;
  148. chomp(my @libraries = `/usr/bin/ldd $filename`);
  149. print "Libraries:\n@libraries\n" if $debug;
  150. foreach my $line (@libraries) {
  151. next if not $line;
  152. $line =~ s/^\s+//g;
  153. $line =~ s/\s+$//g;
  154. # If static or else
  155. if (($line =~ /statically linked/) or ($line =~ /not a dynamic executable/)) {
  156. return;
  157. }
  158. elsif($line =~ /not found/) {
  159. print "$sep"x$depth if not $uniq;
  160. print "$line\n" if not $uniq;
  161. $uniq{$line} = 1;
  162. next;
  163. }
  164. # Split and recurse on libraries (third value is the lib path):
  165. my @newlibs = split(/\s+/,$line);
  166. print Dumper(\@newlibs) if $debug;
  167. # Skip if no mapped or directly linked
  168. # Sane output comes with four elements
  169. if (scalar(@newlibs) < 4) {
  170. print "$sep"x$depth if not $uniq;
  171. print $newlibs[0]."\n" if not $uniq;
  172. $uniq{$newlibs[0]} = 1;
  173. next;
  174. }
  175. print "\nI'm gonna enter recursion with $newlibs[2].\n\n" if $debug;
  176. &recurseLibs($newlibs[2], $depth);
  177. }
  178. return;
  179. }
  180. __END__