Source
# SPDX-License-Identifier: GPL-2.0
# (c) 2014, Sasha Levin <sasha.levin@oracle.com>
#set -x
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() {
# The structure of symbol at this point is:
# ([name]+[offset]/[total length])
#
# For example:
# do_basic_setup+0x9c/0xbf
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
# Remove the englobing parenthesis
symbol=${symbol#\(}
symbol=${symbol%\)}
# Strip segment
local segment
if [[ $symbol == *:* ]] ; then
segment=${symbol%%:*}:
symbol=${symbol#*:}
fi
# Strip the symbol name so that we could look it up
local name=${symbol%+*}
# Use 'nm vmlinux' to figure out the base address of said symbol.
# It's actually faster to call it every time than to load it
# all into bash.
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
# Let's start doing the math to get the exact address into the
# symbol. First, strip out the symbol total length.
local expr=${symbol%/*}
# Now, replace the symbol name with the base address we found