Yet we are on x86 and the locking sequence generated by GCC is simple:
clior could by a bit more complicated:
...
sti
pushfLuckily I used objdump and a bit of massaging come to the rescue in the form of a neat script that finds all the object files that make up the compiled kernel and then searches the disassembler output for these sequences.
pop %reg
cli
...
push %reg
popf
Bonus: the function names that do the locking are also printed.
Here comes findcli_x86.sh [run it at the root of the kernel tree after you compile the kernel]:
As usual awk comes to the rescue.#!/bin/sh
# This file is licensed under GPLv2
# Note this works only with x86 code
obj_list='obj';
trap "rm -f $obj_list" 0 1 2 15
function extractcli()
{
file=$1;
[ ! -r "$file" ] && return 1;
[ -z "$OBJDUMP" ] && OBJDUMP=${CROSS_COMPILE}objdump
$OBJDUMP -dSCl $file | awk 'BEGIN {
idx="nosuchfunc"
}
/(^[a-zA-Z_]|cli[^a-z]|popf|sti[^a-z])/ && !/(file format|Disassembly)/ {
if($0 ~ /^[a-zA-Z_]/) {
idx=$1
} else {
F[idx]=(F[idx] "\n" "\t" $1 "\t" $NF);
}
}
END {
for(idx in F) {
print (" " idx F[idx])
}
}'
return 0
}
# main
find -type f -name '*.o' > $obj_list
for obj in $(cat $obj_list)
do
o=$(echo $obj | sed 's/^\.\///g')
[ "$o" = 'vmlinux.o' ] && continue; # this is the whole kernel
echo $o | grep -q 'built-in\.o' && continue; # these are aggregations
echo -en " \r$o" 1>&2
cnt=$(objdump -dS $o | grep -cw cli)
[ "$cnt" = '0' ] && continue;
echo -en " \r" 1>&2
src='???';
c=$(echo $o | sed 's/\.o$/\.c/g')
S=$(echo $o | sed 's/\.o$/\.S/g')
[ -f "$c" ] && src="$c"
[ -f "$S" ] && src="$S"
echo "$o: $cnt, src: $src"
extractcli $o
done
-ulianov
P.S. I looked for a decent decompiler for Linux other than objdump but I found only ancient ones and all broken. This is annoying as sometimes I need to see what external functions are called by an object file (.o).