#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72V src/bos/usr/bin/svcmd/ldd/ldd.sh 1.8.1.5 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2001,2020 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)32 1.8.1.5 src/bos/usr/bin/svcmd/ldd/ldd.sh, uw7cmds, bos72V, v2020_10A1 2/17/20 01:26:34 # # # Usage: ldd [ -Llibpath ] executable DSPMSG=/usr/bin/dspmsg BASENAME=/usr/bin/basename RM=/usr/bin/rm DUMP=/usr/bin/dump function display_usage { $DSPMSG -s 1 sysvldd.cat 1 'Usage: ldd [ -Llibpath ] executable\n' 1>&2 exit 2 } stack_limit=4096 # Maximum array size permitted on ksh errors=0 whoami=$($BASENAME $0) # gather options Libpath_opt= while getopts :L: opt do case $opt in L) Libpath_opt=$OPTARG;; ?) display_usage;; esac done shift $(($OPTIND - 1)) # Print usage if the number of arguments are not equal to 1. if [ $# -ne 1 ] then display_usage fi trap 'cleanup' 0 1 2 15 # Delete temporary files cleanup() { $RM -rf $LDD_DIR $LOADED_FILE exit $1 } # Make sure a file is an executable XCOFF file. # Return value: 0 if file is executable XCOFF # 1 otherwise function chk_file { if [ \! -s $1 ] then $DSPMSG -s 1 sysvldd.cat 2 \ 'ldd: %s: File does not exist or is empty.\n' $1 1>&2 return 1 fi if LANG=C $DUMP -o $1 2>/dev/null | /usr/bin/grep "^$1\[" >/dev/null then $DSPMSG -s 1 sysvldd.cat 3 \ 'ldd: %s: File is an archive.\n' $1 1>&2 return 1 fi if [ $(LANG=C $DUMP -o $1 2>/dev/null | /usr/bin/wc -l) = 0 ] then $DSPMSG -s 1 sysvldd.cat 4 \ 'ldd: %s: File is not an executable XCOFF file.\n' $1 1>&2 return 1 fi return 0 } # Determine the LIBPATH information from XCOFF loader section. function get_libpath { LANG=C $DUMP -Hp $1 | grep -e "^0 " | cut -c8- } # Determine the Libraries used -- from XCOFF loader section. # Arguments: $1: Directory name of object to be loaded # $2: Name of object being loaded # $3: Member name of object function get_libs { f=$1/$2 if [ \! -z "$3" ] then (cd $LDD_DIR/extract; $RM -f $LDD_DIR/extract/* 2>/dev/null if [[ $f = /* ]] then /usr/bin/ar x $f $3; else /usr/bin/ar x $OLDPWD/$f $3; fi;) f=$LDD_DIR/extract/$3 fi LANG=C $DUMP -Hp $f \ | /usr/bin/awk $DBG ' /^0 / { look=1; Libpath=$NF next; } look==0 {next;} { print Libpath if (substr($0, 8, 1) != " ") printf "%s\n%s\n%s\n", $2, $3, $4 else printf "\n%s\n%s\n", $2, $3 }' } # Find a particular object by searching a list of directories. # Arguments: $1: Libpath information from object requesting object # $2: Directory name of object to be loaded # $3: Basename of object to be loaded # Returns 1 if object cannot be found. Sets global variables object_dir, # and object_base find_object () { object_dir='' saved_ifs=$IFS IFS=":" for f in ${2:-$Libpath_dirs:$1} do if [ -f $f/$3 ] then object_dir=$f object_base=$3 break; fi done IFS=$saved_ifs if [ -z "$object_dir" ] then return 1 else return 0 fi } # Calls find_object internally to locate the objects. load_object() { Mem=${new_mem:+($new_mem)} Dir=${new_dir:+$new_dir/} if [ -z "$new_mem" ] then if [[ "$new_dir" = / && "$new_base" = unix ]] then if [ "$unix_loaded" != 1 ] then print "\t /unix" unix_loaded=1 fi return 1 elif [ -z "$new_dir" ] then if [ "$new_base" = . ] then return 1 elif [ "$new_base" = .. ] then return 1 fi fi fi if find_object "$new_libpath" "$new_dir" "$new_base" "$new_mem" then : else $DSPMSG -s 1 sysvldd.cat 5 'Cannot find %s\n' $Dir$new_base$Mem 1>&2 errors=1 return 2 fi f="$object_dir/$object_base$Mem" saved_ifs=$IFS IFS=":" fbase="$object_dir/$object_base" fs=$(/usr/bin/df $fbase | /usr/bin/sed -n -e '2{s/ .*$//p;q;}') inode=$(/bin/ls -i $fbase | /usr/bin/awk '{print $1;}') if /usr/bin/grep -s "^$fs $inode $new_mem\$" $LOADED_FILE > /dev/null then return 1 # Already loaded fi print "$fs $inode $new_mem" >> $LOADED_FILE IFS=$saved_ifs if [ -z "$Dir" ] then print '\t' "$f" elif [ ! `$BASENAME $f` == `$BASENAME $filename` ]; then print '\t' "$f" fi return 0 } # Calls get_libs internally to get the list of libraries used by the binary. list_libraries () { while ((low_index <= load_index)) do new_libpath=${libpath[low_index]} new_dir=${dirs[low_index]} new_base=${bases[low_index]} new_mem=${mems[low_index]} ((low_index+=1)) saved_ifs=$IFS IFS="" if load_object then get_libs "$object_dir" "$object_base" "$new_mem" | while read libpath do IFS=$saved_ifs read lib if [ "$lib" != / ]; then lib=${lib%/}; fi read base read mem ((load_index+=1)) if ((load_index>=$stack_limit)) then $DSPMSG -s 1 sysvldd.cat 7 'Stack Overflow\n' 1>&2 exit 3 fi libpath[$load_index]=$libpath dirs[$load_index]=$lib bases[$load_index]=$base mems[$load_index]=$mem done fi if ((low_index>=$stack_limit)) then $DSPMSG -s 1 sysvldd.cat 7 'Stack Overflow\n' 1>&2 exit 3 fi done } ########################################################### ########################## Main ########################### # First command line operand is the file being checked. filename=$1 typeset -i low_index=0 typeset -i load_index=0 if [ -z "$TMPDIR" ] then TMPDIR=/tmp/tmpdir$$ LDD_DIR=$TMPDIR else LDD_DIR=$TMPDIR/ldd$$ fi /usr/bin/mkdir -p $LDD_DIR/extract 2>/dev/null LOADED_FILE=$TMPDIR/loaded$$ ###### Defect 1020236 , Based on the input file , OBJECT_MODE is exported so that proper library will be picked ###### if LC_ALL=C /usr/bin/file $filename 2>/dev/null | /usr/bin/grep "64-bit XCOFF" >/dev/null then export OBJECT_MODE=64 else export OBJECT_MODE=32 fi if chk_file $filename then : else exit 2 fi Libpath_dirs=$(get_libpath $filename) #Remove trailing white space. Libpath_dirs="$(echo "${Libpath_dirs}" | sed -e 's/[[:space:]]*$//')" Libpath_dirs=${Libpath_opt:-$LIBPATH}:$Libpath_dirs: bases[0]=$($BASENAME $filename) d=${filename%${bases[0]}} if [ "$d" != "/" ] then d=${d%/} if [ -z "$d" -o "$d" = "$filename" ]; then d='.'; fi fi dirs[0]=$d member[0]='' > $LOADED_FILE # Create or truncate file. $DSPMSG -s 1 sysvldd.cat 6 '%s needs:\n' $filename list_libraries #Cleanup of temporary files $RM -rf $LDD_DIR $LOADED_FILE exit $errors