Skip to content

Commit

Permalink
gen_syscalls: Refactor the scripts
Browse files Browse the repository at this point in the history
Make the extractor configurable to extract {amd64,i386,x32}
from amd64 and other companion architecture syscalls if needed.

Also introduce "GDB" environment variable allowing invocation
of custom GDB, i.e:

GDB=gdb-multiarch ./gen_syscalls.sh /tmp/vmlinux-armmp

Signed-off-by: Vasyl Gello <vasek.gello@gmail.com>
  • Loading branch information
basilgello committed Jul 25, 2024
1 parent a5cc253 commit 0ffeda5
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 35 deletions.
48 changes: 43 additions & 5 deletions tools/gen_syscalls/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
limitations under the License.
"""

import os
import re
import sys

out_file = open('output_syscalls.c', 'w')
# Functions

def output(str):
out_file.write(str)
Expand All @@ -45,21 +47,57 @@ def output_syscall(nr, name):
real_name = m.group(1)
else:
real_name = name
output('\t{"'+real_name+'", '+str(nr)+', {')
output('\t{"'+real_name+'", '+str(nr | sys_call_bit)+', {')
for j in range(0, nb_args):
arg_name = get_string_val("print __syscall_meta__"+name+"->args["+str(j)+"]")
arg_type = get_string_val("print __syscall_meta__"+name+"->types["+str(j)+"]")
arg_size = get_int_val("print sizeof("+arg_type+")")
output('[ARG_'+str(j)+'] = {"'+arg_name+'", '+str(arg_size)+'}, ')
output('}},\n')

num_syscalls=get_int_val("print sizeof(sys_call_table)/sizeof(sys_call_table[0])")
table_cmd = "print sys_call_table"
# Start of script

# "xrange" was renamed to "range" in Python 3

try:
# Python 2
xrange
except NameError:
# Python 3, xrange is now named range
xrange = range

# Define syscall table name

sys_call_table_name = os.getenv("SYSCALLTABLENAME")
if (sys_call_table_name is None) or (sys_call_table_name == ""):
print("WARNING: Environment variable 'SYSCALLTABLENAME' not set!")
out_file.close()
sys.exit(1)

# Define syscall bit

sys_call_bit = os.getenv("SYSCALLBIT")
if (sys_call_bit is None) or (sys_call_bit == ""):
print("WARNING: Environment variable 'SYSCALLBIT' not set!")
out_file.close()
sys.exit(1)
else:
try:
sys_call_bit = int(sys_call_bit)
except:
print("WARNING: Wring value of environment varibable 'SYSCALLBIT'!")
out_file.close()
sys.exit(1)

out_file = open('output_syscalls.c', 'a')

num_syscalls=get_int_val(str("print sizeof(" + sys_call_table_name + ")/sizeof(" + sys_call_table_name + "[0])"))
table_cmd = "print " + sys_call_table_name
syscall_regex = "<([Ss]y[Ss]|stub)_([^>]*)>"

if num_syscalls <= 0:
num_syscalls = 1000
table_cmd = "info symbol ((void**)sys_call_table)"
table_cmd = "info symbol ((void**)" + sys_call_table_name + ")"
syscall_regex = "([Ss]y[Ss]|stub)_([^ ]*)"

for i in range(0, num_syscalls):
Expand Down
113 changes: 83 additions & 30 deletions tools/gen_syscalls/gen_syscalls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,28 @@
# limitations under the License.
#

if [ $# -ne 1 ] || [ ! -e "$1" -o -d "$1" ]; then
echo "USAGE: $0 [linux_with_debugging_symbols]"
exit 1
fi
# Start of functions

export LANG=C
generate_syscall_file()
{
# $1 - linux file ($linux)
# $2 - architecture ($arch)
# $3 - (optional) syscall table symbol name (sys_call_table)
# $4 - (optional) syscall bit (0 or _X32_SYSCALL_BIT)

linux="$1"
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
arch="AMD64"
fi
outname="${arch,,}_syscalls.c"
linux="$1"
arch="$2"
SYSCALLTABLENAME="$3"
SYSCALLBIT="$4"

[ -z "$SYSCALLTABLENAME" ] && SYSCALLTABLENAME="sys_call_table"
[ -z "$SYSCALLBIT" ] && SYSCALLBIT=0

echo -n "Generating syscalls for $arch... "
echo -n "Generating syscalls for $arch ... "
outname="${arch,,}_syscalls.c"

year=$(date +%Y)
cat > "$outname" <<HEADER
year=$(date +%Y)
cat > "$outname" <<HEADER
/*
Kafel - syscalls ($arch)
-----------------------------------------
Expand Down Expand Up @@ -71,26 +75,75 @@ cat > "$outname" <<HEADER
const struct syscall_descriptor ${arch,,}_syscall_list[] = {
HEADER

case "$arch" in
ARM)
gdb --batch -ex 'set gnutarget elf32-littlearm' -ex "file $linux" -x extract.py
;;
*)
gdb --batch -ex "file $linux" -x extract.py
;;
esac

if [ -f "missing/${arch,,}.c" ]; then
cat "missing/${arch,,}.c" >> output_syscalls.c
fi
echo -n "" > output_syscalls.c


case "$arch" in
ARM)
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
SYSCALLBIT=$SYSCALLBIT \
"$GDB" --batch \
-ex 'set gnutarget elf32-littlearm' \
-ex "file $linux" \
-x extract.py
;;
*)
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
SYSCALLBIT=$SYSCALLBIT \
"$GDB" --batch \
-ex "file $linux" \
-x extract.py
;;
esac

cat output_syscalls.c | sort -k1,1 --unique --stable -t',' >> "$outname"
rm output_syscalls.c
if [ -f "missing/${arch,,}.c" ]; then
cat "missing/${arch,,}.c" >> output_syscalls.c
fi

cat >> "$outname" <<FOOTER
cat output_syscalls.c | sort -k1,1 --unique --stable -t',' >> "$outname"

rm output_syscalls.c

cat >> "$outname" <<FOOTER
};
const size_t ${arch,,}_syscall_list_size = sizeof(${arch,,}_syscall_list)/sizeof(${arch,,}_syscall_list[0]);
FOOTER

echo "DONE"
echo "DONE"
}

# End of functions

# Start of script

if [ $# -ne 1 ] || [ ! -e "$1" -o -d "$1" ]; then
echo "USAGE: $0 [linux_with_debugging_symbols]"
exit 1
fi

export LANG=C

# For gdb-multiarch or toolchain-provided gdb

[ -z "$GDB" ] && GDB="gdb"

linux="$1"
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
class="$(readelf -h "$linux" | sed -ne '/Class:/{s/^[[:space:]]*Class:[[:space:]]*//;P}')"

if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
arch="AMD64"
elif [ "$arch" = "Intel 80386" ]; then
arch="i386"
elif [ "$arch" = "MIPS R3000" ]; then
[ "$class" = "ELF32" ] && arch="mipso32" || arch="mips64"
fi

if [ "$arch" = "AMD64" ]; then
generate_syscall_file "$linux" amd64
generate_syscall_file "$linux" i386 ia32_sys_call_table 0
generate_syscall_file "$linux" x32 x32_sys_call_table 1073741824
else
generate_syscall_file "$linux" "$arch"
fi

0 comments on commit 0ffeda5

Please sign in to comment.