where is __aeabi_f2lz implemented? - android-ndk

I have a library which depend on a static library(libexample.a) that I get from third party.
My build failed at linking stage complain about __aeabi_f2lz is undefined. I checked the static lib and it has a undefined symbol __aeabi_f2lz. I would expect this symbol could be resolved while linking.
Also, if I add code like this in my library:
volatile float fixme_float = 1.3f;
volatile int64_t fixme_int64 = static_cast<int64_t>(fixme_float);
The linking error disappear. I think the above code forced a use of __aeabi_f2lz and mysteriously solved the linking error. I suspect that this is just a linking order issue.
Does anyone know which library contains the implementation of __aeabi_f2lz? I want to force dependency to the library after link the static lib to see if I can solve the issue. Or am I even right to claim that this is because of linking order? I am using Android NDK's standalone arm toolchain.
Thanks for help!
Update[1]:
The build command is:
third_party/llvm-build/Release+Asserts/bin/clang++ -shared -Wl,--fatal-warnings \
-fPIC -Wl,-z,noexecstack -Wl,-z,now -Wl,-z,relro -Wl,-z,defs -Wl,--as-needed \
--gcc-toolchain=third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
-fuse-ld=gold -Wl,--icf=all -Wl,--no-undefined -Wl,--exclude-libs=libgcc.a \
-Wl,--exclude-libs=libc++_static.a -Wl,--exclude-libs=libvpx_assembly_arm.a \
--target=arm-linux-androideabi -Werror -nostdlib \
--sysroot=.third_party/android_tools/ndk/platforms/android-16/arch-arm \
-Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,malloc -Wl,-wrap,memalign \
-Wl,-wrap,posix_memalign -Wl,-wrap,pvalloc -Wl,-wrap,realloc -Wl,-wrap,valloc \
-Lthird_party/android_tools/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a \
-o "./lib.unstripped/libexample.so" -Wl,-soname="libexample.so"

It's in libgcc:
$ readelf -sW $NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a | grep __aeabi_f2lz
24: 00000000 56 FUNC GLOBAL DEFAULT 1 __aeabi_f2lz
This is linked by default though. You might have something wrong with your linking order. Could you update your answer to include the command you're using to link your library?

Related

musl fails to link libc.a into shared library

