Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get function's name from function's pointer in Linux kernel?

How to get function's name from function's pointer in C?

Edit: The real case is: I'm writing a linux kernel module and I'm calling kernel functions. Some of these functions are pointers and I want to inspect the code of that function in the kernel source. But I don't know which function it is pointing to. I thought it could be done because, when the system fails (kernel panic) it prints out in the screen the current callstack with function's names. But, I guess I was wrong... am I?

like image 677
Daniel Silveira Avatar asked Dec 08 '08 22:12

Daniel Silveira


People also ask

How do you print a function pointer?

To print the value of a pointer to an object (as opposed to a function pointer) use the p conversion specifier. It is defined to print void -pointers only, so to print out the value of a non void -pointer it needs to be explicitly converted ("casted*") to void* .

Is function name a pointer?

1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function's name can also be used to get functions' address.

What is function pointer Linux?

A function pointer is mutable that holds the location of a method that may be invoked later using that address. Since methods contain behavior, this seems to be helpful. Instead of creating a chunk of code each moment, we require a specific action, like drawing lines; you just have to invoke the method.


1 Answers

I'm surprised why everybody says it is not possible. It is possible on Linux for non-static functions.

I know at least two ways to achieve this.

There are GNU functions for backtrace printing: backtrace() and backtrace_symbols() (See man). In your case you don't need backtrace() as you already have function pointer, you just pass it to backtrace_symbols().

Example (working code):

#include <stdio.h> #include <execinfo.h>  void foo(void) {     printf("foo\n"); }  int main(int argc, char *argv[]) {     void    *funptr = &foo;      backtrace_symbols_fd(&funptr, 1, 1);      return 0; } 

Compile with gcc test.c -rdynamic

Output: ./a.out(foo+0x0)[0x8048634]

It gives you binary name, function name, pointer offset from function start and pointer value so you can parse it.

Another way is to use dladdr() (another extension), I guess print_backtrace() uses dladdr(). dladdr() returns Dl_info structure that has function name in dli_sname field. I don't provide code example here but it is obvious - see man dladdr for details.

NB! Both approaches require function to be non-static!

Well, there is one more way - use debug information using libdwarf but it would require unstripped binary and not very easy to do so I don't recommend it.

like image 183
qrdl Avatar answered Sep 29 '22 03:09

qrdl