This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Bug runtime/22847] ARM OABI syscall tracing issues
- From: "mysecondaccountabc at gmail dot com" <sourceware-bugzilla at sourceware dot org>
- To: systemtap at sourceware dot org
- Date: Mon, 19 Feb 2018 22:42:00 +0000
- Subject: [Bug runtime/22847] ARM OABI syscall tracing issues
- Auto-submitted: auto-generated
- References: <bug-22847-6586@http.sourceware.org/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=22847
--- Comment #9 from Gustavo Moreira <mysecondaccountabc at gmail dot com> ---
(In reply to David Smith from comment #8)
> (In reply to Gustavo Moreira from comment #5)
> > (In reply to David Smith from comment #4)
> > > > 1) Is your connect syscall implemented via sys_connect() or through
> > > > sys_socketcall(), or perhaps through some arch-specific function? Run a test
> > > > binary, set a probe on both sys_connect() and sys_socketcall() and see what
> > > > gets hit. (If you need a test program, look in
> > > > testsuite/systemtap.syscall/connect.c.)
> > >
> > > To be clear here, that try the following:
> > >
> > > # stap -ve 'probe kernel.function("sys_connect").call,
> > > kernel.function("sys_socketcall").call { printf("%s\n", ppfunc()) }' -c
> > > test_program
> > >
> >
> > It's implemented using sys_connect:
> > ...
> > Pass 5: starting run.
> > SyS_connect
> > Connected
> > Pass 5: run completed in 320usr/890sys/2179real ms
> >
> > However, for some reason, the syscall probe alias syscall.*/nd_syscall.*
> > don't capture that.
> >
> >
> > > > 2) Are you getting the correct syscall number for both ABIs? Run your test
> > > > program (compiled once for each ABI) and see what _stp_syscall_nr() returns.
> > > > Is the number the same for both ABIs?
> > >
> > > To be clear here, that try the following:
> > >
> > > # stap -ve 'probe kernel.function("sys_connect").call,
> > > kernel.function("sys_socketcall").call { printf("%s - %d\n", ppfunc(),
> > > _stp_syscall_nr()) }' -c test_program
> > >
> > The above returns:
> > SyS_connect - 32916
> >
> > However, that is not correct because apparently _stp_syscall_nr() is made
> > for EABI where the syscall number is passed using R7.
> >
> > systemtap/runtime/syscall.h:
> > ...
> > #if defined(__arm__)
> > ...
> > static inline long _stp_syscall_get_nr(struct task_struct *task, struct
> > pt_regs *regs)
> > {
> > return regs->ARM_r7;
> > }
> >
> > In OABI the syscall convention is svc 0x900000 + SYSCALL_NR.
> > For instance, for sys_exit() syscall:
> >
> > EABI:
> > mov r7, #0x01 ; sys_exit
> > svc #0x00
> >
> > OABI:
> > svc #0x900001 ; sys_exit
> >
> > man syscall(2):
> > arch/ABI instruction syscall # retval Notes
> > ──────────────────────────────────────────────────────────
> > arm/OABI swi NR - a1 NR is syscall #
> > arm/EABI swi 0x0 r7 r0
> >
> > In the attached example:
> > $ objdump -d test_program | grep -A2 "libc_connect>:"
> > 00008830 <__libc_connect>:
> > 8830: e92d4010 push {r4, lr}
> > 8834: ef90011b svc 0x0090011b
> >
> > Where 0x11b (283) is sys_connect .
> >
> > In the kernel source
> > (https://elixir.bootlin.com/linux/v4.9.75/source/arch/arm/include/uapi/asm/
> > unistd.h):
> > #define __NR_OABI_SYSCALL_BASE 0x900000
> > ...
> > #if defined(__thumb__) || defined(__ARM_EABI__)
> > #define __NR_SYSCALL_BASE 0
> > #else
> > #define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
> > #endif
> > ...
> > #define __NR_exit (__NR_SYSCALL_BASE+ 1)
> > ...
> > #define __NR_connect (__NR_SYSCALL_BASE+283)
>
> OK, let's start small here and try to fix _stp_syscall_get_nr() for OABI.
> Try the following patch (which tries to use the kernel's syscall_get_nr()):
>
> ====
> diff --git a/runtime/syscall.h b/runtime/syscall.h
> index 5ed019869..1f5552d78 100644
> --- a/runtime/syscall.h
> +++ b/runtime/syscall.h
> @@ -166,11 +166,15 @@
> * returns 0 (since it was designed to be used with ftrace syscall
> * tracing, not called from any context). So, let's use our function
> * instead. */
> +#if defined(__thumb__) || defined(__ARM_EABI__)
> static inline long
> _stp_syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
> {
> return regs->ARM_r7;
> }
> +#else
> +#define _stp_syscall_get_nr syscall_get_nr
> +#endif
>
> #elif defined(__mips__)
> /* Define our own function as syscall_get_nr always returns 0 unless
> ====
>
> With that patch added, does the following return the correct value?
>
> # stap -ve 'kernel.function("sys_socketcall").call { printf("%s - %d\n",
> ppfunc(), _stp_syscall_nr()) }' -c test_program
I've added "probe" at the beginning and changed the syscall to "sys_connect"
because it doesn't use sys_socketcall.
# stap -ve 'probe kernel.function("sys_connect").call { printf("%s - %d\n",
ppfunc(), _stp_syscall_nr()) }' -c ./ex_socket_OABI
Pass 1: parsed user script and 452 library scripts using
40896virt/33624res/4948shr/28920data kb, in 4780usr/1090sys/5869real ms.
Pass 2: analyzed script: 1 probe, 2 functions, 97 embeds, 0 globals using
77520virt/70912res/5528shr/65544data kb, in 13480usr/11970sys/25472real ms.
Pass 3: translated to C into
"/tmp/stapSl5Rx9/stap_195c43dcde9908a38abbe97ece0f593b_53976_src.c" using
77520virt/71040res/5656shr/65544data kb, in 1670usr/10930sys/12604real ms.
Pass 4: compiled C into "stap_195c43dcde9908a38abbe97ece0f593b_53976.ko" in
58570usr/20570sys/73572real ms.
Pass 5: starting run.
SyS_connect - 32916
Connected
Pass 5: run completed in 370usr/1000sys/2316real ms.
However, the result seems to be the same. I've patched the file in the
installation directory (/usr/share/systemtap/runtime/syscall.h). I don't think
SystemTap needs to be completely recompiled again, right? The change should be
included when it compiles the LKM in the above stap execution.
--
You are receiving this mail because:
You are the assignee for the bug.