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 |
5212b565 |
8 | ldpath=("${ldpath[@]}" "$dir") |
ab22601b |
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 |
572b5165 |
44 | if [ "$1" -ef "$obj" ]; then return 0; fi |
ab22601b |
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 |
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 | |
72 | found=() |
73 | exclude=() |
74 | programs=() |
75 | |
76 | while [ $# -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 |
87 | done |
88 | |
89 | if [ ${#programs[@]} -lt 1 ]; then |
90 | echo "usage: lddot [-x EXCLUDED] PROGRAM..." >&2 |
91 | exit 1 |
92 | fi |
93 | |
94 | echo "digraph {" |
95 | rv=0 |
96 | for 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 |
113 | done |
114 | echo "}" |
115 | |
116 | exit $rv |