From 36b8eb3ce55602bcf36199330e98f2e154225cf7 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Tue, 25 Oct 2022 15:19:55 +0200 Subject: seitan: Initial import Signed-off-by: Stefano Brivio --- transform.sh | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100755 transform.sh (limited to 'transform.sh') diff --git a/transform.sh b/transform.sh new file mode 100755 index 0000000..1e9eaeb --- /dev/null +++ b/transform.sh @@ -0,0 +1,160 @@ +#!/bin/sh -eu +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# SEITAN - Syscall Expressive Interpreter, Transformer and Notifier +# +# transform.sh - Build syscall transformation table headers +# +# Copyright (c) 2022 Red Hat GmbH +# Author: Stefano Brivio + +TMP="$(mktemp)" +IN="${@}" +OUT="transform.h" + +HEADER="/* This file was automatically generated by $(basename ${0}) */ + +struct table { + int type; + long number; + char arg[1024][6]; +};" + +# Prefix for each profile +PRE=' +struct table table_@PROFILE@[] = {' + +# Suffix for each profile +POST='}; +' + +# cleanup() - Remove temporary file if it exists +cleanup() { + rm -f "${TMP}" +} +trap "cleanup" EXIT + +# sub() - Substitute in-place file line with processed template line +# $1: Line number +# $2: Template name (variable name) +# $@: Replacement for @KEY@ in the form KEY:value +sub() { + IFS= + __line_no="${1}" + __template="$(eval printf '%s' "\${${2}}")" + shift; shift + + sed -i "${__line_no}s#.*#${__template}#" "${TMP}" + + IFS=' ' + for __def in ${@}; do + __key="@${__def%%:*}@" + __value="${__def#*:}" + sed -i "${__line_no}s/${__key}/${__value}/" "${TMP}" + done + unset IFS +} + +# finish() - Finalise header file from temporary files with prefix and suffix +# $1: Variable name of prefix +# $@: Replacements for prefix variable +finish() { + IFS= + __out="$(eval printf '%s' "\${${1}}")" + shift + + IFS=' ' + for __def in ${@}; do + __key="@${__def%%:*}@" + __value="${__def#*:}" + __out="$(printf '%s' "${__out}" | sed "s#${__key}#${__value}#")" + done + + printf '%s\n' "${__out}" >> "${OUT}" + cat "${TMP}" >> "${OUT}" + rm "${TMP}" + printf '%s' "${POST}" >> "${OUT}" + unset IFS +} + +# syscall_nr - Get syscall number from compiler +# $1: Name of syscall +syscall_nr() { + __in="$(printf "#include \n#include \n__NR_%s" ${1})" + __out="$(echo "${__in}" | cc -E -xc - -o - | tail -1)" + [ "${__out}" = "__NR_$1" ] && return 1 + + # Output might be in the form "(x + y)" (seen on armv6l, armv7l) + __out="$(eval echo $((${__out})))" + echo "${__out}" +} + +filter() { + __filtered= + for __c in ${@}; do + __arch_match=0 + case ${__c} in + *:*) + case ${__c} in + $(uname -m):*) + __arch_match=1 + __c=${__c##*:} + ;; + esac + ;; + *) + __arch_match=1 + ;; + esac + [ ${__arch_match} -eq 0 ] && continue + + IFS='| ' + __found=0 + for __name in ${__c}; do + syscall_nr "${__name}" >/dev/null && __found=1 && break + done + unset IFS + + if [ ${__found} -eq 0 ]; then + echo + echo "Warning: no syscall number for ${__c}" >&2 + echo " none of these syscalls will be allowed" >&2 + continue + fi + + __filtered="${__filtered} ${__name}" + done + + echo "${__filtered}" | tr ' ' '\n' | sort -u +} + +printf '%s\n' "${HEADER}" > "${OUT}" +__profiles="${IN}" +for __p in ${__profiles}; do + IFS=' +' + for __l in $(grep "^[a-z].*" "${__p}" | tr -s '\t'); do + unset IFS + __syscall_token="$(echo "${__l}" | cut -f1)" + __type_token="$(echo "${__l}" | cut -f2)" + __arg1_token="$(echo "${__l}" | cut -f3)" + __arg2_token="$(echo "${__l}" | cut -f4)" + __arg3_token="$(echo "${__l}" | cut -f5)" + __arg4_token="$(echo "${__l}" | cut -f6)" + __arg5_token="$(echo "${__l}" | cut -f7)" + __arg6_token="$(echo "${__l}" | cut -f8)" + + __syscall_nr="$(syscall_nr "${__syscall_token}")" + __type_enum="$(echo ${__type_token} | tr [a-z] [A-Z])" + + printf "\t{ %i, %s, \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", },\n" \ + ${__syscall_nr} "${__type_enum}" \ + "${__arg1_token}" "${__arg2_token}" "${__arg3_token}" \ + "${__arg4_token}" "${__arg5_token}" "${__arg6_token}" \ + >> "${TMP}" + IFS=' +' + done + finish PRE "PROFILE:${__p}" +done -- cgit v1.2.3