123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #!/bin/bash
- if [[ $# < 2 ]]; then
- echo "Usage:"
- echo " $0 [vmlinux] [base path] [modules path]"
- exit 1
- fi
- vmlinux=$1
- basepath=$2
- modpath=$3
- declare -A cache
- declare -A modcache
- parse_symbol() {
-
-
-
-
-
- if [[ $module == "" ]] ; then
- local objfile=$vmlinux
- elif [[ "${modcache[$module]+isset}" == "isset" ]]; then
- local objfile=${modcache[$module]}
- else
- [[ $modpath == "" ]] && return
- local objfile=$(find "$modpath" -name $module.ko -print -quit)
- [[ $objfile == "" ]] && return
- modcache[$module]=$objfile
- fi
-
- symbol=${symbol#\(}
- symbol=${symbol%\)}
-
- local name=${symbol%+*}
-
-
-
- if [[ "${cache[$module,$name]+isset}" == "isset" ]]; then
- local base_addr=${cache[$module,$name]}
- else
- local base_addr=$(nm "$objfile" | grep -i ' t ' | awk "/ $name\$/ {print \$1}" | head -n1)
- cache[$module,$name]="$base_addr"
- fi
-
-
- local expr=${symbol%/*}
-
-
- expr=${expr/$name/0x$base_addr}
-
- expr=$((expr))
- local address=$(printf "%x\n" "$expr")
-
-
- if [[ "${cache[$module,$address]+isset}" == "isset" ]]; then
- local code=${cache[$module,$address]}
- else
- local code=$(addr2line -i -e "$objfile" "$address")
- cache[$module,$address]=$code
- fi
-
-
-
- if [[ $code == "??:0" ]]; then
- return
- fi
-
- code=${code//$basepath/""}
-
- code=${code//$'\n'/' '}
-
- symbol="$name ($code)"
- }
- decode_code() {
- local scripts=`dirname "${BASH_SOURCE[0]}"`
- echo "$1" | $scripts/decodecode
- }
- handle_line() {
- local words
-
- read -a words <<<"$1"
-
-
-
-
- local last=$(( ${#words[@]} - 1 ))
- for i in "${!words[@]}"; do
-
- if [[ ${words[$i]} =~ \[\<([^]]+)\>\] ]]; then
- unset words[$i]
- fi
-
- if [[ ${words[$i]} == \[ && ${words[$i+1]} == *\] ]]; then
- unset words[$i]
- words[$i+1]=$(printf "[%13s\n" "${words[$i+1]}")
- fi
- done
- if [[ ${words[$last]} =~ \[([^]]+)\] ]]; then
- module=${words[$last]}
- module=${module#\[}
- module=${module%\]}
- symbol=${words[$last-1]}
- unset words[$last-1]
- else
-
- symbol=${words[$last]}
- module=
- fi
- unset words[$last]
- parse_symbol
-
- echo "${words[@]}" "$symbol $module"
- }
- while read line; do
-
- if [[ $line =~ \[\<([^]]+)\>\] ]]; then
-
- handle_line "$line"
-
- elif [[ $line == *Code:* ]]; then
- decode_code "$line"
- else
-
- echo "$line"
- fi
- done
|