Filip
Filip

Reputation: 111

malloc() returns a pointer to a wrong memory section

I have a simulator of a custom-designed CPU, that has the memory mapped as follows:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16384K  /* KiB */
    RAM (rw)   : ORIGIN = 0x20000000, LENGTH = 512K    /* KiB */
}

From what I've tested, everything in the CPU works as expected, apart from malloc() (and similar memory allocation functions). The malloc function will return a pointer to the FLASH memory (i.e. not respecting the RAM origin).

This is the test code:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

extern uint32_t _sidata; /* Start of .data in FLASH */
extern uint32_t _sdata;  /* Start of .data in RAM */
extern uint32_t _edata;  /* End of .data in RAM */

extern uint32_t _sbss;  /* Start of .bss in RAM */
extern uint32_t _ebss;  /* End of .bss in RAM */

void initialize_memory(void) {
    // Copy initialized variables from FLASH to RAM (.data section)
    uint32_t *src = &_sidata;
    uint32_t *dest = &_sdata;

    while (dest < &_edata) {
        *dest++ = *src++;
    }

    // Zero-initialize the .bss section in RAM
    dest = &_sbss;

    while (dest < &_ebss) {
        *dest++ = 0;
    }
}


int main(void){

    initialize_memory();

    int *ptr1 = (int*)malloc(4*sizeof(int));

    __asm__("nop");               // just for locating this line in assembly
    __asm__("lui t0, 0x80000");   // Destination address
    __asm__("mv t1, a5");         
    __asm__("sw t1, 0(t0)");      // Storing the returned value
    __asm__("nop");
}

The __asm__ part is used for my evaluation - I can see the output of 0x80000000 and it is 8. The malloc is returning a number 8. -> that is not correct, at least it should be 0x20000008 to point into RAM.

This is the risc-v assembly part (.lss) from where I found out the register I wanted to inspect (a5 in this case):

000000bc <main>:
  bc:   fe010113            addi    sp,sp,-32
  c0:   00112e23            sw  ra,28(sp)
  c4:   00812c23            sw  s0,24(sp)
  c8:   02010413            addi    s0,sp,32
  cc:   f4dff0ef            jal 18 <initialize_memory>
  d0:   01000513            li  a0,16
  d4:   038000ef            jal 10c <malloc>
  d8:   00050793            mv  a5,a0
  dc:   fef42623            sw  a5,-20(s0)
  e0:   00000013            nop
  e4:   800002b7            lui t0,0x80000
  e8:   00078313            mv  t1,a5
  ec:   0062a023            sw  t1,0(t0) # 80000000 <_estack+0x5ff80004>
  f0:   00000013            nop
  f4:   00000793            li  a5,0
  f8:   00078513            mv  a0,a5
  fc:   01c12083            lw  ra,28(sp)
 100:   01812403            lw  s0,24(sp)
 104:   02010113            addi    sp,sp,32
 108:   00008067            ret

To see if the malloc is actually doing something, I've tested this code. The result of the second malloc is 0x20:

...
    int *ptr1 = (int*)malloc(4*sizeof(int));

    __asm__("nop");
    __asm__("lui t0, 0x80000");
    __asm__("mv t1, a5");
    __asm__("sw t1, 0(t0)"); 
    __asm__("nop");

    int *ptr2 = (int*)malloc(4*sizeof(int));

    __asm__("nop");
    __asm__("lui t0, 0x80000");
    __asm__("mv t1, a5");
    __asm__("sw t1, 0(t0)"); 
    __asm__("nop");
}

Linker script:

  .data : 
  {
    . = ALIGN(4);
    _sdata = .;
    *(.data)
    *(.data*)
    *(.*data*)
    
    . = ALIGN(4);
    _edata = .;
  } >RAM AT> FLASH
  /* } AT> FLASH */
  /* } >FLASH AT>RAM */
 
 _sibss = LOADADDR(.bss);
  

  . = ALIGN(4);
  .bss :
  {
    _sbss = .; 
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;
    __bss_end__ = _ebss;
  /* } >RAM */
  /* } >RAM */
  } >RAM AT> FLASH

  ._user_heap_stack :
  {
        . = ALIGN(8);
    PROVIDE ( __heap_start__ = . );
    . = . + 0x1000;
    PROVIDE ( __heap_end__ = . );
  } >RAM

The question is, why the output of the malloc is not respecting the origin of the RAM, on the other hand - how do I even know if that returned number is correct in the first place - wouldn't it "collide" with the data preloaded from FLASH?

Toolchain used: xpack-riscv-none-elf-gcc-14.2.0-2

Upvotes: 1

Views: 128

Answers (0)

Related Questions