As the tittle suggest, I'm getting an error related to not defining memcpy and memset, even though I'm not directly using it (although I guess it is used for the linker and compiling process given the nature of this error)
long story short: I'm writing the .data and .bss section originally stored in FLASH to the SRAM memory, I'm using pointer for such operation in a fashion like the following:
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
int main(void);
void Reset_Handler(void);
void Default_Handler(void);
#ifdef __cplusplus
}
#endif
extern uint32_t _etext;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
void Reset_Handler(void)
{
//copy .data section to SRAM
uint32_t size = (uint32_t)&_edata - (uint32_t)&_sdata;
uint8_t *pDst = (uint8_t*)&_sdata; //sram
uint8_t *pSrc = (uint8_t*)&_etext; //source point comes from flash memory that is end of flash
for(uint32_t i =0 ; i < size ; i )
{
*pDst = *pSrc ; //"MEMCPY NOT DEFINED" ERROR TRIGGERS HERE
}
//copy .bss section to SRAM
size = (uint32_t)&_ebss - (uint32_t)&_sbss;
pDst = (uint8_t*)&_sbss; //sram
for(uint32_t i =0 ; i < size ; i )
{
*pDst = 0; //"MEMSET NOT DEFINED" ERROR TRIGGERS HERE
}
main();
}
I'm using arm embedded g compiler for building the .o files and then linking into .elf using -nostdlib option given the fact that embedded application is intended, so no stdlib are requiered/affordable .
The process fails since it appears that there is a implicit calling to "memcpy" and "memset" functions. I tried to include <string.h> (which, to my knowledge, is where those two functions are defined) Also, I've made the include inside extern "C" in order to avoid "not defined symbol" due to name mangling.
This is the make file calling and the terminal output for that:
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g -nostdlib -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: stm32_startup.o: in function `Reset_Handler':
/home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:155: undefined reference to `memcpy'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:165: undefined reference to `memset'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
inumaki@dev-Inumaki:~/Development/stm32/Workspace$ make
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g -nostdlib -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: stm32_startup.o: in function `Reset_Handler':
/home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:155: undefined reference to `memcpy'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:165: undefined reference to `memset'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
The only way out of this as I see, would be to define my own implementation of memcpy and memset functions at the same time as removing #include <string.h> to avoid redefinition problems. Although I don't know what memcpy and memset do.
Thanks in advance.
EDIT:
By removing -nostdlib that is, allowing the linker to link the std libraries, I get this errors related also to undefined functions. It seems to me that it is related to assembler startup file even though I have a .cpp startup file.
inumaki@dev-Inumaki:~/Development/stm32/Workspace$ make
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions main.cpp -o main.o
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions GPIO_PORT.cpp -o GPIO_PORT.o
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g -c -mcpu=cortex-m4 -mthumb -std=c 11 -O2 -g -fno-exceptions config.cpp -o config.o
arm-none-eabi-g -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o: in function `_mainCRTStartup':
(.text 0x128): undefined reference to `__bss_start__'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: (.text 0x12c): undefined reference to `__bss_end__'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): in function `exit':
exit.c:(.text.exit 0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
CodePudding user response:
I was able to reproduce your problem by copying your code into the Compiler Explorer. The solution is to add the -ffreestanding
option to GCC when you are compiling that file. There is more info about -ffreestanding
on this site.
Alternatively, you could try removing the -nostdlib
option you are using during linking, allowing GCC to link in its standard libraries, assuming it is configured properly to allow for that. I recommend that you at least try doing that and see how much bloat it adds to your application. It might be fine to do that because GCC should only include the libary functions you actually are calling.
CodePudding user response:
Add -fno-tree-loop-distribute-patterns
to prevent gcc recognising memset
, memcpy
, etc., patterns and generating external function calls for them. That's typically what you want for a freestanding execution environment. Note that -ffreestanding
does not necessarily suppress the generation of these function calls.
Alternatively, you can link with your own memcpy
, memset
implementations as you point out - but that's probably something to consider when you get everything working.