diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-21 16:13:47 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-21 16:13:47 +0100 |
commit | 74ec14f968a418691b851cbbfeb0269174c64b08 (patch) | |
tree | 9b6b2f6437dc47335fc6160c277992640315bc1d /util.c | |
parent | 7270de551ca6b3ea097c114005b6b028990ce3dc (diff) | |
download | strace-74ec14f968a418691b851cbbfeb0269174c64b08.tar.gz strace-74ec14f968a418691b851cbbfeb0269174c64b08.tar.bz2 strace-74ec14f968a418691b851cbbfeb0269174c64b08.tar.xz |
Eliminate many SCNO_IS_VALID checks
By adding tcp->s_ent pointer tot syscall table entry,
we can replace sysent[tcp->scno] references by tcp->s_ent.
More importantly, we may ensure that tcp->s_ent is always valid,
regardless of tcp->scno value. This allows us to drop
SCNO_IS_VALID(tcp->scno) checks before we access syscall
table entry.
We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks
with a similar technique.
Resulting code shrink:
text data bss dec hex filename
245975 700 19072 265747 40e13 strace.t3/strace
245703 700 19072 265475 40d03 strace.t4/strace
* count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check.
* defs.h: Add "int qual_flg" and "const struct sysent *s_ent"
to struct tcb. Remove "int u_nargs" from it.
Add UNDEFINED_SCNO constant which will mark undefined scnos
in tcp->qual_flg.
* pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check.
Use tcp->s_ent instead of sysent[tcp->scno].
* process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs.
(sys_waitid): Likewise.
* strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS
constant is consistent with init code.
* syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs
instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent.
(decode_ipc_subcall): Likewise.
(printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs.
(printargs_lu): Likewise.
(printargs_ld): Likewise.
(get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check.
If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values.
(internal_fork): Use tcp->s_ent instead of sysent[tcp->scno].
(syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check.
Use tcp->s_ent instead of sysent[tcp->scno].
(get_syscall_args): Likewise.
(get_error): Drop SCNO_IS_VALID check where it is redundant.
(dumpio): Drop SCNO_IS_VALID check where it is redundant.
Use tcp->s_ent instead of sysent[tcp->scno].
(trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead
of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno].
Drop SCNO_IS_VALID check where it is redundant.
Print undefined syscall name with undefined_scno_name(tcp).
(trace_syscall_exiting): Likewise.
* util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno].
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -1332,8 +1332,8 @@ setbpt(struct tcb *tcp) } } - if (sysent[tcp->scno].sys_func == sys_fork || - sysent[tcp->scno].sys_func == sys_vfork) { + if (tcp->s_ent->sys_func == sys_fork || + tcp->s_ent->sys_func == sys_vfork) { if (arg_setup(tcp, &state) < 0 || get_arg0(tcp, &state, &tcp->inst[0]) < 0 || get_arg1(tcp, &state, &tcp->inst[1]) < 0 @@ -1349,7 +1349,7 @@ setbpt(struct tcb *tcp) return 0; } - if (sysent[tcp->scno].sys_func == sys_clone) { + if (tcp->s_ent->sys_func == sys_clone) { /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)' contrary to x86 vfork above. Even on x86 we turn the vfork semantics into plain fork - each application must not |