-1

I'm trying to cross-compile a program that uses gcc builtins, specific __sync_val_compare_and_swap, __sync_add_and_fetch and sync_sub_and_fetch. Compiling works, but the linker is showing me the undefined reference errors. For example:

memory_layout.c:(.text.memory_uniqueid+0x1c): undefined reference to '__sync_val_compare_and_swap_4'
memory_layout.c:(.text.ipc_counter+0x18): undefined reference to '__sync_add_and_fetch_4'

I'm using the st-gnu-arm-gcc-7-2018-q2-update_gdb-5_4-2016q3 toolchain that comes with eclipse and SW4STM32. My host machine is a 64-Bit Linux Mint. The program is build with CMake.

The needed functions are defined in the toolchain file lib/gcc/arm-none-eabi/7.3.1/plugin/include/sync-builtins.def.

I've searched for similar errors but the provided solution (use -march=i486) but this didn't help. Another workaround I found is to compile the needed functions in an own library (http://vincesoft.blogspot.com/2012/04/how-to-solve-undefined-reference-to.html) but this seems to be for older gcc versions.

I also tried to manually link libgcc (that comes with the toolchain) but without success. The used commands are

add_library(GCC_LIB STATIC IMPORTED /home/toolchains/st-gnu-arm-gcc-7-2018-q2-update_gdb-5_4-2016q3/lib/gcc/arm-none-eabi/7.3.1/libgcc.a)
target_link_libraries(${PROJECT_NAME} ${GCC_LIB})

the error is caused in the following function

static inline unsigned int atomic_inc(unsigned int v)
{
    /* atomic load, modify, store */
    return __sync_add_and_fetch(v, 1);
}

Do I need to provide some special compiler flags or defines so the builtin functions can be linked?

F.Cz
  • 37
  • 3
  • 1
    Just define them. The compiler doesn't come with them implemented, you have to provide them yourself. No, [sync-builtins.def](https://github.com/gcc-mirror/gcc/blob/master/gcc/sync-builtins.def) is just a stub file to be used with `DEF_SYNC_BUILTIN`. You have to write `DEF_SYNC_BUILTIN` for your archicture yourself. Or just write the `__sync_add_and_fetch_4` for your architecture yourself. For what target are you compiling? – KamilCuk Oct 15 '19 at 11:19
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – S.S. Anne Oct 15 '19 at 11:23
  • It could look something like `unsigned __sync_add_and_fetch_4(unsigned *v, unsigned add, ...) { disable_interrupts(); const unsigned ret = *v; *v += add; enable_interrupts(); return ret; }` – KamilCuk Oct 15 '19 at 11:27
  • @KamilCuk I'm compiling for arm cortex m7 (STM32 F7). I will try to implement the needed functions. Thanks – F.Cz Oct 15 '19 at 11:34

1 Answers1

0

As @KamiCuk pointed out I had to implement the needed functions by myself. The disable_intterrups() and enable_interrupts() function in his comment are os dependent. As I was compiling for Freertos I used portENTER_CRITICAL and portEXIT_CRITICAL. The finale solution for __sync_add_and_fetch_4 looked like this:

__sync_add_and_fetch_4(unsigned *v, unsigned add, ...) { 
portENTER_CRITICAL(); 
const unsigned ret = *v;
*v += add; 
portEXIT_CRITICAL(); 
return ret; }

Some of the atomic operations are already provided by FreeRTOS headers (atomic.h).

F.Cz
  • 37
  • 3