Skip to content

Commit 0ffeda5

Browse files
committed
gen_syscalls: Refactor the scripts
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>
1 parent a5cc253 commit 0ffeda5

2 files changed

Lines changed: 126 additions & 35 deletions

File tree

tools/gen_syscalls/extract.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
limitations under the License.
1818
"""
1919

20+
import os
2021
import re
22+
import sys
2123

22-
out_file = open('output_syscalls.c', 'w')
24+
# Functions
2325

2426
def output(str):
2527
out_file.write(str)
@@ -45,21 +47,57 @@ def output_syscall(nr, name):
4547
real_name = m.group(1)
4648
else:
4749
real_name = name
48-
output('\t{"'+real_name+'", '+str(nr)+', {')
50+
output('\t{"'+real_name+'", '+str(nr | sys_call_bit)+', {')
4951
for j in range(0, nb_args):
5052
arg_name = get_string_val("print __syscall_meta__"+name+"->args["+str(j)+"]")
5153
arg_type = get_string_val("print __syscall_meta__"+name+"->types["+str(j)+"]")
5254
arg_size = get_int_val("print sizeof("+arg_type+")")
5355
output('[ARG_'+str(j)+'] = {"'+arg_name+'", '+str(arg_size)+'}, ')
5456
output('}},\n')
5557

56-
num_syscalls=get_int_val("print sizeof(sys_call_table)/sizeof(sys_call_table[0])")
57-
table_cmd = "print sys_call_table"
58+
# Start of script
59+
60+
# "xrange" was renamed to "range" in Python 3
61+
62+
try:
63+
# Python 2
64+
xrange
65+
except NameError:
66+
# Python 3, xrange is now named range
67+
xrange = range
68+
69+
# Define syscall table name
70+
71+
sys_call_table_name = os.getenv("SYSCALLTABLENAME")
72+
if (sys_call_table_name is None) or (sys_call_table_name == ""):
73+
print("WARNING: Environment variable 'SYSCALLTABLENAME' not set!")
74+
out_file.close()
75+
sys.exit(1)
76+
77+
# Define syscall bit
78+
79+
sys_call_bit = os.getenv("SYSCALLBIT")
80+
if (sys_call_bit is None) or (sys_call_bit == ""):
81+
print("WARNING: Environment variable 'SYSCALLBIT' not set!")
82+
out_file.close()
83+
sys.exit(1)
84+
else:
85+
try:
86+
sys_call_bit = int(sys_call_bit)
87+
except:
88+
print("WARNING: Wring value of environment varibable 'SYSCALLBIT'!")
89+
out_file.close()
90+
sys.exit(1)
91+
92+
out_file = open('output_syscalls.c', 'a')
93+
94+
num_syscalls=get_int_val(str("print sizeof(" + sys_call_table_name + ")/sizeof(" + sys_call_table_name + "[0])"))
95+
table_cmd = "print " + sys_call_table_name
5896
syscall_regex = "<([Ss]y[Ss]|stub)_([^>]*)>"
5997

6098
if num_syscalls <= 0:
6199
num_syscalls = 1000
62-
table_cmd = "info symbol ((void**)sys_call_table)"
100+
table_cmd = "info symbol ((void**)" + sys_call_table_name + ")"
63101
syscall_regex = "([Ss]y[Ss]|stub)_([^ ]*)"
64102

65103
for i in range(0, num_syscalls):

tools/gen_syscalls/gen_syscalls.sh

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,28 @@
1919
# limitations under the License.
2020
#
2121

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

27-
export LANG=C
24+
generate_syscall_file()
25+
{
26+
# $1 - linux file ($linux)
27+
# $2 - architecture ($arch)
28+
# $3 - (optional) syscall table symbol name (sys_call_table)
29+
# $4 - (optional) syscall bit (0 or _X32_SYSCALL_BIT)
2830

29-
linux="$1"
30-
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
31-
if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
32-
arch="AMD64"
33-
fi
34-
outname="${arch,,}_syscalls.c"
31+
linux="$1"
32+
arch="$2"
33+
SYSCALLTABLENAME="$3"
34+
SYSCALLBIT="$4"
35+
36+
[ -z "$SYSCALLTABLENAME" ] && SYSCALLTABLENAME="sys_call_table"
37+
[ -z "$SYSCALLBIT" ] && SYSCALLBIT=0
3538

36-
echo -n "Generating syscalls for $arch... "
39+
echo -n "Generating syscalls for $arch ... "
40+
outname="${arch,,}_syscalls.c"
3741

38-
year=$(date +%Y)
39-
cat > "$outname" <<HEADER
42+
year=$(date +%Y)
43+
cat > "$outname" <<HEADER
4044
/*
4145
Kafel - syscalls ($arch)
4246
-----------------------------------------
@@ -71,26 +75,75 @@ cat > "$outname" <<HEADER
7175
const struct syscall_descriptor ${arch,,}_syscall_list[] = {
7276
HEADER
7377

74-
case "$arch" in
75-
ARM)
76-
gdb --batch -ex 'set gnutarget elf32-littlearm' -ex "file $linux" -x extract.py
77-
;;
78-
*)
79-
gdb --batch -ex "file $linux" -x extract.py
80-
;;
81-
esac
82-
83-
if [ -f "missing/${arch,,}.c" ]; then
84-
cat "missing/${arch,,}.c" >> output_syscalls.c
85-
fi
78+
echo -n "" > output_syscalls.c
79+
80+
81+
case "$arch" in
82+
ARM)
83+
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
84+
SYSCALLBIT=$SYSCALLBIT \
85+
"$GDB" --batch \
86+
-ex 'set gnutarget elf32-littlearm' \
87+
-ex "file $linux" \
88+
-x extract.py
89+
;;
90+
*)
91+
SYSCALLTABLENAME="$SYSCALLTABLENAME" \
92+
SYSCALLBIT=$SYSCALLBIT \
93+
"$GDB" --batch \
94+
-ex "file $linux" \
95+
-x extract.py
96+
;;
97+
esac
8698

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

90-
cat >> "$outname" <<FOOTER
103+
cat output_syscalls.c | sort -k1,1 --unique --stable -t',' >> "$outname"
104+
105+
rm output_syscalls.c
106+
107+
cat >> "$outname" <<FOOTER
91108
};
92109
93110
const size_t ${arch,,}_syscall_list_size = sizeof(${arch,,}_syscall_list)/sizeof(${arch,,}_syscall_list[0]);
94111
FOOTER
95112

96-
echo "DONE"
113+
echo "DONE"
114+
}
115+
116+
# End of functions
117+
118+
# Start of script
119+
120+
if [ $# -ne 1 ] || [ ! -e "$1" -o -d "$1" ]; then
121+
echo "USAGE: $0 [linux_with_debugging_symbols]"
122+
exit 1
123+
fi
124+
125+
export LANG=C
126+
127+
# For gdb-multiarch or toolchain-provided gdb
128+
129+
[ -z "$GDB" ] && GDB="gdb"
130+
131+
linux="$1"
132+
arch="$(readelf -h "$linux" | sed -ne '/Machine:/{s/^[[:space:]]*Machine:[[:space:]]*//;P}')"
133+
class="$(readelf -h "$linux" | sed -ne '/Class:/{s/^[[:space:]]*Class:[[:space:]]*//;P}')"
134+
135+
if [ "$arch" = "Advanced Micro Devices X86-64" ]; then
136+
arch="AMD64"
137+
elif [ "$arch" = "Intel 80386" ]; then
138+
arch="i386"
139+
elif [ "$arch" = "MIPS R3000" ]; then
140+
[ "$class" = "ELF32" ] && arch="mipso32" || arch="mips64"
141+
fi
142+
143+
if [ "$arch" = "AMD64" ]; then
144+
generate_syscall_file "$linux" amd64
145+
generate_syscall_file "$linux" i386 ia32_sys_call_table 0
146+
generate_syscall_file "$linux" x32 x32_sys_call_table 1073741824
147+
else
148+
generate_syscall_file "$linux" "$arch"
149+
fi

0 commit comments

Comments
 (0)