ab22601b |
1 | #!/bin/bash |
2 | |
3 | IFS=: ldpath=($LD_LIBRARY_PATH) |
4 | while read dir; do |
5 | if [ "${dir:0:1}" == "#" ]; then |
6 | continue |
7 | elif [ -d "$dir" ]; then |
8 | ldpath=$("${LDPATH[@]}" "$dir") |
9 | fi |
10 | done </etc/ld.so.conf |
11 | ldpath=("${ldpath[@]}" /usr/lib /lib) |
12 | IFS=: apath=($PATH) |
13 | |
14 | findlib() { |
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 | |
24 | findbin() { |
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 | |
34 | has() { |
35 | for obj in "${found[@]}"; do |
36 | if [ "$obj" = "$1" ]; then return 0; fi |
37 | done |
38 | return 1 |
39 | } |
40 | |
41 | excluded() { |
42 | for obj in "${exclude[@]}"; do |
43 | if [ -d "$obj" ] && [[ "$1" == "$obj"* ]]; then return 0; fi |
44 | if [ "$1" = "$obj" ]; then return 0; fi |
45 | done |
46 | return 1 |
47 | } |
48 | |
49 | examine() { |
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 |
55 | echo "lddot: $lib: not found" >&2 |
56 | rm -f "$tfile" |
57 | return 1 |
58 | fi |
59 | lib="$lib2" |
60 | unset lib2 |
61 | if excluded "$lib"; then continue; fi |
62 | echo "\"$1\" -> \"$lib\";" |
63 | if has "$lib"; then continue; fi |
64 | found=("${found[@]}" "$lib") |
65 | examine "$lib" |
66 | done <"$tfile" |
67 | rm -f "$tfile" |
68 | return 0 |
69 | } |
70 | |
71 | found=() |
72 | exclude=() |
73 | programs=() |
74 | |
75 | while [ $# -gt 0 ]; do |
76 | arg="$1" |
77 | shift |
78 | case "$arg" in |
79 | -x) |
80 | exclude=("${exclude[@]}" "$1") |
81 | shift |
82 | ;; |
83 | *) |
84 | programs=("${programs[@]}" "$arg") |
85 | esac |
86 | done |
87 | |
88 | if [ ${#programs[@]} -lt 1 ]; then |
89 | echo "usage: lddot [-x EXCLUDED] PROGRAM..." >&2 |
90 | exit 1 |
91 | fi |
92 | |
93 | echo "digraph {" |
94 | rv=0 |
95 | for bin in "${programs[@]}"; do |
96 | if [[ "$bin" != */* ]]; then |
97 | if ! bin2="$(findbin "$bin")"; then |
98 | echo "lddot: $bin: not found" >&2 |
99 | rv=1 |
100 | continue |
101 | fi |
102 | bin="$bin2" |
103 | unset bin2 |
104 | fi |
105 | if [ ! -r "$bin" ]; then |
106 | echo "lddot: $bin: not readable" >&2 |
107 | rv=1 |
108 | continue |
109 | fi |
110 | if ! examine "$bin"; then rv=1; fi |
111 | done |
112 | echo "}" |
113 | |
114 | exit $rv |