I would like to use openOCD as my debugger to interact with the J-Link adapter on my board. So I download the code from a mirror repository openocd - github and follow the step in README to build it.
./bootstrap (when building from the git repository)
./configure [options]
make
sudo make install
And the configure threw a error:
configure: error: libjaylink-0.2 is required for the SEGGER J-Link Programmer
So I built libjaylink from libjaylink - gitlab and finally got libjaylink.a and libjaylink.so in /usr/local/lib.
After that the build process is smooth and link all the object files into an executable ./src/openocd:
libtool: link: ( cd "src/.libs" && rm -f "libopenocd.la" && ln -s "../libopenocd.la" "libopenocd.la" )
/bin/bash ./libtool --tag=CC --mode=link gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Wpointer-arith -Wundef -Werror -g -O2 -o src/openocd src/main.o src/libopenocd.la ./jimtcl/libjim.a -lutil -ldl
libtool: link: gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Wpointer-arith -Wundef -Werror -g -O2 -o src/openocd src/main.o src/.libs/libopenocd.a -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib /usr/local/lib/libjaylink.so -lusb-1.0 -lm ./jimtcl/libjim.a -lutil -ldl
In my limited experience with linking, the global function symbol in libjaylink.so should be callable in ./src/openocd.
But openocd threw an error when running:
$ ./src/openocd -f interface/jlink.cfg target/stm32f4x.cfg
./src/openocd: symbol lookup error: ./src/openocd: undefined symbol: jaylink_device_get_usb_bus_ports
But it should be in libjaylink.so
$ objdump -t /usr/local/lib/libjaylink.so
...
0000000000004150 g F .text 00000000000000c9 jaylink_device_get_usb_bus_ports
0000000000004110 g F .text 0000000000000036 jaylink_device_get_usb_address
...
Wanted to know if there's something I overlook in dynamic linking or there's some step I can follow to find out problem. orz
What happens when an executable can't find a symbol in dynamic library?
When the executable calls a function (jaylink_device_get_usb_bus_ports()
here), the runtime loader (ld-linux
here) searches all the shared libraries loaded into the current process, and if the symbol can't be found in any of them, the process is terminated (by calling _exit
).
objdump ...
You should not call objdump
on ELF binaries for reasons explained here. Use readelf -s
instead. Here the better choice would be to use nm -D
instead.
some step I can follow to find out problem.
The first order of business is to verify that libjaylink.so
in fact defines the jaylink_device_get_usb_bus_ports()
as an exported function:
nm -D /usr/local/lib/libjaylink.so | grep jaylink_device_get_usb_bus_ports
If the output looks anything other than ...hex-address... T jaylink_device_get_usb_bus_ports
, then it doesn't (and that would need to be debugged separately).
If the output does look correct, you next need to find out whether your ./src/openocd
binary is actually using the version of the library you think it is using. Run ldd ./src/openocd
, chances are there is some other version of libjaylink.so
somewhere on your system.
If the correct library is used, and that library does define the symbol, then further debugging can be accomplished by running
LD_DEBUG=libs,symbols ./src/openocd -f interface/jlink.cfg target/stm32f4x.cfg
This will produce a lot of output and will likely provide a clue as to what went wrong.