I have an executable and it calls a function. There are a lot of static and dynamic libraries that are linked with this exe. I need to know which one provides this function.
You can get a list of shared libraries used by the executable foo like this:
ldd -v foo
This post:
How do I list the symbols in a .so file
explains how to list symbols (exported functions) in a shared library.
If your library is linked statically, it'll show up in the list of symbols inside the executable itself:
nm -C foo
The same command will also list the names of all exported symbols (function names) in a static library:
nm -C libasan.a
You may want to construct a shell script to enumerate your libraries, looking for the specific function that you want inside each one. For example, to figure out which .a file provides sprintf():
for x in *.a; do echo --- ${x} ---; nm -C $x | grep sprintf ; done
Related
Does anyone know how to use gcc to generate all possible binary files from object files ? I know you can use : "gcc -MM" to generate all the .o files for some given source files.
But how would you use gcc to generate all possible binary files from object files
in a project ?
Example: I use "gcc -MM" to generate: a.o, b.o, c.o, d.o
If one were trying to generate a list of binaries files built from each of the .o files like this:
a: b.o c.o d.o
b: a.o c.o d.o
c: a.o b.o d.o
d: a.o b.o b.o
I can do this with a Perl script, but I was just curious if there was some way to do it with gcc
Thanks
Short answer, "no, but..."
gcc -MM can give you foo.o: bar.h because foo.cc contains the directive:
#include "bar.h"
That's easy. But foo.cc can also contain the declaration:
int bar_f1(int);
How can gcc know which object file contains the binary code for this function? Or if there are two object files containing functions with this signature, which it should use? It can't.
...Unless...
Long answer, "yes, if..."
If you refrain from giving source files forward declarations of things in other source files, and also refrain from giving a header file declarations of anything not contained in the corresponding source file, and also give the source file containing int main(...) a fixed name like, say, main.cc, then you can take the output of gcc -MM:
bar.o: bar.h baz.h
foo.o: bar.h
main.o: foo.h zot.h
pan.o: pan.h
zot.o: zot.h
and transform it without too much trouble (using e.g Perl or sed) into:
main: bar.o foo.o zot.o
In theory you could get by without these restrictions(*) by scanning the object files and constructing the dependency tree; this might be equivalent to scanning for the presence of int main(...), segregating those files and linking each of them against all the others, or just listing them, if all you want is a list of possible executables without dependencies (I'm still not sure exactly what you want). These things still require some scripting on your part, I know of no way to do them with gcc alone.
(*)You must still refrain from having two definitions of the same thing.
I mean whether gcc can insert some source code version infor into ELF binary as section or something similar. I do not want to change my source file, but add some info with gcc option in Makefile.
If you don't mind changing your source file just once, add something like this:
const volatile static char version[] = VERSION;
and compile with:
gcc -c -DVERSION='"1.2.3"'
The volatile keeps gcc from removing the string at higher optimization levels.
As written, this won't compile if you forget the -D option, which may be either good or bad depending on your requirements.
You can emit your version info into a text file, then turn that text file into an object file which you then statically link into your executable.
The first step is simple but you have to write some code: a script or something to write your version info in any format you like as a plain text file. Then write a makefile rule to produce say version.o from version.txt, using objcopy. Now you'll have an object file with two useful symbols defined in it: the beginning and end of the textual version info. Add that generated object to your executable, and you'll be able to access the version two ways: by running strings on the binary, or by writing code in the application to print the version string (you'll need to declare the start and end symbols as variables in some header file).
Even if you don't have access to your source anymore, you can link the object with this option:
gcc -Wl,--defsym,VERSION_1_2_3=0 prog.o -o prog
You can check it with hexdump -C prog | less and look for VERSION
Add this to your makefile and be sure to always know when a program was compiled:
BUILD = $(shell date +"%Y%m%d_%H%M%S")
LDLIBS = -Wl,--defsym,BUILD_$(BUILD)=0
With the GNU linker ld You can use
--version-script=version-scriptfile
Read more about the command-line options at:
Using LD, the GNU linker - Options
Read more about creating version scripts at:
Using LD, the GNU linker - Version Script
Let me warn you though, that it is not for the weak-hearted!
Where does the ELF format stores the names of imported functions? Is it always possible to enumerate all import names, like for PE executables?
For example, if a binary is using printf is it possible to tell it does, just by static analysis of the binary itself?
In ELF they're called undefined symbols. You can view the list of undefined symbols by:
nm -D <file>|grep -w U
objdump -T <file>|grep "\*UND\*"
ELF files don't specify which symbols come from which libraries; it just adds a list of shared libraries to link to into the ELF binary, and lets the linker find the symbols in the libraries.
I have a program, myprogram, which is linked with a static convenience library, call it libconvenience.a, which contains a function, func(). The function func() isn't called anywhere in myprogram; it needs to be able to be called from a plugin library, plugin.so.
The symbol func() is not getting exported dynamically in myprogram. If I run
nm myprogram | grep func
I get nothing. However, it isn't missing from libconvenience.a:
nm libconvenience/libconvenience.a | grep func
00000000 T func
I am using automake, but if I do the last linking step by hand on the command line instead, it doesn't work either:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`
However, if I link the program like this, skipping the use of a convenience library and linking the object files that would have gone into libconvenience.a directly, func() shows up in myprogram's symbols as it should:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`
If I add a dummy call to func() somewhere in myprogram, then func() also shows up in myprogram's symbols. But I thought that --export-dynamic was supposed to export all symbols regardless of whether they were used in the program or not!
I am using automake 1.11.1 and gcc 4.5.1 on Fedora 14. I am also using Libtool 2.2.10 to build plugin.so (but not the convenience library.)
I didn't forget to put -Wl,--export-dynamic in myprogram_LDFLAGS, nor did I forget to put the source that contains func() in libconvenience_a_SOURCES (some Googling suggests that these are common causes of this problem.)
Can somebody help me understand what is going on here?
I managed to solve it. It was this note from John Calcote's excellent Autotools book that pointed me in the right direction:
Linkers add to the binary product every object file specified explicitly on the command line, but they only extract from archives those object files that are actually referenced in the code being linked.
To counteract this behavior, one can use the --whole-archive flag to libtool. However, this causes all the symbols from all the system libraries to be pulled in also, causing lots of double symbol definition errors. So --whole-archive needs to be right before libconvenience.a on the linker command line, and it needs to be followed by --no-whole-archive so that the other libraries aren't treated that way. This is a bit difficult since automake and libtool don't really guarantee keeping your flags in the same order on the command line, but this line in Makefile.am did the trick:
myprogram_LDFLAGS = -Wl,--export-dynamic \
-Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive
If you need func to be in plugin.so, you should try and locate it there if possible. Convenience libraries are meant to be just that -- a convenience to link to an executable or lib as an intermediate step.
There is an executable that is dynamically linked to number of shared objects. How can I determine, to which of them some symbol (imported into executable) belongs ?
If there are more than one possibility, could I silmulate ld and see from where it is being taken ?
Have a look at nm(1), objdump(1) and elfdump(1).
As well as the ones Charlie mentioned, "ldd" might do some of what you're looking for.
If you can relink the executable, the simplest way to find out where references and definitions come from is using ld -y flag. For example:
$ cat t.c
int main() { printf("Hello\n"); return 0; }
$ gcc t.c -Wl,-yprintf
/lib/libc.so.6: definition of printf
If you can not relink the executable, then run ldd on it, and then run 'nm -D' on all the libraries listed in order, and grep for the symbol you are interested in.
$LD_DEBUG=bindings my_program
That would print all the symbol bindings on the console.