meta données pour cette page
  •  

How to solve __sync_add_and_fetch_4

I was hit by this problem on september 23rd 2012 :

g++ -DU_CHARSET_IS_UTF8=1 -O3 -W -Wall -ansi -pedantic -Wpointer-arith \
-Wwrite-strings -Wno-long-long   -o ../../bin/makeconv makeconv.o \
ucnvstat.o genmbcs.o gencnvex.o -L../../lib -licutu -L../../lib \
-licui18n -L../../lib -licuuc -L../../stubdata -licudata -lpthread \
-ldl -lm
../../lib/libicuuc.so: undefined reference to `__sync_val_compare_and_swap_4'
../../lib/libicuuc.so: undefined reference to `__sync_add_and_fetch_4'
../../lib/libicuuc.so: undefined reference to `__sync_sub_and_fetch_4'
collect2: ld returned 1 exit status

The solution I found was here, dated april 15th 2012. It appears that I try to compile a recent piece of software with a compiler that is too old. modern gcc have the __sync_val_compare_and_swap_4 functions. Olders don't. The solution, when updating gcc is not an option, is to download a recent compiler, dig the source for the missing functions, just compile the needed files and link your software with this file.

Since this problem happened on my nslu2, an ARM machine, here is what I did to compile the missing functions.

  • from gnu site, download gcc-core-4.6.3.tar.gz
  • extract just the needed directory gcc-4.6.3/gcc/config/arm/
  • remove the HIDDEN directives from gcc-4.6.3/gcc/config/arm/linux-atomic.c file, otherwise, the compiled file is useless.
  • build linux-atomic.o and liblinux-atomic.a using libtool
  • add either the .o file or the .a library to any prog that complains about __sync_add_and_fetch_4 and the like.

I used the linux-atomic.o file to compile ICU4C 49.1.2 on my nslu2. See compilation et installation de ICU4C 49.1.2 for the details.

Here is exactly what I did to build the .o and .a file

schpluntz:linux_atomic (0) $ sudo opkg install libtool
schpluntz:linux_atomic (0) $ tar xf gcc-core-4.6.3.tar.gz gcc-4.6.3/gcc/config/arm/
schpluntz:linux_atomic (0) $ cd gcc-4.6.3/gcc/config/arm/
schpluntz:arm (0) $ sed -i -e 's/define HIDDEN.*/define HIDDEN/' linux-atomic.c
schpluntz:arm (0) $ libtool --tag=CC --mode=compile gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.c
mkdir .libs
 gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c linux-atomic.c  -fPIC -DPIC -o .libs/linux-atomic.o
 gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c linux-atomic.c -o linux-atomic.o >/dev/null 2>&1
schpluntz:arm (0) $ libtool --tag=CC --mode=link gcc -g -O2 -o liblinux-atomic.la linux-atomic.lo
armeb-linux-gnueabi-ar cru .libs/liblinux-atomic.a .libs/linux-atomic.o
armeb-linux-gnueabi-ranlib .libs/liblinux-atomic.a
creating liblinux-atomic.la
(cd .libs && rm -f liblinux-atomic.la && ln -s ../liblinux-atomic.la liblinux-atomic.la)
schpluntz:arm (0) $ sudo cp .libs/linux-atomic.o .libs/liblinux-atomic.a .libs/liblinux-atomic.la /opt/schplurtz/lib/

In the end, here are the symbols in the files :

schpluntz:~ (0) $ nm  /opt/schplurtz/lib/liblinux-atomic.a
linux-atomic.o:
00000b84 T __sync_add_and_fetch_1
00000880 T __sync_add_and_fetch_2
000006fc T __sync_add_and_fetch_4
00000cec T __sync_and_and_fetch_1
00000a00 T __sync_and_and_fetch_2
000007bc T __sync_and_and_fetch_4
000010cc T __sync_bool_compare_and_swap_1
00001170 T __sync_bool_compare_and_swap_2
00000e58 T __sync_bool_compare_and_swap_4
00000458 T __sync_fetch_and_add_1
00000184 T __sync_fetch_and_add_2
00000000 T __sync_fetch_and_add_4
000005a8 T __sync_fetch_and_and_1
000002ec T __sync_fetch_and_and_2
000000c0 T __sync_fetch_and_and_4
00000688 T __sync_fetch_and_nand_1
000003dc T __sync_fetch_and_nand_2
00000140 T __sync_fetch_and_nand_4
00000538 T __sync_fetch_and_or_1
00000274 T __sync_fetch_and_or_2
00000080 T __sync_fetch_and_or_4
000004c8 T __sync_fetch_and_sub_1
000001fc T __sync_fetch_and_sub_2
00000040 T __sync_fetch_and_sub_4
00000618 T __sync_fetch_and_xor_1
00000364 T __sync_fetch_and_xor_2
00000100 T __sync_fetch_and_xor_4
00001028 T __sync_lock_release_1
00001000 T __sync_lock_release_2
00000fd8 T __sync_lock_release_4
00000f6c T __sync_lock_test_and_set_1
00000ef8 T __sync_lock_test_and_set_2
00000eb8 T __sync_lock_test_and_set_4
00000ddc T __sync_nand_and_fetch_1
00000b00 T __sync_nand_and_fetch_2
0000083c T __sync_nand_and_fetch_4
00000c74 T __sync_or_and_fetch_1
00000980 T __sync_or_and_fetch_2
0000077c T __sync_or_and_fetch_4
00000bfc T __sync_sub_and_fetch_1
00000900 T __sync_sub_and_fetch_2
0000073c T __sync_sub_and_fetch_4
00000e94 T __sync_synchronize
00001050 T __sync_val_compare_and_swap_1
000010ec T __sync_val_compare_and_swap_2
00001190 T __sync_val_compare_and_swap_4
00000d64 T __sync_xor_and_fetch_1
00000a80 T __sync_xor_and_fetch_2
000007fc T __sync_xor_and_fetch_4

schplurtz le déboulonné 2012/09/23 22:54