I have a C99 shared library that I want to link in a few statically static libraries (via --whole-archive). Note: All the static libs are built with -fPIC
I also would like to build a universal linux binary and thus have decided to use musl. When I try to link in the static libc.a from musl I get the following error:
# Building shared library tgt/Linux-x86_64/mylib/lib/mylib.so
/root/mylib/./tgt/Linux-x86_64/libmusl/bin/musl-gcc -Wl,-whole-archive -L./tgt/Linux-x86_64/libmusl/lib -L./tgt/Linux-x86_64/libz/lib -L./tgt/Linux-x86_64/libssl/lib -L./tgt/Linux-x86_64/libsasl/lib -L./tgt/Linux-x86_64/librdkafka/lib -L./tgt/Linux-x86_64/libcurl/lib -L./tgt/Linux-x86_64/libgjalloc/lib -L./tgt/Linux-x86_64/libavro/lib -L./tgt/Linux-x86_64/libunwind/lib -l:libc.a -l:libpthread.a -l:libz.a -l:libssl.a -l:libcrypto.a -l:libsasl2.a -l:libm.a -l:librt.a -l:libcrypt.a -l:libunwind-x86_64.a -l:librdkafka.a -l:libcurl.a -l:libgjalloc.a -l:libavro.a -Wl,-no-whole-archive -shared -fPIC -o tgt/Linux-x86_64/mylib/lib/mylib.so ./tgt/Linux-x86_64/mylib/obj/myfile.o ./tgt/Linux-x86_64/mylib/obj/myotherfile.o ./tgt/Linux-x86_64/mylib/obj/cJSON.o
/usr/bin/ld: ./tgt/Linux-x86_64/libmusl/lib/libc.a(exit.lo): relocation R_X86_64_PC32 against undefined hidden symbol `__fini_array_start' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make: *** [tgt/Linux-x86_64/mylib/lib/mylib.so] Error 1
My musl build looks like:
cd mystatic_libs_build_dir/musl; \
./configure CFLAGS='-fPIC' \
--enable-shared \
--enable-static \
--prefix=/root/mylib/tgt/Linux-x86_64/libmusl; \
make; make install;
# libmusl is available
exit.lo will be written in assembler which is why your CFLAGS='-fPIC' is not having the effect you intend. This is either 1. a bug in 'musl' or 2. intentional and they do not support statically linking into .so's.
I would assume that it is unintentional and file a bug against 'musl'
You could also edit the asm yourself if you need a fix quickly.
Finally you might be able to configure musl to build with no asm?
Slightly off topic, but other options for a universal binary are:
Simply linking against glibc on the oldest version of Linux that you support.
Rather than struggling with a dependency on 'musl', simply use the Linux kernel api's directly.
Recompile musl as long as your own code with CFLAGS="-fPIC -Wa,-mrelax-relocations=no" (your binutils version must be >=2.27).

how to pass -fPIC to GCC on linux

I am trying to compile libedit on linux using GCC 5.3 and am getting a cryptic error message.
/home/mybin/libgcc/x86_64-unknown-linux-gnu/5.3.0/../../../libcurses.a(lib_termcap.o): relocation R_X86_64_32 against `_nc_globals' can not be used when making a shared object; recompile with -fPIC
/home/mybin/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../libcurses.a: could not read symbols: Bad value
To what does the recompile with -fPIC refer, ncurses or libedit? and then how do I pass the -fPIC flag. I have tried adding CFLAGS=-fPIC to the configure of ncurses & libedit but still did not work.
I have found may posts on SO about what -fPIC is, but none on how to set the flag.
thanks Art
Perhaps you ran afoul of the changes outlined in Fedora's Changes/Harden All Packages which use a linker spec that only works if you have compiled using either -fPIC or -fPIE. The linker message is almost useless; only the part about -fPIC has any usefulness.
To address this problem, you can add/modify the compiler flags in several ways. One of the simplest is to set it in the CFLAGS environment variable, e.g.,
export CFLAGS='-O -fPIC'
If you happen to be building ncurses, this means that you would have to also be configuring to build only shared libraries, e.g.,
configure --with-shared --without-normal --without-debug
Of course that all works best if you do not have a previous set of makefiles, etc.
You're looking at the wrong part of the error message. The "relocation R_X86_64_32" means that you're trying to build 32-bit code against a 64-bit library or vice versa. Make sure you have selected the same architecture for both.
-fPIC is used to generate position independent code, it is used to create shared libraries. the make file has a problem, to fix it:
edit the Makefile, line 98 :
.c.o:
${CC} ${CFLAGS} -c $<
after CC add -fpic after CC like this :
.c.o:
${CC} -fpic ${CFLAGS} -c $<
also in line 103:
libedit.so: ${OOBJS}
${CC} --shared -o $# ${OOBJS}
add -fpic after --shared:
libedit.so: ${OOBJS}
${CC} --shared -fpic -o $# ${OOBJS}
if you are wondering what is the difference between -fPIC and -fpic note that they both do the same thing but -fpic is more efficient, check this for more informations What is the difference between `-fpic` and `-fPIC` gcc parameters?.

Linux using lapack library

