Commit 96a8fae0 authored by Russell King's avatar Russell King

ARM: convert to generated system call tables

Convert ARM to use a similar mechanism to x86 to generate the unistd.h
system call numbers and the various kernel system call tables.  This
means that rather than having to edit three places (asm/unistd.h for
the total number of system calls, uapi/asm/unistd.h for the system call
numbers, and arch/arm/kernel/calls.S for the call table) we have only
one place to edit, making the process much more simple.

The scripts have knowledge of the table padding requirements, so there's
no need to worry about __NR_syscalls not fitting within the immediate
constant field of ALU instructions anymore.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent 4e2648db
......@@ -311,6 +311,9 @@ all: $(KBUILD_IMAGE) $(KBUILD_DTBS)
boot := arch/arm/boot
archheaders:
$(Q)$(MAKE) $(build)=arch/arm/tools uapi
archprepare:
$(Q)$(MAKE) $(build)=arch/arm/tools kapi
......
......@@ -41,3 +41,4 @@ generic-y += trace_clock.h
generic-y += unaligned.h
generated-y += mach-types.h
generated-y += unistd-nr.h
......@@ -14,12 +14,7 @@
#define __ASM_ARM_UNISTD_H
#include <uapi/asm/unistd.h>
/*
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
#define __NR_syscalls (396)
#include <asm/unistd-nr.h>
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
......@@ -52,4 +47,23 @@
#define __IGNORE_fadvise64_64
#define __IGNORE_migrate_pages
#ifdef __ARM_EABI__
/*
* The following syscalls are obsolete and no longer available for EABI:
* __NR_time
* __NR_umount
* __NR_stime
* __NR_alarm
* __NR_utime
* __NR_getrlimit
* __NR_select
* __NR_readdir
* __NR_mmap
* __NR_socketcall
* __NR_syscall
* __NR_ipc
*/
#define __IGNORE_getrlimit
#endif
#endif /* __ASM_ARM_UNISTD_H */
......@@ -18,3 +18,6 @@ header-y += stat.h
header-y += statfs.h
header-y += swab.h
header-y += unistd.h
genhdr-y += unistd-common.h
genhdr-y += unistd-oabi.h
genhdr-y += unistd-eabi.h
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,11 @@
#include <asm/unistd.h>
#include <asm/ftrace.h>
#include <asm/unwind.h>
#ifdef CONFIG_AEABI
#include <asm/unistd-oabi.h>
#endif
.equ NR_syscalls, __NR_syscalls
#ifdef CONFIG_NEED_RET_TO_USER
#include <mach/entry-macro.S>
......@@ -120,21 +125,6 @@ ENTRY(ret_from_fork)
b ret_slow_syscall
ENDPROC(ret_from_fork)
.equ NR_syscalls,0
#define CALL(x) .equ NR_syscalls,NR_syscalls+1
#include "calls.S"
/*
* Ensure that the system call table is equal to __NR_syscalls,
* which is the value the rest of the system sees
*/
.ifne NR_syscalls - __NR_syscalls
.error "__NR_syscalls is not equal to the size of the syscall table"
.endif
#undef CALL
#define CALL(x) .long x
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
......@@ -291,22 +281,48 @@ __cr_alignment:
#endif
.ltorg
.macro syscall_table_start, sym
.equ __sys_nr, 0
.type \sym, #object
ENTRY(\sym)
.endm
.macro syscall, nr, func
.ifgt __sys_nr - \nr
.error "Duplicated/unorded system call entry"
.endif
.rept \nr - __sys_nr
.long sys_ni_syscall
.endr
.long \func
.equ __sys_nr, \nr + 1
.endm
.macro syscall_table_end, sym
.ifgt __sys_nr - __NR_syscalls
.error "System call table too big"
.endif
.rept __NR_syscalls - __sys_nr
.long sys_ni_syscall
.endr
.size \sym, . - \sym
.endm
#define NATIVE(nr, func) syscall nr, func
/*
* This is the syscall table declaration for native ABI syscalls.
* With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
*/
#define ABI(native, compat) native
syscall_table_start sys_call_table
#define COMPAT(nr, native, compat) syscall nr, native
#ifdef CONFIG_AEABI
#define OBSOLETE(syscall) sys_ni_syscall
#include <calls-eabi.S>
#else
#define OBSOLETE(syscall) syscall
#include <calls-oabi.S>
#endif
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE
#undef COMPAT
syscall_table_end sys_call_table
/*============================================================================
* Special system call wrappers
......@@ -407,14 +423,10 @@ ENDPROC(sys_oabi_readahead)
* Let's declare a second syscall table for old ABI binaries
* using the compatibility syscall entries.
*/
#define ABI(native, compat) compat
#define OBSOLETE(syscall) syscall
.type sys_oabi_call_table, #object
ENTRY(sys_oabi_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE
syscall_table_start sys_oabi_call_table
#define COMPAT(nr, native, compat) syscall nr, compat
#include <calls-oabi.S>
syscall_table_end sys_oabi_call_table
#endif
......@@ -6,17 +6,31 @@
gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
uapi := $(gen)/uapi/asm
syshdr := $(srctree)/$(src)/syscallhdr.sh
sysnr := $(srctree)/$(src)/syscallnr.sh
systbl := $(srctree)/$(src)/syscalltbl.sh
syscall := $(srctree)/$(src)/syscall.tbl
kapi-hdrs-y := $(kapi)/mach-types.h
gen-y := $(gen)/calls-oabi.S
gen-y += $(gen)/calls-eabi.S
kapi-hdrs-y := $(kapi)/unistd-nr.h
kapi-hdrs-y += $(kapi)/mach-types.h
uapi-hdrs-y := $(uapi)/unistd-common.h
uapi-hdrs-y += $(uapi)/unistd-oabi.h
uapi-hdrs-y += $(uapi)/unistd-eabi.h
targets += $(addprefix ../../../,$(kapi-hdrs-y))
targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
PHONY += kapi
PHONY += kapi uapi
kapi: $(kapi-hdrs-y)
kapi: $(kapi-hdrs-y) $(gen-y)
uapi: $(uapi-hdrs-y)
# Create output directory if not already present
_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)')
_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)') \
$(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)')
quiet_cmd_gen_mach = GEN $@
cmd_gen_mach = mkdir -p $(dir $@) && \
......@@ -25,3 +39,41 @@ quiet_cmd_gen_mach = GEN $@
$(kapi)/mach-types.h: $(src)/gen-mach-types $(src)/mach-types FORCE
$(call if_changed,gen_mach)
quiet_cmd_syshdr = SYSHDR $@
cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \
'$(syshdr_abi_$(basetarget))' \
'$(syshdr_pfx_$(basetarget))' \
'__NR_SYSCALL_BASE'
quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) '$(systbl)' '$<' '$@' \
'$(systbl_abi_$(basetarget))'
quiet_cmd_sysnr = SYSNR $@
cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@' \
'$(syshdr_abi_$(basetarget))'
syshdr_abi_unistd-common := common
$(uapi)/unistd-common.h: $(syscall) $(syshdr) FORCE
$(call if_changed,syshdr)
syshdr_abi_unistd-oabi := oabi
$(uapi)/unistd-oabi.h: $(syscall) $(syshdr) FORCE
$(call if_changed,syshdr)
syshdr_abi_unistd-eabi := eabi
$(uapi)/unistd-eabi.h: $(syscall) $(syshdr) FORCE
$(call if_changed,syshdr)
sysnr_abi_unistd-nr := common,oabi,eabi,compat
$(kapi)/unistd-nr.h: $(syscall) $(sysnr) FORCE
$(call if_changed,sysnr)
systbl_abi_calls-oabi := common,oabi
$(gen)/calls-oabi.S: $(syscall) $(systbl) FORCE
$(call if_changed,systbl)
systbl_abi_calls-eabi := common,eabi
$(gen)/calls-eabi.S: $(syscall) $(systbl) FORCE
$(call if_changed,systbl)
This diff is collapsed.
#!/bin/sh
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
prefix="$4"
offset="$5"
fileguard=_ASM_ARM_`basename "$out" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
if echo $out | grep -q uapi; then
fileguard="_UAPI$fileguard"
fi
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
echo "#ifndef ${fileguard}"
echo "#define ${fileguard} 1"
echo ""
while read nr abi name entry ; do
if [ -z "$offset" ]; then
echo "#define __NR_${prefix}${name} $nr"
else
echo "#define __NR_${prefix}${name} ($offset + $nr)"
fi
done
echo ""
echo "#endif /* ${fileguard} */"
) > "$out"
#!/bin/sh
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
align=1
fileguard=_ASM_ARM_`basename "$out" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | tail -n1 | (
echo "#ifndef ${fileguard}
#define ${fileguard} 1
/*
* This needs to be greater than __NR_last_syscall+1 in order to account
* for the padding in the syscall table.
*/
"
while read nr abi name entry; do
nr=$(($nr + 1))
while [ "$(($nr / (256 * $align) ))" -gt 0 ]; do
align=$(( $align * 4 ))
done
nr=$(( ($nr + $align - 1) & ~($align - 1) ))
echo "/* aligned to $align */"
echo "#define __NR_syscalls $nr"
done
echo ""
echo "#endif /* ${fileguard} */"
) > "$out"
#!/bin/sh
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
while read nr abi name entry compat; do
if [ "$abi" = "eabi" -a -n "$compat" ]; then
echo "$in: error: a compat entry for an EABI syscall ($name) makes no sense" >&2
exit 1
fi
if [ -n "$entry" ]; then
if [ -z "$compat" ]; then
echo "NATIVE($nr, $entry)"
else
echo "COMPAT($nr, $entry, $compat)"
fi
fi
done
) > "$out"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment