#!/bin/bash # (c) 2014, Sasha Levin #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 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 # before. expr=${expr/$name/0x$base_addr} # Evaluate it to find the actual address expr=$((expr)) local address=$(printf "%x\n" "$expr") # Pass it to addr2line to get filename and line number # Could get more than one result 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 # addr2line doesn't return a proper error code if it fails, so # we detect it using the value it prints so that we could preserve # the offset/size into the function and bail out if [[ $code == "??:0" ]]; then return fi # Strip out the base of the path code=${code//$basepath/""} # In the case of inlines, move everything to same line code=${code//$'\n'/' '} # Replace old address with pretty line numbers symbol="$name ($code)" } decode_code() { local scripts=`dirname "${BASH_SOURCE[0]}"` echo "$1" | $scripts/decodecode } handle_line() { local words # Tokenize read -a words <<<"$1" # Remove hex numbers. Do it ourselves until it happens in the # kernel # We need to know the index of the last element before we # remove elements because arrays are sparse local last=$(( ${#words[@]} - 1 )) for i in "${!words[@]}"; do # Remove the address if [[ ${words[$i]} =~ \[\<([^]]+)\>\] ]]; then unset words[$i] fi # Format timestamps with tabs 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 # The symbol is the last element, process it symbol=${words[$last]} module= fi unset words[$last] parse_symbol # modifies $symbol # Add up the line number to the symbol echo "${words[@]}" "$symbol $module" } while read line; do # Let's see if we have an address in the line if [[ $line =~ \[\<([^]]+)\>\] ]] || [[ $line =~ [^+\ ]+\+0x[0-9a-f]+/0x[0-9a-f]+ ]]; then # Translate address to line numbers handle_line "$line" # Is it a code line? elif [[ $line == *Code:* ]]; then decode_code "$line" else # Nothing special in this line, show it as is echo "$line" fi done c2fafec57fcb55b5d69bcf293b1a5fc8b3'>alphascale,asm9260.h2695logplain -rw-r--r--at91.h751logplain -rw-r--r--ath79-clk.h479logplain -rw-r--r--axis,artpec6-clkctrl.h1112logplain -rw-r--r--bcm-cygnus.h3135logplain -rw-r--r--bcm-ns2.h2915logplain -rw-r--r--bcm-nsp.h2148logplain -rw-r--r--bcm21664.h1984logplain -rw-r--r--bcm281xx.h2456logplain -rw-r--r--bcm2835-aux.h635logplain -rw-r--r--bcm2835.h1962logplain -rw-r--r--berlin2.h1034logplain -rw-r--r--berlin2q.h695logplain -rw-r--r--clps711x-clock.h718logplain -rw-r--r--efm32-cmu.h1112logplain -rw-r--r--exynos-audss-clk.h597logplain -rw-r--r--exynos3250.h9083logplain -rw-r--r--exynos4.h8284logplain -rw-r--r--exynos4415.h9828logplain -rw-r--r--exynos5250.h4616logplain -rw-r--r--exynos5260-clk.h14876logplain -rw-r--r--exynos5410.h1689logplain -rw-r--r--exynos5420.h6857logplain -rw-r--r--exynos5433.h45372logplain -rw-r--r--exynos5440.h1141logplain -rw-r--r--exynos7-clk.h5281logplain -rw-r--r--gxbb-aoclkc.h2866logplain -rw-r--r--gxbb-clkc.h592logplain -rw-r--r--hi3516cv300-clock.h1668logplain -rw-r--r--hi3519-clock.h1328logplain -rw-r--r--hi3620-clock.h4496logplain -rw-r--r--hi6220-clock.h4508logplain -rw-r--r--hip04-clock.h1137logplain -rw-r--r--histb-clock.h2012logplain -rw-r--r--hix5hd2-clock.h2415logplain -rw-r--r--imx1-clock.h1055logplain -rw-r--r--imx21-clock.h2461logplain -rw-r--r--imx27-clock.h3494logplain -rw-r--r--imx5-clock.h7212logplain -rw-r--r--imx6qdl-clock.h9593logplain -rw-r--r--imx6sl-clock.h5849logplain -rw-r--r--imx6sx-clock.h9099logplain -rw-r--r--imx6ul-clock.h8203logplain -rw-r--r--imx7d-clock.h15974logplain -rw-r--r--jz4740-cgu.h1028logplain -rw-r--r--jz4780-cgu.h2470logplain -rw-r--r--lpc18xx-ccu.h2134logplain -rw-r--r--lpc18xx-cgu.h1142logplain -rw-r--r--lpc32xx-clock.h1633logplain -rw-r--r--lsi,axm5516-clks.h974logplain -rw-r--r--marvell,mmp2.h2022logplain -rw-r--r--marvell,pxa168.h1654logplain -rw-r--r--marvell,pxa1928.h1535logplain -rw-r--r--marvell,pxa910.h1598logplain -rw-r--r--maxim,max77620.h632logplain -rw-r--r--maxim,max77686.h648logplain -rw-r--r--maxim,max77802.h630logplain -rw-r--r--meson8b-clkc.h523logplain -rw-r--r--microchip,pic32-clock.h1150logplain -rw-r--r--mpc512x-clock.h2236logplain -rw-r--r--mt2701-clk.h13832logplain -rw-r--r--mt8135-clk.h5641logplain -rw-r--r--mt8173-clk.h9293logplain -rw-r--r--oxsemi,ox810se.h1002logplain -rw-r--r--oxsemi,ox820.h1203logplain -rw-r--r--pistachio-clk.h4863logplain -rw-r--r--pxa-clock.h1715logplain -rw-r--r--qcom,gcc-apq8084.h12872logplain -rw-r--r--qcom,gcc-ipq4019.h5423logplain -rw-r--r--qcom,gcc-ipq806x.h8574logplain -rw-r--r--qcom,gcc-mdm9615.h9497logplain -rw-r--r--qcom,gcc-msm8660.h7932logplain -rw-r--r--qcom,gcc-msm8916.h6190logplain -rw-r--r--qcom,gcc-msm8960.h9342logplain -rw-r--r--qcom,gcc-msm8974.h12340logplain -rw-r--r--qcom,gcc-msm8994.h4858logplain -rw-r--r--qcom,gcc-msm8996.h12575logplain -rw-r--r--qcom,lcc-ipq806x.h899logplain -rw-r--r--qcom,lcc-mdm9615.h1701logplain -rw-r--r--qcom,lcc-msm8960.h1616logplain -rw-r--r--qcom,mmcc-apq8084.h5722logplain -rw-r--r--qcom,mmcc-msm8960.h4109logplain -rw-r--r--qcom,mmcc-msm8974.h5223logplain -rw-r--r--qcom,mmcc-msm8996.h9403logplain -rw-r--r--qcom,rpmcc.h2101logplain -rw-r--r--r7s72100-clock.h1218logplain -rw-r--r--r8a73a4-clock.h1596logplain -rw-r--r--r8a7740-clock.h1992logplain -rw-r--r--r8a7743-cpg-mssr.h1269logplain -rw-r--r--r8a7745-cpg-mssr.h1298logplain -rw-r--r--r8a7778-clock.h1855logplain -rw-r--r--r8a7779-clock.h1647logplain -rw-r--r--r8a7790-clock.h4367logplain -rw-r--r--r8a7791-clock.h4388logplain -rw-r--r--r8a7792-clock.h2562logplain -rw-r--r--r8a7793-clock.h4561logplain -rw-r--r--r8a7794-clock.h3679logplain -rw-r--r--r8a7795-cpg-mssr.h1890logplain -rw-r--r--r8a7796-cpg-mssr.h2066logplain -rw-r--r--renesas-cpg-mssr.h542logplain -rw-r--r--rk1108-cru.h6605logplain -rw-r--r--rk3036-cru.h4584logplain -rw-r--r--rk3066a-cru.h1068logplain -rw-r--r--rk3188-cru-common.h6105logplain -rw-r--r--rk3188-cru.h1435logplain