0

RIP is a register that stores the address of the current instruction. I am writing a system call to get the program counter of a user level process. Taking the following code for an example, the sys_getrip() is the system call that I am working on. How shall I implement it?

The platform that I am working on is Ubuntu 14.04 with Linux kernel 3.14.4.

/*A system call in the kernel level*/
void sys_getrip(){
    char *pc =//What's the magic here?

    printk(KERN_INFO, "The current program counter of %d is %p", current->pid, pc);
}

/*A test function running in user level*/
void main(void){
   ...
   sys_getrip();
   ...
   ...
   sys_getrip();
   ...
}

A similar problem has been posted here: How to print exact value of the program counter in C. I tried the approach in this post by implementing the sys_getrip() as following

void sys_getrip(void){
    printk(KERN_INFO "RIP = %p\n", __builtin_return_address(0));
}

In this case, however, different invokes of sys_getrip() in main() gave the same RIP value.

Community
  • 1
  • 1
Qi Zhang
  • 631
  • 1
  • 7
  • 15
  • Is not that (more or less) the return address of sys_getrip()? _The program counter._ A kind of `push (fp+0)`. Or (more likely) do you mean any other user space thread? _(Sorry for the nitwit question.)_ – Joop Eggen Jul 11 '16 at 05:48
  • @JoopEggen Thank you for your questions. I updated my question a little bit. Actually, my goal is to get the rip of the calling process from inside the system call. – Qi Zhang Jul 11 '16 at 05:57
  • Possible duplicate of [How to print exact value of the program counter in C](http://stackoverflow.com/questions/18350021/how-to-print-exact-value-of-the-program-counter-in-c) – kaylum Jul 11 '16 at 06:00
  • @kaylum I tried the approach in this post by using "printk(KERN_INFO "rip = %p\n", __builtin_return_address(0))" in sys_getrip(). However, different invokes of sys_getrip() in main() gave the same address. – Qi Zhang Jul 11 '16 at 06:22
  • That's a purely user level solution. Why do you need to do it in a system call? That's costly and unnecessary unless you have a very specific reason. – kaylum Jul 11 '16 at 06:23
  • @kaylum I wanna figure out the name of the caller function in the system call. So my idea is to first figure out the RIP, and then refer to the ELF file to find out the name of the caller function. – Qi Zhang Jul 11 '16 at 06:27
  • The user PC is stored in the `task_struct`. See the kernel implementation for [ptrace](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/ptrace.c) for an example of how to access the user registers. – kaylum Jul 11 '16 at 06:33
  • @kaylum Thanks. I tried using sys_ptrace in the system call, but the error said undefined function sys_ptrace. Can I call sys_ptrace directly in the kernel? – Qi Zhang Jul 11 '16 at 06:38

0 Answers0