mirror of
https://github.com/physwizz/a155-U-u1.git
synced 2025-07-25 00:20:43 +00:00
308 lines
10 KiB
Bash
Executable File
308 lines
10 KiB
Bash
Executable File
#! /bin/sh
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# (c) 2019, Google
|
|
progname="${0##*/}"
|
|
|
|
# Add instrumentation to module_init and probe functions.
|
|
|
|
USAGE="USAGE: ${progname} [dir|file]
|
|
|
|
Add debug instrumentation to module_init and probe functions."
|
|
|
|
if [ X"--help" = X"${1}" -o X"{-h}" = X"${1}" ]; then
|
|
echo "${USAGE}" >&2
|
|
exit
|
|
fi
|
|
DIR=.
|
|
if [ 1 = ${#} ]; then
|
|
DIR=${1}
|
|
shift
|
|
fi
|
|
if [ 0 != ${#} ]; then
|
|
echo "Unexpected Argument: ${*}" >&2
|
|
echo >&2
|
|
echo "${USAGE}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# A _real_ embedded tab character
|
|
TAB="`echo | tr '\n' '\t'`"
|
|
# A _real_ embedded escape character
|
|
ESCAPE="`echo | tr '\n' '\033'`"
|
|
# Colours
|
|
RED="${ESCAPE}[38;5;196m"
|
|
ORANGE="${ESCAPE}[38;5;255:165:0m"
|
|
BLUE="${ESCAPE}[35m"
|
|
NORMAL="${ESCAPE}[0m"
|
|
|
|
TMP=`mktemp -d`
|
|
|
|
# ${file} ${call} and ${symbol} input
|
|
SYMBOLS=" "
|
|
add_debug_printk()
|
|
{
|
|
message="printk(KERN_WARNING \"${file##*/}:"
|
|
if [ -z "${call#select}" ]; then
|
|
# We need uniqueness for discovery, so instead of truth of __func__ to
|
|
# cover any of our mistakes(!), we select the expectation.
|
|
message+="${symbol}: ENTER\\\\n\");"
|
|
else
|
|
message+="%s:${call}: ENTER\\\\n\", __func__);"
|
|
fi
|
|
if grep "${TAB}${message%%\\*}" ${file} >/dev/null; then
|
|
if [ "${SYMBOLS}" == "${SYMBOLS#* ${symbol}:${call#select}}" ]; then
|
|
echo INFO: already ${file} instrumented ${call#select} ${symbol} >&2
|
|
SYMBOLS="${SYMBOLS}${symbol}:${call} "
|
|
fi
|
|
return
|
|
fi
|
|
if [ "device_initcall" = "${call}" -o "module_init" = "${call}" -o "module_exit" = "${call}" ] &&
|
|
grep "${TAB}printk(KERN_WARNING \"${file##*/}:%s:\(builtin\|module\)_[a-z]*_driver: ENTER" ${file} >/dev/null; then
|
|
if [ "${SYMBOLS}" == "${SYMBOLS#* ${symbol}:${call#select}}" ]; then
|
|
echo INFO: maybe already ${file} instrumented ${call#select} ${symbol} >&2
|
|
fi
|
|
return
|
|
fi
|
|
sed "/^\(static \)\{0,1\}.* ${symbol}(/ {
|
|
N
|
|
s/^\(static \)\{0,1\}\(.* ${symbol}(\)\(void\)\{0,1\}) {[ ${TAB}]*}\(\n\)/\1\2\3)\4{\4${TAB}${message}\4}\4/
|
|
t exit
|
|
N
|
|
/\/[*][^*]*\$/ {
|
|
: comment_loop
|
|
N
|
|
/\/[*].*[*]\// b comment_done
|
|
b comment_loop
|
|
: comment_done
|
|
/\/[*].*[*]\/\$/ N
|
|
}
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(\n${TAB}\)\(kfree(\|DBG(\|return[ ${TAB}]\|if (\|platform_driver_\|class_destroy(\|pr_info(\|[a-z_0-9]*_register\(_drivers\|_simple\)\{0,1\}(\|[a-z_0-9]*_\(un\|de\)register\(_drivers\|_simple\)\{0,1\}(\|[a-z+_0-9]*_driver(\)/\1${message}&/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(\n${TAB}\)\(DBG(\|return[ ${TAB}]\|if (\|platform_driver_\|pr_info(\|[a-z_0-9]*_register\(_drivers\|_simple\)\{0,1\}(\|[a-z_0-9]*_\(un\|de\)register\(_drivers\|_simple\)\{0,1\}(\)/\1${message}&/
|
|
t exit
|
|
s/\(static void .*\)\(\n${TAB}\)\([a-z].*\)\2}\$/\1\2${message}\2\3\2}/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
t exit
|
|
N
|
|
/printk(KERN_WARNING \"${file##*/}:/ b exit
|
|
s/\(.*\)\(\n${TAB}\)\(.*\n\)\2/&${message}\2/
|
|
: exit
|
|
}
|
|
s/^builtin_\([a-z]*\)_driver(\(${symbol}\));\$/static int __init \2_init(void)\n{\n${TAB}${message}\n${TAB}return \1_driver_register(\&\2);\n}\ndevice_initcall(\2_init);/
|
|
s/^module_\([a-z]*\)_driver(\(${symbol}\));\$/static int __init \2_init(void)\n{\n${TAB}${message}\n${TAB}return \1_driver_register(\&\2);\n}\nmodule_init(\2_init);\n\nstatic void __exit \2_exit(void)\n{\n${TAB}${message}\n${TAB}\1_driver_unregister(\&\2);\n}\nmodule_exit(\2_exit);/
|
|
" ${file} > ${TMP}/${file##*/} &&
|
|
! cmp -s ${file} ${TMP}/${file##*/} &&
|
|
cp ${TMP}/${file##*/} ${file} &&
|
|
(
|
|
echo INFO: modified ${file} to instrument ${call#select} ${symbol} >&2
|
|
echo ${symbol}
|
|
) ||
|
|
(
|
|
files=`grep -lr "^\(static \)\{0,1\}[^ ${TAB}][ %{TAB}_a-zA-Z0-9]* ${symbol}(" ${DIR} |
|
|
sed -e '/[.]h$/d' -e 's@^[.]/@@'`
|
|
if [ X"${file}" != X"${files}" ]; then
|
|
echo "${ORANGE}WARNING${NORMAL}: ${symbol} is in ${files}" >&2
|
|
if [ 1 -eq `echo ${files} | wc -w` ]; then
|
|
file=${files}
|
|
add_debug_printk
|
|
exit
|
|
fi
|
|
fi
|
|
if [ "${SYMBOLS}" == "${SYMBOLS#* ${symbol}:${call#select}}" ]; then
|
|
echo "${RED}ERROR${NORMAL}: failed to modify ${file} to instrument" ${call#select} ${symbol} >&2
|
|
fi
|
|
false
|
|
)
|
|
ret=${?}
|
|
rm -f ${TMP}/${file##*/}
|
|
if [ 0 -eq ${ret} ]; then
|
|
SYMBOLS="${SYMBOLS}${symbol}:${call} "
|
|
fi
|
|
return ${ret}
|
|
}
|
|
|
|
# module_init, module_exit, late_initcall ...
|
|
(
|
|
grep -Hr '^\(builtin_[a-z]*_driver\|module_[a-z]*_driver\|module_\(init\|exit\)\|[a-z]*_initcall\)(' ${DIR} |
|
|
sed -n 's@^[.]/@@
|
|
s/^\([^:]*\):\(builtin_[a-z]*_driver\|module_[a-z]*_driver\|module_init\|module_exit\|[a-z]*_initcall\)(\([^)]*\));$/\1 \2 \3/p' |
|
|
sort -u
|
|
find ${DIR} -name '*.c' |
|
|
while read file; do
|
|
sed -n "/.* [a-z_0-9]*(void)\$/ {
|
|
: loop
|
|
N
|
|
/^[^\n]* [a-z_0-9]*(void)\n.*\n}\$/ {
|
|
/.*platform_\(driver\|device\)_\(un\)\{0,1\}register([&][^)]*).*/ {
|
|
s@^[^\n]* \([a-z_0-9]*\)(void)\n.*@${file} select \1@p
|
|
b exit
|
|
}
|
|
/.*[ ${TAB}]_[a-z]_\(un\)\{0,1\}register_driver([&][^, ${TAB})]*).*/ {
|
|
s@^[^\n]* \([a-z_0-9]*\)(void)\n.*@${file} select \1@p
|
|
b exit
|
|
}
|
|
/.*i2c_\(add\|del\)_driver([&][^)]*).*/ {
|
|
s@^[^\n]* \([a-z_0-9]*\)(void)\n.*@${file} select \1@p
|
|
}
|
|
b exit
|
|
}
|
|
b loop
|
|
}
|
|
: exit" ${file}
|
|
done |
|
|
sort -u
|
|
) |
|
|
while read file call symbol; do
|
|
if ! add_debug_printk && [ "${SYMBOLS}" == "${SYMBOLS#* ${symbol}:${call#select}}" ]; then
|
|
echo FAILED
|
|
fi
|
|
|
|
if [ "${call}" != "${call#builtin_*_driver}" -o "${call}" != "${call#module_*_driver}" ]; then
|
|
symbol=${symbol}_init
|
|
fi
|
|
call=probe
|
|
sed -n "/\(static \)\{0,1\}.* ${symbol}(/,/^}/ {
|
|
s/.*platform_\(driver\|device\)_register([&]\([^)]*\)).*/struct platform_\1 \2/p
|
|
s/.*[ ${TAB}]\(_[a-z]\)_register_driver([&]\([^, ${TAB})]*\)).*/struct \1_driver \2/p
|
|
s/.*i2c_add_driver([&]\([^)]*\)).*/struct i2c_driver \1/p
|
|
}
|
|
s/\(builtin\|module\)_\([a-z]*_driver\)(\([^)]*\));/struct \2 \3/p" ${file} |
|
|
sort -u |
|
|
while read struct; do
|
|
sed -n "/\(static \)\{0,1\}${struct} = {/,/^};/ {
|
|
s/^[ ${TAB}]*[.]probe[ ${TAB}]*=[ ${TAB}]*\([^ ${TAB}]*\),\$/\1/p
|
|
}" ${file} |
|
|
sort -u |
|
|
while read symbol; do
|
|
if ! add_debug_printk && [ "${SYMBOLS}" == "${SYMBOLS#* ${symbol}:${call} }" ]; then
|
|
echo FAILED
|
|
fi
|
|
done
|
|
done
|
|
done |
|
|
sort -u |
|
|
tee ${TMP}/list |
|
|
grep '^FAILED' >/dev/null
|
|
ret=${?}
|
|
SYMBOLS=`grep -v '^FAILED$' ${TMP}/list`
|
|
|
|
rm -rf ${TMP}
|
|
|
|
if [ 0 -ne ${ret} ]; then
|
|
echo "DONE" >&2
|
|
|
|
AUTHOR_NAME="`git config user.name`"
|
|
AUTHOR_EMAIL="`git config user.email`"
|
|
if [ -z "${AUTHOR_EMAIL}" ]; then
|
|
AUTHOR_EMAIL="`${USER}@google.com`"
|
|
fi
|
|
if [ -z "${AUTHOR_NAME}" ]; then
|
|
convert_ldap_to_name() {
|
|
echo "${1##*/}" |
|
|
sed "s@[-_]@ @g
|
|
s@ *@ @g" |
|
|
sed 's@\(^\| \)a@\1A@g
|
|
s@\(^\| \)b@\1B@g
|
|
s@\(^\| \)c@\1C@g
|
|
s@\(^\| \)d@\1D@g
|
|
s@\(^\| \)e@\1E@g
|
|
s@\(^\| \)f@\1F@g
|
|
s@\(^\| \)g@\1G@g
|
|
s@\(^\| \)h@\1H@g
|
|
s@\(^\| \)i@\1I@g
|
|
s@\(^\| \)j@\1J@g
|
|
s@\(^\| \)k@\1K@g
|
|
s@\(^\| \)l@\1L@g
|
|
s@\(^\| \)m@\1M@g
|
|
s@\(^\| \)n@\1N@g
|
|
s@\(^\| \)o@\1O@g
|
|
s@\(^\| \)p@\1P@g
|
|
s@\(^\| \)q@\1Q@g
|
|
s@\(^\| \)r@\1R@g
|
|
s@\(^\| \)s@\1S@g
|
|
s@\(^\| \)t@\1T@g
|
|
s@\(^\| \)u@\1U@g
|
|
s@\(^\| \|Mc\)v@\1V@g
|
|
s@\(^\| \)w@\1W@g
|
|
s@\(^\| \)x@\1X@g
|
|
s@\(^\| \)y@\1Y@g
|
|
s@\(^\| \)z@\1Z@g'
|
|
}
|
|
AUTHOR_NAME="`convert_ldap_to_name ${USER}`"
|
|
fi
|
|
|
|
git commit -a -m "GKI: DEBUG: add instrumentation to init and probe functions
|
|
|
|
Automatically generated by ${0}
|
|
|
|
The following symbols are instrumented:
|
|
`echo \"${SYMBOLS}\" |
|
|
sed 's/^/ - /'`
|
|
|
|
Signed-off-by: ${AUTHOR_NAME} <${AUTHOR_EMAIL}>
|
|
Test: compile" ||
|
|
echo "${RED}ERROR${NORMAL}: failed to commit changes to git" >&2
|
|
exit
|
|
fi
|
|
echo "${RED}FAILED${NORMAL}: could not complete task" >&2
|
|
exit 1
|