I am seeking the implementation details of malloc() and free() in the arm-none-eabi-gcc source code. I have observed that malloc()/free() functions work on STM32 without an operating system and any additional implementation.
So that I want to understand how malloc works in arm-none-eabi-gcc on bare-metal systems. How is it implemented at the low level in the source code?
As far as my understanding goes, using malloc typically requires the implementation of functions like _sbrk_r or _malloc_r. However, in my case, it seems to work without explicitly implementing these functions.
I have examined several .c files such as malloc.c, mallocr.c, nano-mallocr.c, which I assume might be related to the malloc implementation in the gcc source directory. However, I haven't been able to confirm whether these functions in the files are indeed called by malloc() to implement allocating function.
GCC does not implement malloc. This is part of the C standard library.
The usual C library used on bare metal ARM microcontrollers is newlib.
You are correct that malloc depends on _sbrk_r, which in turn is a thread safe version of sbrk or _sbrk.
The typical brk/sbrk implementation usually keeps a single word of state, which is a pointer to the end of the heap. Every time you ask for more heap it increments this pointer and returns its previous value.
The initial value for the end of the heap is set using a symbol which is defined in the linker script. Traditionally this is called _end or end.
So maybe all you need to have malloc working is a liker script that defines _end. The ones in STM32Cube do this.
Sometimes there is also a symbol for the point beyond which the heap must not grow, and the brk implementation may check for that too. You would have to look at the source for your C library to see if this is the case for you.
If this is not done then malloc will always return ever-increasing pointers, but eventually they will point beyond the end of memory and things will stop working as you expect.
Traditionally on some embedded systems the heap grows upwards into the same memory block into which the stack is growing downwards from the other end. In this case allocating too much memory with malloc will overrun the stack, and you can compare the returned pointers to the stack pointer to see how close you are to this happening.