Improve lddot a bit more.
[utils.git] / lddot
CommitLineData
ab22601b 1#!/bin/bash
2
3IFS=: ldpath=($LD_LIBRARY_PATH)
4while read dir; do
5 if [ "${dir:0:1}" == "#" ]; then
6 continue
7 elif [ -d "$dir" ]; then
5212b565 8 ldpath=("${ldpath[@]}" "$dir")
ab22601b 9 fi
10done </etc/ld.so.conf
11ldpath=("${ldpath[@]}" /usr/lib /lib)
12IFS=: apath=($PATH)
13
14findlib() {
15 for d in "${ldpath[@]}"; do
16 if [ -r "$d/$1" ]; then
17 echo "$d/$1"
18 return 0
19 fi
20 done
21 return 1
22}
23
24findbin() {
25 for d in "${apath[@]}"; do
26 if [ -r "$d/$1" ]; then
27 echo "$d/$1"
28 return 0
29 fi
30 done
31 return 1
32}
33
34has() {
35 for obj in "${found[@]}"; do
36 if [ "$obj" = "$1" ]; then return 0; fi
37 done
38 return 1
39}
40
41excluded() {
42 for obj in "${exclude[@]}"; do
43 if [ -d "$obj" ] && [[ "$1" == "$obj"* ]]; then return 0; fi
572b5165 44 if [ "$1" -ef "$obj" ]; then return 0; fi
ab22601b 45 done
46 return 1
47}
48
49examine() {
50 local tfile lib lib2
51 tfile="$(mktemp /tmp/lddotXXXXXX)"
52 objdump -p "$1" | sed -n 's/^.*NEEDED \+\(lib.*\)/\1/p' >"$tfile"
53 while read lib; do
54 if ! lib2="$(findlib "$lib")"; then
5212b565 55 echo "\"$lib\" [ color=red ];"
442d5c52 56 echo "lddot: $lib: not found" >&2
5212b565 57 echo "\"$1\" -> \"$lib\";"
58 continue
ab22601b 59 fi
60 lib="$lib2"
61 unset lib2
62 if excluded "$lib"; then continue; fi
63 echo "\"$1\" -> \"$lib\";"
64 if has "$lib"; then continue; fi
65 found=("${found[@]}" "$lib")
66 examine "$lib"
67 done <"$tfile"
68 rm -f "$tfile"
69 return 0
70}
71
72found=()
73exclude=()
74programs=()
75
76while [ $# -gt 0 ]; do
77 arg="$1"
78 shift
79 case "$arg" in
80 -x)
81 exclude=("${exclude[@]}" "$1")
82 shift
83 ;;
84 *)
85 programs=("${programs[@]}" "$arg")
86 esac
87done
88
89if [ ${#programs[@]} -lt 1 ]; then
90 echo "usage: lddot [-x EXCLUDED] PROGRAM..." >&2
91 exit 1
92fi
93
94echo "digraph {"
95rv=0
96for bin in "${programs[@]}"; do
97 if [[ "$bin" != */* ]]; then
98 if ! bin2="$(findbin "$bin")"; then
99 echo "lddot: $bin: not found" >&2
100 rv=1
101 continue
102 fi
103 bin="$bin2"
104 unset bin2
105 fi
106 if [ ! -r "$bin" ]; then
107 echo "lddot: $bin: not readable" >&2
108 rv=1
109 continue
110 fi
572b5165 111 echo "\"$bin\" [ shape=box ];"
ab22601b 112 if ! examine "$bin"; then rv=1; fi
113done
114echo "}"
115
116exit $rv