I have a dynamically linked library that defines __attribute__((visibility("hidden")))
symbol which I need to access. Here is a simplified code
shared.c
__attribute__((visibility("hidden"))) int hidden_sym[12];
int visible_sym[12];
shared_user.c
#include <dlfcn.h>
#include <stdio.h>
int main() {
void* dlopen_res = dlopen("./libnogcc.so", RTLD_LAZY);
if (dlopen_res == NULL) {
printf("dlopen_res is NULL: %s\n", dlerror());
return 1;
}
if (dlsym(dlopen_res, "visible_sym") == NULL) {
printf("bb_so is NULL: %s\n", dlerror());
return 1;
} else {
printf("'visible_sym' open ok\n");
}
if (dlsym(dlopen_res, "hidden_sym") == NULL) {
printf("bb_so is NULL: %s\n", dlerror());
return 1;
}
}
compilation and execution
gcc shared.c -fpic -shared -olibnogcc.so
gcc -ldl shared_user.c -o shared_main
./shared_main
It correctly loads visible_symbol
, but expectedly fails to resolve the hidden symbol:
'visible_sym' open ok
bb_so is NULL: ./libnogcc.so: undefined symbol: hidden_sym
I want to know if there is any workaround that would allow me to get access to the hidden symbol.
Note that it is not required to be a dlsym
-based solution. Anything that would give me access to the hidden symbol, without modification of the library symbol table, would be considered an accepted solution.
My real-world use case is quite similar - I want to get access to the profiling information that is generated by gprof
in instrumented code. I'm still not exactly sure, but it seems like it is stored in the __bb_head
variable that is declared as struct __bb *__bb_head __attribute__((visibility("hidden")));
. Structure definition is accessible using <sys/gmon.h>
and <sys/gmon_out.h>
headers, but I wasn't able to find any way to actually get profiling data in raw form. I am aware that gprof
allows me to dump information when the program has finished executing, but I need to get this data at runtime, without having to force file writing and then re-reading it back.
code for accessing libc data
#include <dlfcn.h>
#include <stdio.h>
#include <sys/gmon.h>
#include <sys/gmon_out.h>
int main() {
void* dlopen_res = dlopen("libc.so.6", RTLD_LAZY);
if (dlopen_res == NULL) {
printf("dlopen_res is NULL: %s\n", dlerror());
return 1;
}
void* bb_so = dlsym(dlopen_res, "__bb_head");
if (bb_so == NULL) {
printf("bb_so is NULL: %s\n", dlerror());
return 1;
}
}