769946f50a
This script is going to be used to generate xlat fallback values. * maint/gen_xlat_defs.sh: New file. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
231 lines
5.8 KiB
Bash
Executable File
231 lines
5.8 KiB
Bash
Executable File
#! /bin/bash -eu
|
|
|
|
# Generate xlat .in file based on the existing file and Linux UAPI headers.
|
|
#
|
|
# Copyright (c) 2018 The strace developers.
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# 3. The name of the author may not be used to endorse or promote products
|
|
# derived from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
warn()
|
|
{
|
|
printf >&2 '%s: %s\n' "$0" "$*"
|
|
}
|
|
|
|
fatal()
|
|
{
|
|
warn "$@"
|
|
exit 1
|
|
}
|
|
|
|
usage()
|
|
{
|
|
s="${0//?/ }"
|
|
cat >&2 <<-EOF
|
|
$0 -f VAL_PRINT_FMT \\
|
|
$s -p REGEXP_PATTERN \\
|
|
$s -d LINUX_SRC_DIR \\
|
|
$s -c COMMON_DEFS_GLOB_PATTERN \\
|
|
$s -a ARCH_DEFS_FILE \\
|
|
$s < xlat/xlat_file_name.in
|
|
|
|
Examples:
|
|
$0 -f 'd' -p 'MADV_' -d '/path/to/linux' -c 'asm-generic/mman-common.h' -a 'asm/mman.h' < xlat/madvise_cmds.in
|
|
$0 -f '#x' -p '_?MAP_' -d '/path/to/linux' -c 'asm-generic/mman*.h' -a 'asm/mman.h' < xlat/mmap_flags.in
|
|
$0 -f '#o' -p '[_OF]' -d '/path/to/linux' -c 'asm-generic/fcntl.h' -a 'asm/fcntl.h' < xlat/open_mode_flags.in
|
|
$0 -f 'u' -p 'SO_' -d '/path/to/linux' -c 'asm-generic/socket.h' -a 'asm/socket.h' < xlat/sock_options.in
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
VAL_PRINT_FMT=
|
|
REGEXP_PATTERN=
|
|
COMMON_DEFS_GLOB_PATTERN=
|
|
ARCH_DEFS_FILE=
|
|
LINUX_SRC=
|
|
|
|
comment_re='[^/]*\/\*.*\*\/.*'
|
|
comment_glob='*/\**\*/*'
|
|
|
|
while [ 0 -lt "$#" ]; do
|
|
case "$1" in
|
|
-p)
|
|
shift
|
|
REGEXP_PATTERN="$1"
|
|
;;
|
|
-d)
|
|
shift
|
|
LINUX_SRC="$1"
|
|
;;
|
|
-c)
|
|
shift
|
|
COMMON_DEFS_GLOB_PATTERN="$1"
|
|
;;
|
|
-a)
|
|
shift
|
|
ARCH_DEFS_FILE="$1"
|
|
;;
|
|
-f)
|
|
shift
|
|
VAL_PRINT_FMT="$1"
|
|
;;
|
|
-[h?])
|
|
usage
|
|
;;
|
|
-*)
|
|
fatal "$1: unknown option"
|
|
;;
|
|
*)
|
|
fatal "$1: unexpected argument"
|
|
;;
|
|
esac
|
|
|
|
shift
|
|
done
|
|
|
|
for v in \
|
|
VAL_PRINT_FMT \
|
|
REGEXP_PATTERN \
|
|
COMMON_DEFS_GLOB_PATTERN \
|
|
ARCH_DEFS_FILE \
|
|
LINUX_SRC \
|
|
; do
|
|
eval [ -n \"\$$v\" ] || fatal "$v has not been specified"
|
|
done
|
|
|
|
printf "/* Generated by %s -f '%s' -p '%s' -c '%s' -a '%s' */\\n" \
|
|
"$0" "$VAL_PRINT_FMT" "$REGEXP_PATTERN" \
|
|
"$COMMON_DEFS_GLOB_PATTERN" "$ARCH_DEFS_FILE"
|
|
|
|
sed -rn '/^\/\* Generated by .*\*\//d;s/^((# .*|'"$comment_re"'|'"$REGEXP_PATTERN"'[^[:space:]]*).*)?$/\2/p' |
|
|
uniq |
|
|
while read name_ rest; do
|
|
# Empty lines, comments, and "# " directives are passed verbatim.
|
|
case "$name_ $rest" in
|
|
\ )
|
|
echo
|
|
continue ;;
|
|
\#\ *|${comment_glob})
|
|
printf '%s\n' "$name_ $rest"
|
|
continue ;;
|
|
esac
|
|
sed -rn 's/#define[[:space:]]+('"$name_"')[[:space:]]+([x[:xdigit:]]+).*$/\2\t\1/p' \
|
|
$LINUX_SRC/include/uapi/$COMMON_DEFS_GLOB_PATTERN |
|
|
sort -n | {
|
|
def=
|
|
name=
|
|
read def name ||:
|
|
|
|
if [ -n "$def" ]; then
|
|
warn "$name_ is defined to $def"
|
|
else
|
|
warn "No def for $name_"
|
|
name="$name_"
|
|
fi
|
|
|
|
grep -oEH '#define[[:space:]]+'"$name"'[[:space:]]+(0x[[:xdigit:]]+|[[:digit:]]+)' \
|
|
$LINUX_SRC/arch/*/include/uapi/$ARCH_DEFS_FILE |
|
|
sed -rn 's|^[^#]*/arch/([^/]+)/include/uapi/'"$ARCH_DEFS_FILE"':#define[[:space:]]+'"$name"'[[:space:]]+([^[:space:]]+)([[:space:]].*)?$|\1\t\2|p' |
|
|
sed s/parisc/hppa/ |
|
|
sort |
|
|
awk -vname="$name" -vdef="$def" -vfmt="$VAL_PRINT_FMT" '
|
|
# Like strtonum, but also supports octal and hexadecimal
|
|
# representation.
|
|
# Taken from https://www.gnu.org/software/gawk/manual/html_node/Strtonum-Function.html
|
|
function mystrtonum(str, ret, n, i, k, c)
|
|
{
|
|
if (str ~ /^0[0-7]*$/) {
|
|
# octal
|
|
n = length(str)
|
|
ret = 0
|
|
for (i = 1; i <= n; i++) {
|
|
c = substr(str, i, 1)
|
|
# index() returns 0 if c not in string,
|
|
# includes c == "0"
|
|
k = index("1234567", c)
|
|
|
|
ret = ret * 8 + k
|
|
}
|
|
} else if (str ~ /^0[xX][[:xdigit:]]+$/) {
|
|
# hexadecimal
|
|
str = substr(str, 3) # lop off leading 0x
|
|
n = length(str)
|
|
ret = 0
|
|
|
|
for (i = 1; i <= n; i++) {
|
|
c = substr(str, i, 1)
|
|
c = tolower(c)
|
|
# index() returns 0 if c not in string,
|
|
# includes c == "0"
|
|
k = index("123456789abcdef", c)
|
|
|
|
ret = ret * 16 + k
|
|
}
|
|
} else if (str ~ \
|
|
/^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) {
|
|
# decimal number, possibly floating point
|
|
ret = str + 0
|
|
} else {
|
|
ret = "NOT-A-NUMBER"
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
BEGIN {
|
|
d = mystrtonum(def)
|
|
}
|
|
|
|
{
|
|
i = mystrtonum($2)
|
|
if (i == d) next
|
|
if (a[i])
|
|
a[i] = a[i] " || defined __" $1 "__"
|
|
else
|
|
a[i] = "defined __" $1 "__"
|
|
}
|
|
|
|
END {
|
|
iftext = "#if"
|
|
for (i in a) {
|
|
printf("%s %s\n%s\t%" fmt "\n", iftext, a[i],
|
|
name, i)
|
|
iftext = "#elif"
|
|
}
|
|
|
|
if (iftext != "#if")
|
|
print "#else"
|
|
|
|
if (def == "")
|
|
printf("%s\n", name)
|
|
else
|
|
printf("%s\t%" fmt "\n", name, d)
|
|
|
|
if (iftext != "#if")
|
|
print "#endif"
|
|
}' |
|
|
sed -e 's/defined __arm64__/& || defined __aarch64__/g' \
|
|
-e 's/defined __x86__/defined __x86_64__ || defined __i386__/g'
|
|
}
|
|
done
|