e2studio GCC tools, malloc not returning NULL when all memory is already allocated

I'm using e2studio with RX 4.8.4.201803-GNURX tools, on an RX71 with 512KB of RAM memory. The map file of the project shows correctly RAM ending at 0x80000 as shown below:

Memory Configuration

Name Origin Length Attributes
RAM 0x00000000 0x00080000
ROM 0xffc00000 0x00400000
OFS 0x00120000 0x00000100
*default* 0x00000000 0xffffffff

The linker script also has the correct ram at 0 with a size of 524288 (0x80000) bytes.

MEMORY
{
RAM : ORIGIN = 0x0, LENGTH = 524288
ROM : ORIGIN = 0xFFC00000, LENGTH = 4194304
OFS : ORIGIN = 0x120000, LENGTH = 256
}

Using malloc test code of:

struct kilo{ //test 128byte structures to allocate
    struct kilo *next;
    char dummy[124];
};

...

current = (struct kilo *) malloc(sizeof(struct kilo));
counter = 0;

do { //allocate ALL the available memory 128 bytes at a time
    counter++;
    current->next = (struct kilo *)malloc(sizeof(struct kilo));
    current = current->next;

    if(current > 0x7ff80) printf("WTF? %x\n",current);
} while (current);

A NULL value should be returned for allocation requests above 0x7ff80 and the do loop should exit without triggering the printf line. However the above test prints "WTF 7ffac". There is not enough remaining RAM above 0x7ffac to store the next 128byte structure. The next loop itteration does fail. 

My question is why doesn't malloc know that it is out of memory? What configuration setting tells malloc where RAM memory ends?

Any help would be appreciated. thank you in advance!

Regards

Dan

 

Parents
  • Hallo Dan.

    if you are building with newsyslib - check your override of _sbrk. Ours looks something like this:

    caddr_t __attribute__((weak)) sbrk(int incr)
    {
    extern char end; /* Defined by the linker */
    static char *heap_end;
    char *prev_heap_end;

    if (heap_end == 0)
    heap_end = &end;

    prev_heap_end = heap_end;
    if (heap_end + incr > (const char*)SDRAM_START + SDRAM_LENGTH) {
    return (caddr_t) -1;
    }

    heap_end += incr;

    return (caddr_t) prev_heap_end;
    }

    Good luck.
  • Hi Starzhuk,

    Thank you for your reply.

    I’m using optlib, but I frankly don’t know how would I find the similar code you reference for “override of _sbrk”? or how to modify it. It looks like this code is assigning a new heap_end with a limit which is exactly what I need.

    Regards
    Dan
  • Hi,

    The code returns -1 in case no more heap memory is available. heap_end is a localy visible variable - nobody knows about it outside of sbrk(). It is just used to maintain the heap allocations.

    For optlib stuff look into ...\GCC for Renesas ...\rx-elf\rx-elf\rx-elf\optlibinc\internal\heap.h - for old projects with optlib we wrap the _top_of_the_heap as following:

    +/*
    + returns end of heap memory
    + wrapper for original (<..\optlibinc\internal\heap.h>)
    + char* _top_of_heap(void);
    +
    + add "--wrap=_top_of_heap" option to linker in order to use it.
    +*/
    +char*
    +__wrap__top_of_heap(void)
    +{
    + return (char*)(SDRAM_START + SDRAM_LENGTH);
    +}

    Good luck.
  • Thank you siarZhuk. I added the code and linker option as you suggested and the program does not compile. I wonder what I have done wrong; it does not recognize the --wrap command. Here is the new linker command line:

    -T "C:\\Workspace VnetX1\\VnetX_Slave_USB/generate/linker_script.ld" -L"C:\\Workspace VnetX1\\VnetX_Slave_USB\\HardwareDebug" -Wl,-M=VnetX_Slave_USB.map -Wl,--start-group -lVnetX_Slave_USB -lgcc -lstdc++ -Wl,--end-group -nostartfiles --wrap=_top_of_heap

    Here is the wrapper function:

    char* __wrap__top_of_heap(void)
    {
    return (char *) 0x80000;
    }

    Here is the compile error it generated:

    rx-elf-g++: error: unrecognized command line option '--wrap=_top_of_heap'
    makefile:138: recipe for target 'VnetX_Slave_USB.elf' failed
    make: *** [VnetX_Slave_USB.elf] Error 1

    Not having the best luck so far but I appreciate your input.

    Regards
    Dan
  • you are sending --wrap to compiler but not linker. Try to prepend the option with -Wl,

    -Wl,--wrap=_top_of_heap
  • Hi siarzhuk,

    That suggestion does not work either. The linker command line is now:

    -T "C:\\Workspace VnetX1\\VnetX_Slave_USB/generate/linker_script.ld" -L"C:\\Workspace VnetX1\\VnetX_Slave_USB\\HardwareDebug" -Wl,-M=VnetX_Slave_USB.map -Wl,--start-group -lVnetX_Slave_USB -lgcc -lstdc++ -Wl,--end-group -nostartfiles -WI,--wrap=_top_of_heap

    I still get an error of:

    rx-elf-g++: error: unrecognized command line option '-WI,--wrap=_top_of_heap'

    Is it possible rx-elf-g++ does not support the --wrap command or it has a different format? I had a look at the GNU linker manual and the syntax for the ld linker appears to be as you suggest, but the g++ man page does not refer to a --wrap option at all.

    Thanks again for your help so far.
Reply
  • Hi siarzhuk,

    That suggestion does not work either. The linker command line is now:

    -T "C:\\Workspace VnetX1\\VnetX_Slave_USB/generate/linker_script.ld" -L"C:\\Workspace VnetX1\\VnetX_Slave_USB\\HardwareDebug" -Wl,-M=VnetX_Slave_USB.map -Wl,--start-group -lVnetX_Slave_USB -lgcc -lstdc++ -Wl,--end-group -nostartfiles -WI,--wrap=_top_of_heap

    I still get an error of:

    rx-elf-g++: error: unrecognized command line option '-WI,--wrap=_top_of_heap'

    Is it possible rx-elf-g++ does not support the --wrap command or it has a different format? I had a look at the GNU linker manual and the syntax for the ld linker appears to be as you suggest, but the g++ man page does not refer to a --wrap option at all.

    Thanks again for your help so far.
Children