Suppose you work with a codebase comprising several tools and libraries and you want to port (or resurrect) some component within such codebase but any clue about where symbols lie within the various libs is either lost or will take ages to find out by looking at the code itself (yes improved documentation can avoid such issues but is quite demanding). What is the fastest way to discover in which library you can find symbols used in the code?
A .o file inside a library might contain symbols (functions, variables etc.) that are not used by your program. At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.
9. Which one of the following command can list the symbols defined in a library? Explanation: None.
To list the symbols stored in the static library we can use the command “nm”, which lists each symbol's symbol value, symbol type, and symbol name from object files.
National Library Symbol/Library Symbol Highway Sign The Task Force had specifically sought a standard symbol that could be used to identify all types of libraries, hoping to increase public awareness of the institution of libraries through the symbol's utilization on library directional signs and promotional materials.
Assuming a linux box, the nm tool, listing names in library files, comes to the rescue.
It can be used to do an extensive search as follows: one can first find all the libraries available (assuming the project have been successfully compiled without the component you are adding) with a find, then such find can be enclosed in a loop where you call nm on all discovered libraries; the output you then grep for discarding "U" references (undefined symbols, aka where else the symbol is being used). On a single bash line that gives:
for lib in $(find base_path -name \*.a) ; do echo $lib ; nm $lib | grep my_symbol | grep -v " U " ; done
where:
The echo generates a list of all libraries found, which is not so clean since it outputs names of libs not holding the symbol, but it was the fastest way I found to have a direct reference to the library so when you see a:
base_path/component/libA.a
0000000000000080 D my_symbol
You have found your usual suspect.
Using nm
, it is possible to list the symbols defined in a binary, and the --defined-only
switch ignores undefined references.
find
In a single command:
find $path -name \*.a -exec bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}" \;
where $path
is the root of the file tree containing the binaries, and $symbol
is the name of the symbol you are looking for.
find
+ GNU parallel
Running nm
on all files can take time, so it could be helpful to process the results of find
in parallel (using GNU parallel
):
find $path -name \*.a | parallel "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
fd
And at last, my favourite. Using the fd
tool, that has a simpler syntax than find
, is generally faster, and processes the results in parallel by default:
fd '.*\.a$' -x bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
Searching for the gz_write
symbol in /usr/lib
on my laptop:
find
takes around 23 secondsfind | parallel
takes around 10 secondsfd
takes around 8 secondsIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With