This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Calling a function in kernel initialization code

Note: This was originally posted on 3rd September 2012 at http://forums.arm.com

As part of a project I'm trying to modify the entry point to an ARM Linux kernel through the file entry-common.S. I'm not quite familiar with the ARM architecture but I'm learning. What I need to do is when a system call is about to happen, for some system call numbers, I do some pre-call by calling another system call and then continue calling the desired system call.

So, I had to modify entry-common.S as follows:




....
stmdb   sp!, {r4, r5}     @ push fifth and sixth args
tst ip, #_TIF_SYSCALL_TRACE  @ are we tracing syscalls?
bne __sys_trace

cmp scno, #NR_syscalls      @ check upper syscall limit

@ added code
mov ip, scno
stmdb   sp!, {r4}
mov  r4, #255
add  scno, r4, #115   @ preparing the system call number
pop  {r4}
adr lr,a2cont        @ getting the return address for the called function
ldrcc   pc, [tbl, scno, lsl #2]  @ my system call
a2cont:
mov  scno, ip   @ restoring the original desired system call

@ added code ends

adr lr, BSYM(ret_fast_syscall)  @ return address 
ldrcc   pc, [tbl, scno, lsl #2]  @ call sys_* routine
    ...


[font="Arial,"]

[size="2"]This code does not work. The issue is with the my first call:

adr lr,a2contldrcc   pc, [tbl, scno, lsl #2]
[/size]

[size="2"]It looks like the call does not return to the appropriate location. If I remove these two lines, the kernel proceeds with no issues. I'm probably missing something about the call stack in ARM. Any thoughts is highly appreciated.

[/size]
Parents
  • Note: This was originally posted on 3rd September 2012 at http://forums.arm.com

    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,a2cont


    Normally 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.

    *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?
Reply
  • Note: This was originally posted on 3rd September 2012 at http://forums.arm.com

    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,a2cont


    Normally 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.

    *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?
Children
No data