Added lddot.
authorfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Sun, 2 Sep 2007 22:25:54 +0000 (22:25 +0000)
committerfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Sun, 2 Sep 2007 22:25:54 +0000 (22:25 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/utils@1101 959494ce-11ee-0310-bf91-de5d638817bd

lddot [new file with mode: 0755]

diff --git a/lddot b/lddot
new file mode 100755 (executable)
index 0000000..5c3568c
--- /dev/null
+++ b/lddot
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+IFS=: ldpath=($LD_LIBRARY_PATH)
+while read dir; do
+    if [ "${dir:0:1}" == "#" ]; then
+       continue
+    elif [ -d "$dir" ]; then
+       ldpath=$("${LDPATH[@]}" "$dir")
+    fi
+done </etc/ld.so.conf
+ldpath=("${ldpath[@]}" /usr/lib /lib)
+IFS=: apath=($PATH)
+
+findlib() {
+    for d in "${ldpath[@]}"; do
+       if [ -r "$d/$1" ]; then
+           echo "$d/$1"
+           return 0
+       fi
+    done
+    return 1
+}
+
+findbin() {
+    for d in "${apath[@]}"; do
+       if [ -r "$d/$1" ]; then
+           echo "$d/$1"
+           return 0
+       fi
+    done
+    return 1
+}
+
+has() {
+    for obj in "${found[@]}"; do
+       if [ "$obj" = "$1" ]; then return 0; fi
+    done
+    return 1
+}
+
+excluded() {
+    for obj in "${exclude[@]}"; do
+       if [ -d "$obj" ] && [[ "$1" == "$obj"* ]]; then return 0; fi
+       if [ "$1" = "$obj" ]; then return 0; fi
+    done
+    return 1
+}
+
+examine() {
+    local tfile lib lib2
+    tfile="$(mktemp /tmp/lddotXXXXXX)"
+    objdump -p "$1" | sed -n 's/^.*NEEDED \+\(lib.*\)/\1/p' >"$tfile"
+    while read lib; do
+       if ! lib2="$(findlib "$lib")"; then
+           echo "lddot: $lib: not found" >&2
+           rm -f "$tfile"
+           return 1
+       fi
+       lib="$lib2"
+       unset lib2
+       if excluded "$lib"; then continue; fi
+       echo "\"$1\" -> \"$lib\";"
+       if has "$lib"; then continue; fi
+       found=("${found[@]}" "$lib")
+       examine "$lib"
+    done <"$tfile"
+    rm -f "$tfile"
+    return 0
+}
+
+found=()
+exclude=()
+programs=()
+
+while [ $# -gt 0 ]; do
+    arg="$1"
+    shift
+    case "$arg" in
+       -x)
+           exclude=("${exclude[@]}" "$1")
+           shift
+           ;;
+       *)
+           programs=("${programs[@]}" "$arg")
+    esac
+done
+
+if [ ${#programs[@]} -lt 1 ]; then
+    echo "usage: lddot [-x EXCLUDED] PROGRAM..." >&2
+    exit 1
+fi
+
+echo "digraph {"
+rv=0
+for bin in "${programs[@]}"; do
+    if [[ "$bin" != */* ]]; then
+       if ! bin2="$(findbin "$bin")"; then
+           echo "lddot: $bin: not found" >&2
+           rv=1
+           continue
+       fi
+       bin="$bin2"
+       unset bin2
+    fi
+    if [ ! -r "$bin" ]; then
+       echo "lddot: $bin: not readable" >&2
+       rv=1
+       continue
+    fi
+    if ! examine "$bin"; then rv=1; fi
+done
+echo "}"
+
+exit $rv