I am a newbie with psp programming.
After checking the kernal library implementation, I found all the entry stub of system call is replace as 03e00008 jr ra. I am really confused how the system call is made.
Hope some one here can give me the answer. Thanks.
How user mode program make a system call
The PSP's kernel fixes up the system calls according to the import definitions present in the executable at load time. You really shouldn't need to worry about it for the most part as the psp kernel and pspsdk handle it all for you.
If you must know more then load a program and dump the instructions (which in the ELF was just jr $ra) to a file on the ms and disassemble them, you will then see the actual syscall instructions.
If you must know more then load a program and dump the instructions (which in the ELF was just jr $ra) to a file on the ms and disassemble them, you will then see the actual syscall instructions.
You're probably being confused by the way the MIPS processor handles jump instructions.
Basically, it will always execute the next instruction following the jump, before making the jump itself.
So, you'll probably find that the entry stub really looks like this:
jr $ra
sycall 0xnnnn
which will actually execute the syscall before the jump takes effect.
It's really confusing the first few times you see it, then you get used to it.
If I remember right then branch instructions do the same thing.
Basically, it will always execute the next instruction following the jump, before making the jump itself.
So, you'll probably find that the entry stub really looks like this:
jr $ra
sycall 0xnnnn
which will actually execute the syscall before the jump takes effect.
It's really confusing the first few times you see it, then you get used to it.
If I remember right then branch instructions do the same thing.
Thanks for your replies
After reading your explanation about load time fixup and misp jump instruction, I still have some questions.
At the link time the import stub of system call looks like:
jr ra
nop
The psp system loader will do the load time fixup and change the stub to what looks like:
jr ra
system call
If the system call is put in the defer slot of the return instruction jr ra, it means that the system call is made and the control returns to the caller at the same time.
But I think the control should not return to caller until the system call is completed. Another thing is that the control transfer instruction usually should not be put in jump instruction's defer slot.
At the link time the import stub of system call looks like:
jr ra
nop
The psp system loader will do the load time fixup and change the stub to what looks like:
jr ra
system call
If the system call is put in the defer slot of the return instruction jr ra, it means that the system call is made and the control returns to the caller at the same time.
But I think the control should not return to caller until the system call is completed. Another thing is that the control transfer instruction usually should not be put in jump instruction's defer slot.
The final resolution of the jump call, and setting of $PC to the destination address, only happens after the defer slot instruction is completed.
So you don't get the syscall and the JR happening at the same time - they're executed in order, it's just that the order is the opposite to what you'd think when looking at the disassembly naively.
It does seem odd (and confusing) that syscalls are used in the defer slot, but it does work and it's just the way that things are done.
So you don't get the syscall and the JR happening at the same time - they're executed in order, it's just that the order is the opposite to what you'd think when looking at the disassembly naively.
It does seem odd (and confusing) that syscalls are used in the defer slot, but it does work and it's just the way that things are done.