How to get function address by name?
Asked Answered
N

3

6

I'd like to get function's address by name.

For example, currently I am using dlsym:

unsigned long get_func_addr(const char *func_name)
{
     return (unsigned long)dlsym(NULL, func_name);
}

However, dlsym only works for extern function. It won't work for static function. I know there could multiple static functions with same name in different files. But I need to at least get one static function's address with the name. Sometime static function will be inlned. But it's OK if C file is compiled with debug. I think with -g, the symbol table of static functions is present, but how can I access it?

I don't want to created a table for mapping the string to function address. I need to find a way to do it dynamically.

Nutty answered 8/9, 2011 at 17:25 Comment(6)
Use uintptr_t from stdint.h instead of unsigned long.Brawn
Why do you want to do this? If you're able to guarantee that the module with the static is compiled in debug mode, you should be able to make the function non-static, or add a trivial non-static wrapper for it.Acquiescent
This SO question has some pointers to information on how to read debugging symbols: https://mcmap.net/q/1208349/-read-debugging-information-at-runtime-from-an-application/12711Patinous
"I don't want to created a table for mapping the string to function address." what you are looking for is called magic.Stegosaur
nm <file> will give you symbol addresses (including functions) if you have debug symbols in the file.Carolinacaroline
Yes, for static symbol in executable. nm will give the address. For static symbols in shared library, I now get the address through "pmap" info and "nm". it works now!Nutty
F
3

This isn't really possible without somehow creating some external file that can be used for a look-up ... for instance, as you mentioned, a symbol table of static functions is present, but that is generated at compile/link time ... it is not something accessible from a non-compiled code module.

So basically you could generate and export the symbol table as an external file from your compiled and linked executable, and then have a function that dynamically looks up the function name in the external file which would provide the information necessary to get the address of the function where the complier and linker compiled/linked it to.

Fourchette answered 8/9, 2011 at 17:32 Comment(2)
I am thinking it could be possible. You know, backtrace() can get functions' name from address. It should not be too difficult to extend backtrace to support getting address from name.Nutty
Yes, but backtrace() is a function implemented by libc and is therefore part of the OS runtime that is running your executable. If you had another program that was creating a virtual runtime for your C executable, then you could also create functions callable from your executable where the runtime could inspect your process and then return information back to you (i.e, ptrace, debuggers, etc.). But that's not really possible from within your own code unless the runtime has created a method of communication between your executable and itself.Fourchette
F
3

A static function need not even exist in the binary, so there's no way to get its address. Even if it does exist, it might have been modified by the compiler based on the knowledge that certain arguments can only take particular values, or it might have had the calling convention adjusted such that it's not externally callable, etc. The only way you can be sure a "real" version of a static function exists is if its address is made visible to other modules via a function pointer.

Famous answered 8/9, 2011 at 18:19 Comment(0)
V
0

If the required function you want to lookup is in a DLL, you could use the Windows API getprocaddress(), which takes the name of the function and the name of the DLL as parameters.

If you want to find user defined functions, I would recommend using a lookup table as the names of those functions are not stored.

For user defined functions, you could force that every function export its name to another function at its start. i.e.:

void my_func()
{
    register(my_func,"my_func");// the address and the name
    // ...
}

Thus you could lookup the function later by name.

Voigt answered 17/9, 2011 at 5:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.