#!/bin/bash
# Copyright (C) 2022-2025 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Used to generate .xml.in files, like so:
# $ ./update-linux-from-src.sh ~/linux-stable.git
pwd=$(pwd -P)
parse_args ()
{
if [ $# -lt 1 ]; then
echo "dir argument needed"
exit 1
fi
d="$1"
shift
if [ ! -d "$d" ]; then
echo "cannot find $d"
exit 1
fi
}
gen_from_kernel_headers ()
{
local f
f="$1"
local arch
arch="$2"
echo "Generating $f"
local tmpdir
tmpdir=$(mktemp -d)
trap 'rm -Rf $tmpdir/*' EXIT
local build
build="$tmpdir"/build
local install
install="$tmpdir"/install
local usr
usr="$install"/usr
local include
include="$usr"/include
mkdir -p "$build" "$usr"
(
cd "$build" || exit 1
make \
-f "$d"/Makefile \
ARCH="$arch" \
INSTALL_HDR_PATH="$usr" \
headers_install \
> "$build"/header_install.log \
2>&1
"$pwd"/update-linux.sh \
"$pwd"/"$f" \
-nostdinc \
-isystem "$include"
)
trap '' EXIT
rm -Rf "$tmpdir"
}
pre ()
{
local f
f="$1"
local start_date
start_date="$2"
local h
h="$3"
local prefix
prefix=" "
if [ "$h" != "" ]; then
file_files="files"
belong_belongs="belong"
files=$(echo -e "$prefix$f\n$prefix$h")
else
file_files="file"
belong_belongs="belongs"
files="$prefix$f"
fi
local year
year=$(date +%Y)
cat <
EOF
echo ''
}
post ()
{
echo ''
}
one ()
{
local f
f="$1"
local select_abis
select_abis="$2"
local start_date
start_date="$3"
local offset
offset="$4"
local h
h="$5"
tmp=$(mktemp)
trap 'rm -f $tmp' EXIT
pre "$f" "$start_date" "$h"
# Print out num, abi, name.
grep -v "^#" "$d/$f" \
| awk '{print $1, $2, $3}' \
> "$tmp"
local decimal
decimal="[0-9][0-9]*"
# Print out num, "removed", name.
grep -E "^# $decimal was sys_*" "$d/$f" \
| awk '{print $2, "removed", gensub("^sys_", "", 1, $4)}' \
>> "$tmp"
case $h in
arch/arm/include/uapi/asm/unistd.h)
grep '#define __ARM_NR_[a-z].*__ARM_NR_BASE\+' "$d/$h" \
| sed 's/#define //;s/__ARM_NR_BASE+//;s/[()]//g;s/__ARM_NR_/ARM_/' \
| awk '{print $2 + 0x0f0000, "private", $1}' \
>> "$tmp"
;;
esac
local nums
declare -a nums
local abis
declare -a abis
local names
declare -a names
local name_exists
declare -A name_exists
local i
i=0
local _num
local _abi
local _name
while read -r -a line; do
_num="${line[0]}"
_abi="${line[1]}"
_name="${line[2]}"
local found
found=false
for a in $select_abis; do
if [ "$a" = "$_abi" ]; then
found=true
break
fi
done
if ! $found; then
continue
fi
if [ "${_name/reserved+([0-9])/}" = "" ]; then
continue
fi
if [ "${_name/unused+([0-9])/}" = "" ]; then
continue
fi
nums[i]="$_num"
abis[i]="$_abi"
names[i]="$_name"
if [ "$_abi" != "removed" ]; then
name_exists[$_name]=1
fi
i=$((i + 1))
done < <(sort -V "$tmp")
local n
n=$i
for ((i = 0 ; i < n ; i++)); do
_name=${names[$i]}
_abi=${abis[$i]}
_num=$((${nums[$i]} + offset))
if [ "$_abi" = "removed" ] && [ "${name_exists[$_name]}" = 1 ]; then
_name=old$_name
fi
echo -n " "
if [ "$_abi" = "removed" ]; then
echo " "
else
echo
fi
done
post
}
regen ()
{
local f
f="$1"
local start_date
start_date=2009
local offset
offset=0
local h
h=
local t
local abi
case $f in
amd64-linux.xml.in)
t="arch/x86/entry/syscalls/syscall_64.tbl"
abi="common 64"
;;
i386-linux.xml.in)
t="arch/x86/entry/syscalls/syscall_32.tbl"
abi=i386
;;
ppc64-linux.xml.in)
t="arch/powerpc/kernel/syscalls/syscall.tbl"
abi="common 64 nospu"
;;
ppc-linux.xml.in)
t="arch/powerpc/kernel/syscalls/syscall.tbl"
abi="common 32 nospu"
;;
s390-linux.xml.in)
t="arch/s390/kernel/syscalls/syscall.tbl"
abi="common 32"
;;
s390x-linux.xml.in)
t="arch/s390/kernel/syscalls/syscall.tbl"
abi="common 64"
;;
sparc64-linux.xml.in)
t="arch/sparc/kernel/syscalls/syscall.tbl"
abi="common 64"
start_date="2010"
;;
sparc-linux.xml.in)
t="arch/sparc/kernel/syscalls/syscall.tbl"
abi="common 32"
start_date="2010"
;;
mips-n32-linux.xml.in)
t="arch/mips/kernel/syscalls/syscall_n32.tbl"
abi="n32"
start_date="2011"
offset=6000
;;
mips-n64-linux.xml.in)
t="arch/mips/kernel/syscalls/syscall_n64.tbl"
abi="n64"
start_date="2011"
offset=5000
;;
mips-o32-linux.xml.in)
t="arch/mips/kernel/syscalls/syscall_o32.tbl"
abi="o32"
start_date="2011"
offset=4000
;;
bfin-linux.xml.in)
echo "Skipping $f, no longer supported"
return
;;
aarch64-linux.xml.in)
# No syscall.tbl.
gen_from_kernel_headers "$f" arm64
return
;;
riscv-linux.xml.in)
# No syscall.tbl.
gen_from_kernel_headers "$f" riscv
return
;;
arm-linux.xml.in)
t="arch/arm/tools/syscall.tbl"
h="arch/arm/include/uapi/asm/unistd.h"
abi="common eabi oabi removed private"
;;
loongarch-linux.xml.in)
echo "Skipping $f, no syscall.tbl"
return
;;
linux-defaults.xml.in)
return
;;
*)
echo "Don't know how to generate $f"
return
;;
esac
echo "Generating $f"
one "$t" "$abi" "$start_date" "$offset" "$h" > "$f"
}
main ()
{
shopt -s extglob
# Set global d.
parse_args "$@"
local f
for f in *.xml.in; do
regen "$f"
done
}
main "$@"