I need to know the function address from current executable on Solaris 10 using C++ (I'm using GNU g++ 4.9.2). For example, I have a function say as: void doSomething(const char *p), that may or may not get defined in current executable. So, I would like to search for the function in the current executable, if exists, then call that else do some default operation. How do I do that? Will dlsym help? Please help me with the syntax and the mangled name.
Asked
Active
Viewed 2,374 times
1
-
Yes, that's exactly the purpose of dlsym. It will return a function pointer (i.e. address) for a function by (mangled) name. – Cameron Nov 22 '16 at 04:46
-
@Cameron Please help me the arguments to use (to search from current executable) and the mangled name – Dr. Debasish Jana Nov 22 '16 at 04:48
2 Answers
3
You can get a list of symbols in your executable by running nm exec
. Or if you are trying to get a symbol from a shared library, you can nm
the library for symbols as well. Pick the one you want, and load it with something like ...
void* handle = dlopen(NULL, RTLD_LAZY);
void* ptr = dlsym(handle, "mangled_name_you_got_from_nm");
Though you will probably want to cast it to the function pointer type of the function you are loading via something like (obviously, change to the appropriate function pointer type)...
void* handle = dlopen(NULL, RTLD_LAZY);
auto ptr = reinterpret_cast<int(*)(int)>(dlsym(handle, "mangled_name_you_got_from_nm"));

pat
- 763
- 4
- 12
-
Is there any equivalent of nm on Solaris 10? That would help me to get the mangled name – Dr. Debasish Jana Nov 22 '16 at 08:24
-
You can go with [elfdump -S](https://docs.oracle.com/cd/E26502_01/html/E29030/elfdump-1.html#REFMAN1elfdump-1) – yugr Nov 22 '16 at 09:02
-
This answer suffers from two flaws: (1) name mangling may change between compilers, or even between different versions of the same compiler. (2) Unless the main executable is linked with `-rdynamic` (or equivalent), the function will not be exported in the dynamic symbol table, and `dlsym` will return `NULL` for it. – Employed Russian Dec 21 '16 at 04:02
-
@EmployedRussian Solaris 10 does not support statically-linked executables. See [Static Linking - where did it go?](https://blogs.oracle.com/rie/entry/static_linking_where_did_it): *With Solaris 10 you can no longer build a static executable. ...* – Andrew Henle Jan 05 '17 at 10:44
-
@AndrewHenle Static linking has absolutely *nothing* to do with the answer, or my comment. – Employed Russian Jan 05 '17 at 15:02
-
@EmployedRussian *Static linking has absolutely nothing to do with the answer, or my comment.* **Wrong.** In your comment, you specifically state the executable has to be dynamically linked: *Unless the main executable is linked with `-rdynamic` (or equivalent)* Again: Solaris 10 does not support anything *but* dynamic linking, so your comment is superfluous. – Andrew Henle Jan 05 '17 at 15:56
-
@AndrewHenle You are mistaken. The `-rdynamic` flag has to do with what symbols are *exported* from *dynamically* linked executable (by default, without `-rdynamic`, *only* the symbols that are referenced by other shared libraries are exported). – Employed Russian Jan 05 '17 at 16:44
1
The need to "call foo()
if it is defined, but do nothing if it's not" is quite common in libraries.
One common example is to call pthread_mutex_lock
and pthread_mutex_unlock
if the program is linked with threads, but perform no locking otherwise.
Weak unresolved symbols are a perfect solution.
extern void foo() __attribute__((weak));
void MaybeCallFoo()
{
if (&foo == NULL) { printf("foo is not defined\n"); return; }
foo(); // It is defined, call it.
}

Employed Russian
- 199,314
- 34
- 295
- 362