I have an error making a code project because of what I believe is a missing routine from lapack:
HomographyInit.cc:(.text+0x385): undefined reference to `dgesvd_'
I think I need to add lapack library somehow to my Makefile. Here is part of my Makefile:
CC = g++
COMPILEFLAGS = -I MY_CUSTOM_INCLUDE_PATH -D_LINUX -D_REENTRANT -Wall -O3 -march=nocona -msse3
LINKFLAGS = -L MY_CUSTOM_LINK_PATH -lGVars3 -lcvd
I tried doing the following to no avail:
CC = g++
COMPILEFLAGS = -I MY_CUSTOM_INCLUDE_PATH -D_LINUX -D_REENTRANT -Wall -O3 -march=nocona -msse3
LINKFLAGS = -L MY_CUSTOM_LINK_PATH -lGVars3 -lcvd **-llapack**
Result:
make
...
/usr/bin/ld: cannot find -llapack
collect2: ld returned 1 exit status
How can I add lapack to my project? I am pretty sure I installed it correctly, though would be willing to double-check that somehow.
It looks like liblapack isn't in the path that ld can find. I would suggest two things:
Establish a symbolic link manually. It is possible (and sometimes common) that ld cannot recognize liblapack.so.3gf or liblapack.so.3.0.1 or so are essentially liblapack.so. You can set up a link by ln -s liblapack.so.3gf liblapack.so
Install liblapack-dev package instead if you're using ubuntu or debian repos. For some unclear reasons, liblapack3gf is not the same as liblapack-dev. I am not sure if in any circumstances, both will do or not do the same thing.
I think the first item should be able to resolve your problem (hopefully).
On my computer the dynamic library is in /usr/lib64/liblapack.so.3.4.1 and contains the requested symbol:
$ nm -D /usr/lib64/liblapack.so.3.4.1 | grep dgesvd
0000000000189200 T dgesvd_
So I would guess that the place where your lapack is installed is not in the linker search path. You should add the flag -L/path/to/the/lapackdir to LINKFLAGS

Linker error on Linux: "undefined reference to"

I am able to make a shared library without problems. I create libcbitcoin.so (without any errors) and attempt to link against it with an executable as well as OpenSSL libraries. I use this command:
gcc -L/media/sf_BitEagle_Projects/cbitcoin/build/bin -lcbitcoin \
-Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin -lssl -lcrypto \
-L/usr/local/ssl/lib/ -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o
The bin directory is the location of the library. The obj directory has the object files I wish to link into an executable. In the command I use the -L, -l and -rpath* options which I thought was all that is needed for linking in Linux. It seems I am wrong since I get errors like:
/media/sf_BitEagle_Projects/cbitcoin/test/testCBAddress.c:40:
undefined reference to `CBNewByteArrayFromString'
CBNewByteArrayFromString is found in the library. For some reason it is not being linked. OpenSSL too:
/media/sf_BitEagle_Projects/cbitcoin/dependencies/crypto/CBOpenSSLCrypto.c:37:
undefined reference to `SHA1'
How do I get the linking to work?
GCC version: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
It is on Linux Mint 13 (Maya).
Put the libraries after the object files on the link command line:
gcc /media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o \
-L/media/sf_BitEagle_Projects/cbitcoin/build/bin \
-lcbitcoin -Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin \
-L/usr/local/ssl/lib/ -lssl -lcrypto \
-o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress
If you don't do that, the linker may decide that it needs nothing from a particular library at the stage of the link where it scans the library, and then it won't rescan the library later after it finds some undefined symbols in the object files. If you put the object files first, you don't run into this problem.
I think it is caused by can not find symbol. GCC will first go through from the left and will try to put the library file at the end.

error Compile shared libraries with -fPIC

While I run snmpd daemon on powerpc board(a.p.) I am getting this error:
R_PPC_REL24: Compile shared libraries with -fPIC!
/usr/local/sbin/snmpd: symbol 'strlen': can't handle reloc type 0xa in lib
/lib/libnetsnmpmibs.so.15'
sh: you need to specify whom to kill
I googled and found that the -fPIC flag should be there while compiling and its place should be right after gcc, so I changed my Makefie accordingly. Here is a snippet of my makefile:
$(Q)cd $(PROJECT_BUILD_DIR)/$(NET_SNMP_PKG) && ./configure --target=$(TARGET_TRIPLET) \
--host=$(HOST_TRIPLET) \
--build=$(BUILD_TRIPLET) \
--with-cc="$(CR_COMPLR)gcc -fPIC" \`
--with-cflags="-Os -I$(RFS)/lib -I$(NMS_DIR)/include" \`
--with-linkcc="$(CR_COMPLR)gcc -fPIC" \`
As you can see I embedded -fPIC right after gcc, but I am still getting an error. I have cross compiled for powerpc platform and I am using latest buildroot-2011.11 and gcc 4.3.6 and uClibc version 0.9.32. What may be the cause of error?
P.S. When I do nm libnetsnmpmibs.so.15 | grep strlen then I get output as U strlen. Does this mean it is undefined?
I got the problem. actually the main thing is to compile with -fPIC only.
In my case I was compiling snmp libraries with -fPIC correctly but some of the functions were dependent on libraries of other packages (nms). As I am working on firmware development there are more than 20 packages involved. So I compiled nms libraries with -fPIC and error is resolved.

Resources