How to programmatically display ELF shared library symbols

In my shared C library, I want to dlopen () another shared library and get a list of exported symbols that the library has.

Is there a way to do this programmatically, without running nm / objdump?

As a side question: How do I get the base address where this second library loaded after dlopen () - without knowing the names of any symbols (so I can't run dlsym!) And without reading / proc / self / the map?

I've tried the following:

struct link_map *imagehandle = (struct link_map*)dlopen(libraryname, RTLD_LOCAL | RTLD_LAZY);
void * fbase = (void*) imagehandle->l_addr;
printf("base addr is %p",fbase)

      

Will print

"base addr is 0x6862696c"

However, the library is not there:

[/ proc / pid / maps output:]

b6d27000-b6d28000 r-xp 00000000 1f:01 1581       mysecondlib.so
b6d28000-b6d29000 r--p 00000000 1f:01 1581       mysecondlib.so
b6d29000-b6d2a000 rw-p 00001000 1f:01 1581       mysecondlib.so

      

It has been suggested that l_addr is not the actual base address of the library, but an offset from the executable header - but I'm not sure how to find that header address.

+3


source to share


1 answer


Yes, you can definitely get the symbol table programmatically. I would suggest that instead of running dlopen () on SO, you open it yourself via mmap, or even just read the file into contiguous memory yourself. After doing this in memory, you can easily iterate over each SO section by following the documentation below: http://linux.die.net/man/5/elf . Sections that have sh_type equal to SHT_SYMTAB (symbol table) are what you are looking for.



IF you still need to find the base address of the loaded SO, I haven't found a way to get it from dlopen () in my experience. The best way I have found is to call dladdr () on a known symbol in SO, which populates the Dl_info structure that contains the dli_fbase member, which is the base address of the module the symbol came from. If you don't really know any symbol from this SO you can use dl_iterate_phdr ( http://linux.die.net/man/3/dl_iterate_phdr ) which will iterate over all loaded SOs into your process and give you an instance of the dl_phdr_info structure for each of them. This structure contains the name, base address (dlpi_addr), and an array of program headers.

+2


source







All Articles