Linker issues when building with gcc

I am attempting to port a project that was originally building in IAR over to GCC. I am using CMake to run the build with the ARM GCC tools in WSL.

Processor: STM32F756 on custom hardware

Thus far, I can successfully compile all of my relevant files, but now I’m stuck with a linker problem. The issue seems to be related to standard library function wrappers. Specifically, the linker errors I get are;

mbed-os/platform/source/mbed_alloc_wrappers.cpp: In function malloc_wrapper': mbed-os/platform/source/mbed_alloc_wrappers.cpp:108: undefined reference to __real__malloc_r’

and

/mbed-os/platform/source/mbed_alloc_wrappers.cpp: In function free_wrapper': mbed-os/platform/source/mbed_alloc_wrappers.cpp:199: undefined reference to __real__free_r’

I also have a multiple definition of _exit, stemming from
/mbed-os/platform/source/mbed_retarget.cpp and newlib/nosys/_exit.c

Now, at face value the problem makes sense to me; mbed_alloc_wrappers.cpp has defined __real__xxx as an external C linkage but obviously the linker is not able to locate the object code for those functions. My understanding was that this is provided by newlib. I have tried passing different spec options to the linker, as outlined in this document :

https://www.st.com/content/ccc/resource/technical/document/user_manual/group1/cd/29/43/c5/36/c0/40/bb/Newlib_nano_readme/files/newlib-nano_readme.pdf/jcr:content/translations/en.newlib-nano_readme.pdf

I’m a bit out of my depth at this point. I don’t have any prior experience with getting newlib working, and I don’t fully understand what I need to get all of these wrapper functions linking correctly. Any help would be greatly appreciated.

Hello Brendan,

Although no __real__malloc_r and __real__free_r functions have been defined in the project, the linker should be able to resolve such references after adding --wrap _malloc_r and --wrap _free_r options to the linker command.

Explanation:

--wrap symbol

instructs the linker to use a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol . Any undefined reference to __real_symbol will be resolved to symbol. This can be used to provide a wrapper for a system function. The wrapper function should be called __wrap_symbol . If it wishes to call the system function, it should call __real_symbol .

Have a look at http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html.

Best regards, Zoltan.

Hello Zoltan,

Thank you for the reply. I have seen information on the --wrap option and despite my best efforts, I cannot seem to resolve this linker issue with that option. Here is the current output from my build:

Linker Output
/mbed-os/platform/source/mbed_retarget.cpp.o (symbol from plugin): In function `mbed_heap_start':
(.text+0x0): multiple definition of `_exit'
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libnosys.a(_exit.o):/build/newlib-jo3xW1/newlib-2.4.0.20160527/build/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/libgloss/libnosys/../../../../../../../../libgloss/libnosys/_exit.c:11: first defined here
/tmp/ccjgEZxx.ltrans27.ltrans.o: In function `_exit':
/mbed-os/platform/source/mbed_retarget.cpp:1345: multiple definition of `_exit'
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libnosys.a(_exit.o):/build/newlib-jo3xW1/newlib-2.4.0.20160527/build/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/libgloss/libnosys/../../../../../../../../libgloss/libnosys/_exit.c:11: first defined here
/tmp/ccjgEZxx.ltrans12.ltrans.o: In function `free_wrapper':
/mbed-os/platform/source/mbed_alloc_wrappers.cpp:201: undefined reference to `__real__free_r'
/tmp/ccjgEZxx.ltrans12.ltrans.o: In function `malloc_wrapper':
/mbed-os/platform/source/mbed_alloc_wrappers.cpp:108: undefined reference to `__real__malloc_r'
collect2: error: ld returned 1 exit status

As you can see, I actually have an additional type of error in that _exit is defined in more than one place. I am not sure why that would be the case.

Here are my linker options as defined in my CMakeFiles.txt:

Linker Flags
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS      "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS    "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS} -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r")

I have resolved my issue. Turned out to be a simple mistake in my linker flags as set in CMakeLists.txt.

what was the mistake?