We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
....stmdb sp!, {r4, r5} @ push fifth and sixth argstst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?bne __sys_trace cmp scno, #NR_syscalls @ check upper syscall limit @ added codemov ip, scnostmdb sp!, {r4}mov r4, #255add scno, r4, #115 @ preparing the system call number pop {r4}adr lr,a2cont @ getting the return address for the called functionldrcc pc, [tbl, scno, lsl #2] @ my system call a2cont:mov scno, ip @ restoring the original desired system call @ added code endsadr lr, BSYM(ret_fast_syscall) @ return address ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine ...
adr lr,a2contldrcc pc, [tbl, scno, lsl #2]
I'm not 100% sure for Linux - the calling conventions are a little arcane for some of the entry point stuff, but I think the issue is the:adr lr,a2contNormally for ARM the lr contains the return address, so assuming the sys call entry has something valid there (I would expect it to) then you've just corrupted the valid return address that was in the link register. You have to save it to stack, and then restore it after your handler returns.
adr lr,a2cont
adr lr, BSYM(ret_fast_syscall) @ return address
*EDIT* Looking at the original Linux code I'm not sure that's the problem - it corrupts lr too. Are you sure the handler you are jumping to is doing the right thing?