/[gentoo-projects]/pax-utils/lddtree.sh
Gentoo

Diff of /pax-utils/lddtree.sh

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.10 Revision 1.11
1#!/bin/bash 1#!/bin/bash
2# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.sh,v 1.10 2011/03/23 02:23:34 vapier Exp $ 2# $Header: /var/cvsroot/gentoo-projects/pax-utils/lddtree.sh,v 1.11 2012/11/03 00:06:10 vapier Exp $
3 3
4argv0=${0##*/} 4argv0=${0##*/}
5 5
6usage() { 6usage() {
7 cat <<-EOF 7 cat <<-EOF
21 echo "${argv0}: $*" 1>&2 21 echo "${argv0}: $*" 1>&2
22 ret=1 22 ret=1
23 return 1 23 return 1
24} 24}
25 25
26unset c_last_needed_by 26elf_specs() {
27unset c_ldso_paths 27 scanelf -BF '#F%a %M %D %I' "$1"
28}
29
30lib_paths_fallback="/lib* /usr/lib* /usr/local/lib*"
31c_ldso_paths_loaded='false'
28find_elf() { 32find_elf() {
33 _find_elf=''
34
29 local elf=$1 needed_by=$2 35 local elf=$1 needed_by=$2
30 if [[ ${elf} == */* ]] && [[ -e ${elf} ]] ; then 36 if [[ ${elf} == */* ]] && [[ -e ${elf} ]] ; then
31 echo "${elf}" 37 _find_elf=${elf}
32 return 0 38 return 0
33 else 39 else
34 check_paths() { 40 check_paths() {
35 local elf=$1 ; shift 41 local elf=$1 ; shift
36 local path 42 local path pe
37 for path in "$@" ; do 43 for path ; do
38 # XXX: This lacks ELF EM/EI_CLASS/EI_DATA/... checking (multilib) 44 pe="${path%/}/${elf#/}"
39 if [[ -e ${path}/${elf} ]] ; then 45 if [[ -e ${pe} ]] ; then
40 echo "${path}/${elf}" 46 if [[ $(elf_specs "${pe}") == "${elf_specs}" ]] ; then
47 _find_elf=${pe}
41 return 0 48 return 0
49 fi
42 fi 50 fi
43 done 51 done
44 return 1 52 return 1
45 } 53 }
46 54
60 [[ ${path} == *:* ]] || break 68 [[ ${path} == *:* ]] || break
61 path=${path#*:} 69 path=${path#*:}
62 done 70 done
63 fi 71 fi
64 72
65 if [[ -z ${c_ldso_paths} ]] ; then 73 if ! ${c_ldso_paths_loaded} ; then
74 c_ldso_paths_loaded='true'
75 c_ldso_paths=()
66 if [[ -r /etc/ld.so.conf ]] ; then 76 if [[ -r /etc/ld.so.conf ]] ; then
67 read_ldso_conf() { 77 read_ldso_conf() {
68 local line p 78 local line p
69 for p in "$@" ; do 79 for p ; do
70 # if the glob didnt match anything #360041, 80 # if the glob didnt match anything #360041,
71 # or the files arent readable, skip it 81 # or the files arent readable, skip it
72 [[ -r ${p} ]] || continue 82 [[ -r ${p} ]] || continue
73 while read line ; do 83 while read line ; do
74 case ${line} in 84 case ${line} in
75 "#"*) ;; 85 "#"*) ;;
76 "include "*) read_ldso_conf ${line#* } ;; 86 "include "*) read_ldso_conf ${line#* } ;;
77 *) c_ldso_paths="${c_ldso_paths} ${line}" ;; 87 *) c_ldso_paths+=( "${line}" ) ;;
78 esac 88 esac
79 done <"${p}" 89 done <"${p}"
80 done 90 done
81 } 91 }
82 # the 'include' command is relative 92 # the 'include' command is relative
83 pushd /etc >/dev/null 93 pushd /etc >/dev/null
84 read_ldso_conf /etc/ld.so.conf 94 read_ldso_conf /etc/ld.so.conf
85 popd >/dev/null 95 popd >/dev/null
86 fi 96 fi
87 : ${c_ldso_paths:= }
88 fi 97 fi
89 if [[ ${c_ldso_paths} != " " ]] ; then 98 if [[ ${#c_ldso_paths[@]} -gt 0 ]] ; then
90 check_paths "${elf}" ${c_ldso_paths} && return 0 99 check_paths "${elf}" "${c_ldso_paths[@]}" && return 0
91 fi 100 fi
92 101
93 check_paths "${elf}" /lib* /usr/lib* /usr/local/lib* && return 0 102 check_paths "${elf}" ${lib_paths_ldso:-${lib_paths_fallback}} && return 0
94 fi 103 fi
95 return 1 104 return 1
96} 105}
97 106
98show_elf() { 107show_elf() {
99 local elf=$1 indent=$2 parent_elfs=$3 108 local elf=$1 indent=$2 parent_elfs=$3
100 local rlib lib libs 109 local rlib lib libs
101 local interp resolved=$(find_elf "${elf}") 110 local interp resolved
111 find_elf "${elf}"
112 resolved=${_find_elf}
102 elf=${elf##*/} 113 elf=${elf##*/}
103 114
104 printf "%${indent}s%s => " "" "${elf}" 115 printf "%${indent}s%s => " "" "${elf}"
105 if [[ ,${parent_elfs}, == *,${elf},* ]] ; then 116 if [[ ,${parent_elfs}, == *,${elf},* ]] ; then
106 printf "!!! circular loop !!!\n" "" 117 printf "!!! circular loop !!!\n" ""
107 return 118 return
108 fi 119 fi
109 parent_elfs="${parent_elfs},${elf}" 120 parent_elfs="${parent_elfs},${elf}"
110 printf "${resolved:-not found}" 121 printf "${resolved:-not found}"
111 if [[ ${indent} -eq 0 ]] ; then 122 if [[ ${indent} -eq 0 ]] ; then
123 elf_specs=$(elf_specs "${resolved}")
112 interp=$(scanelf -qF '#F%i' "${resolved}") 124 interp=$(scanelf -qF '#F%i' "${resolved}")
125
113 printf " (interpreter => ${interp:-none})" 126 printf " (interpreter => ${interp:-none})"
127 if [[ -r ${interp} ]] ; then
128 # Extract the default lib paths out of the ldso.
129 lib_paths_ldso=$(strings "${interp}" | grep '^/.*lib')
130 lib_paths_ldso=${lib_paths_ldso//:/ }
131 fi
114 interp=${interp##*/} 132 interp=${interp##*/}
115 fi 133 fi
116 printf "\n" 134 printf "\n"
117 135
118 [[ -z ${resolved} ]] && return 136 [[ -z ${resolved} ]] && return
126 fi 144 fi
127 145
128 for lib in ${libs//,/ } ; do 146 for lib in ${libs//,/ } ; do
129 lib=${lib##*/} 147 lib=${lib##*/}
130 [[ ,${my_allhits}, == *,${lib},* ]] && continue 148 [[ ,${my_allhits}, == *,${lib},* ]] && continue
131 rlib=$(find_elf "${lib}" "${resolved}") 149 find_elf "${lib}" "${resolved}"
150 rlib=${_find_elf}
132 show_elf "${rlib:-${lib}}" $((indent + 4)) "${parent_elfs}" 151 show_elf "${rlib:-${lib}}" $((indent + 4)) "${parent_elfs}"
133 done 152 done
134} 153}
135 154
136# XXX: internal hack 155# XXX: internal hack
151[[ -z $1 ]] && usage 1 170[[ -z $1 ]] && usage 1
152 171
153${SET_X} && set -x 172${SET_X} && set -x
154 173
155ret=0 174ret=0
156for elf in "$@" ; do 175for elf ; do
176 unset lib_paths_ldso
177 unset c_last_needed_by
157 if [[ ! -e ${elf} ]] ; then 178 if [[ ! -e ${elf} ]] ; then
158 error "${elf}: file does not exist" 179 error "${elf}: file does not exist"
159 elif [[ ! -r ${elf} ]] ; then 180 elif [[ ! -r ${elf} ]] ; then
160 error "${elf}: file is not readable" 181 error "${elf}: file is not readable"
161 elif [[ -d ${elf} ]] ; then 182 elif [[ -d ${elf} ]] ; then

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

  ViewVC Help
Powered by ViewVC 1.1.20