diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-01-23 17:01:39 +0100 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2020-03-23 11:14:35 -0400 |
commit | 9b129c41ac1f43d373742697aa2faf6040b9dfab (patch) | |
tree | 25c69d113e954473adb7b5209c76b67773a383e9 /src/arch-arm.c | |
parent | f5b3166d6126f4a45b59d6af6780b5e00a0e9867 (diff) | |
download | libseccomp-9b129c41ac1f43d373742697aa2faf6040b9dfab.tar.gz |
arch: use gperf to generate a perfact hash to lookup syscall names
This patch significantly improves the performance of
seccomp_syscall_resolve_name since it replaces the expensive strcmp
for each syscall in the database, with a lookup table.
The complexity for syscall_resolve_num is not changed and it
uses the linear search, that is anyway less expensive than
seccomp_syscall_resolve_name as it uses an index for comparison
instead of doing a string comparison.
On my machine, calling 1000 seccomp_syscall_resolve_name_arch and
seccomp_syscall_resolve_num_arch over the entire syscalls DB passed
from ~0.45 sec to ~0.06s.
PM: After talking with Giuseppe I made a number of additional
changes, some substantial, the highlights include:
* various style tweaks
* .gitignore fixes
* fixed subject line, tweaked the description
* dropped the arch-syscall-validate changes as they were masking
other problems
* extracted the syscalls.csv and file deletions to other patches
to keep this one more focused
* fixed the x86, x32, arm, all the MIPS ABIs, s390, and s390x ABIs as
the syscall offsets were not properly incorporated into this change
* cleaned up the ABI specific headers
* cleaned up generate_syscalls_perf.sh and renamed to
arch-gperf-generate
* fixed problems with automake's file packaging
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Tom Hromatka <tom.hromatka@oracle.com>
[PM: see notes in the "PM" section above]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src/arch-arm.c')
-rw-r--r-- | src/arch-arm.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/arch-arm.c b/src/arch-arm.c index c797f3f..3465111 100644 --- a/src/arch-arm.c +++ b/src/arch-arm.c @@ -26,13 +26,58 @@ #include "arch.h" #include "arch-arm.h" +#define __SCMP_NR_OABI_SYSCALL_BASE 0x900000 +#define __SCMP_ARM_NR_BASE 0x0f0000 + +/* NOTE: we currently only support the ARM EABI, more info at the URL below: + * -> http://wiki.embeddedarm.com/wiki/EABI_vs_OABI */ +#if 1 +#define __SCMP_NR_BASE 0 +#else +#define __SCMP_NR_BASE __SCMP_NR_OABI_SYSCALL_BASE +#endif + +/** + * Resolve a syscall name to a number + * @param name the syscall name + * + * Resolve the given syscall name to the syscall number using the syscall table. + * Returns the syscall number on success, including negative pseudo syscall + * numbers; returns __NR_SCMP_ERROR on failure. + * + */ +int arm_syscall_resolve_name_munge(const char *name) +{ + int sys; + + sys = arm_syscall_resolve_name(name); + if (sys == __NR_SCMP_ERROR) + return sys; + + return sys + __SCMP_NR_BASE; +} + +/** + * Resolve a syscall number to a name + * @param num the syscall number + * + * Resolve the given syscall number to the syscall name using the syscall table. + * Returns a pointer to the syscall name string on success, including pseudo + * syscall names; returns NULL on failure. + * + */ +const char *arm_syscall_resolve_num_munge(int num) +{ + return arm_syscall_resolve_num(num - __SCMP_NR_BASE); +} + const struct arch_def arch_def_arm = { .token = SCMP_ARCH_ARM, .token_bpf = AUDIT_ARCH_ARM, .size = ARCH_SIZE_32, .endian = ARCH_ENDIAN_LITTLE, - .syscall_resolve_name = arm_syscall_resolve_name, - .syscall_resolve_num = arm_syscall_resolve_num, + .syscall_resolve_name = arm_syscall_resolve_name_munge, + .syscall_resolve_num = arm_syscall_resolve_num_munge, .syscall_rewrite = NULL, .rule_add = NULL, }; |