GCC: How to completely disable heap usage on the MCU?

I have an application that runs on an ARM Cortex-M MCU and is written in C and C ++. I use gccand g++to compile it and would like to completely disable the use of the heap.

In the MCU start file, the heap size is already set to 0. In addition to this, I would also like to prohibit any accidental use of the heap in the code.

In other words, I would like to see the layout (and / or compiler) gave me an error when the functions malloc, calloc, freeand new, new[], delete, delete[].

So far I have tried -nostdlib, which gives me problems like undefined reference to _start. I also tried -nodefaultlibs, but I'm still not complaining when I try to call malloc. What is the right way to do this?

Notes:

  • This application runs on bare metal, there is no operating system.
  • I would also like to avoid using malloc in third-party code (specialized libraries, standard library, printf, etc.).
  • I completely agree that I do not use parts of the standard C / C ++ libraries that require dynamic memory allocation.
  • I would prefer compile time over runtime.
+4
source share
2 answers

, , --wrap ld ( gcc -Wl).

, --wrap ld "" ; , --wrap=malloc, ld __wrap_malloc, `malloc.

, --wrap=malloc __wrap_malloc, , , - malloc, .

$ cat test-nomalloc.c 
#include <stdlib.h>

int main() {
#ifdef USE_MALLOC
    malloc(10);
#endif
    return 0;
}
$ gcc test-nomalloc.c -Wl,--wrap=malloc
$ gcc test-nomalloc.c -DUSE_MALLOC -Wl,--wrap=malloc
/tmp/ccIEUu9v.o: In function `main':
test-nomalloc.c:(.text+0xa): undefined reference to `__wrap_malloc'
collect2: error: ld returned 1 exit status

new _Znwm (operator new(unsigned long)) _Znam (operator new[](unsigned long)), , new.

+3

( , )

LD_PRELOAD, :

/* remove the LD_PRELOAD from the environment so it
   doesn't kill any child process the app may spawn */
static void lib_init(void) __attribute__((constructor));
static void lib_init( void )
{
    unsetenv( "LD_PRELOAD" );
}

void *malloc( size_t bytes )
{
    kill( getpid(), SIGSEGV );
    return( NULL );
}

void *calloc( size_t n, size_t bytes )
{
    kill( getpid(), SIGSEGV );
    return( NULL );
}

void *realloc( void *ptr, size_t bytes )
{
    kill( getpid(), SIGSEGV );
    return( NULL );
}

void *valloc( size_t bytes )
{
    kill( getpid(), SIGSEGV );
    return( NULL );
}

void *memalign( size_t alignment, size_t bytes )
{
    kill( getpid(), SIGSEGV );
    return( NULL );
}

int posix_memalign( void **ptr, size_t alignment, size_t bytes )
{
    *ptr = NULL;
    kill( getpid(), SIGSEGV );
    return( -1 );
}

, new malloc(), delete free(), , , .

, :

gcc [-m32|-m64] -shared heapdetect.c -o heapdetect.so

:

LD_PRELOAD=/path/to/heapdetect.so /your/app/here args ...
-1

Source: https://habr.com/ru/post/1658200/


All Articles