highsciguy
highsciguy

Reputation: 2637

How to know which functions of a library get called by a program

Assume I have binary library (*.so) and a binary program using that library (i.e. I do not own the source code for either).

How can I find out which of the library's functions are called at run time. I would like to know their names, but do not need live info.

Neither of the binaries includes debugging symbols.

Upvotes: 8

Views: 2758

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490108

Ignoring (for the moment) the possibility of using dlopen/dlsysm, you'd normally just use something like nm a.out (or whatever your executable's name is).

For C++, you may want to add --demangle to demangle C++ names to something at least marginally more readable. You may also want to use -u to get only undefined external symbols (this will remove a fair a number of symbols you probably don't care about).

If the program is using dlopen/dlsym, then essentially the only way to know what it links with is to monitor it at run time. It could (for example) open a text file, read in some strings, then use those strings as the names of libraries and functions to link with. Changing that text file could completely change what functions it links with, so you can't really determine this based on the content of the executable itself.

Upvotes: 0

Sam Varshavchik
Sam Varshavchik

Reputation: 118330

The objdump command dumps external symbol references from a binary. The typical use case involves running it with the -T option, to dump a binary's external symbol references.

For example, running objdump -T on /bin/ls:

/bin/ls:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   __ctype_toupper_loc
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 getenv
0000000000000000      DF *UND*  0000000000000000              cap_to_text
0000000000000000      DO *UND*  0000000000000000  GLIBC_2.2.5 __progname
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 sigprocmask
...

And so on. The dump includes all external symbol references, not just functions. The manual page explains the meaning of codes in the 2nd column, that specify the type of the external symbol reference. Here, looks like we'll be interested in DFs, indicating dynamic function calls. Here, we see some familiar C library functions, like getenv() and sigprocmask(), being referenced by `/bin/ls.

Unrecognized library calls are likely the result of internal macros in the header files, using the library's internal implementation details. That's probably what "__ctype_toupper_loc" is all about.

When using this with C++ code you also want to specify the -C option, to demangle C++ symbols.

Of course, the fact that a particular binary carries an external reference to some library function doesn't guarantee that the binary will actually call it, at runtime.

Upvotes: 4

Related Questions