riscv-collab / riscv-gnu-toolchain

GNU toolchain for RISC-V, including GCC
Other
3.42k stars 1.13k forks source link

undefined reference to malloc and memcpy error #1017

Closed Mousavikia closed 1 year ago

Mousavikia commented 2 years ago

Hi and sorry it will be long question... I have installed Vector version of RiscV gnu toolchain with following setups:

git clone https://github.com/riscv/riscv-gnu-toolchain -b rvv-intrinsic
cd riscv-gnu-toolchain
git submodule update --init --recursive
mkdir build && cd build
../configure --prefix=/desired/installation/path
make

And here is my makefile and linker file:

# Copyright TU Wien
# Licensed under the ISC license, see LICENSE.txt for details
# SPDX-License-Identifier: ISC

# Generic Makefile for RV32IMV applications
# Specify program name with PROG, object files with OBJ

SW_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

RISCV_CC   := riscv32-unknown-elf-gcc
RISCV_DUMP := riscv32-unknown-elf-objdump
RISCV_OBCP := riscv32-unknown-elf-objcopy

LD_SCRIPT := $(SW_DIR)/link.ld

RISCV_FLAGS := -march=rv32imv -mabi=ilp32 -static -mcmodel=medany             \
               -fvisibility=hidden -nostdlib -nostartfiles -Wall

CFLAGS := $(CFLAGS) -I$(SW_DIR)/lib/

PROG ?= test
OBJ  ?= test.o

# add crt0 to object files
RISCV_OBJ := $(SW_DIR)/crt0.o $(OBJ) $(SW_DIR)/lib/uart.o

all: $(PROG).vmem

dump: $(PROG).elf
    $(RISCV_DUMP) -D $<

$(PROG).elf: $(RISCV_OBJ) $(LD_SCRIPT)
    $(RISCV_CC) $(RISCV_FLAGS) -T $(LD_SCRIPT) $(LDFLAGS) $(RISCV_OBJ) -o $@

%.o: %.c
    $(RISCV_CC) $(RISCV_FLAGS) $(CFLAGS) -c -o $@ $<

%.o: %.S
    $(RISCV_CC) $(RISCV_FLAGS) $(ASFLAGS) -c -o $@ $<

# currently unusable due to problems with byte order
# (see https://github.com/riscv/riscv-tools/issues/168#issuecomment-554973539)
#%.vmem: %.elf
#   $(OBJCOPY) -O verilog --verilog-data-width 4 $^ $@

# workaround (requires srecord):
# note: start address must be reset manually because it is lost in bin file
%.vmem: %.bin
    srec_cat $^ -binary -offset 0x0000 -byte-swap 4 -o $@ -vmem
%.bin: %.elf
    $(RISCV_OBCP) -O binary $^ $@

clean:
    rm -f *.o *.elf *.bin *.vmem
/* Copyright TU Wien                                                          */
/* Licensed under the ISC license, see LICENSE.txt for details                */
/* SPDX-License-Identifier: ISC                                               */

OUTPUT_ARCH(riscv)
ENTRY(_start)

SEARCH_DIR(.)
__DYNAMIC = 0;

MEMORY
{
    boot : ORIGIN = 0x00000000, LENGTH = 0x00002000 /*   8 kB */
    ram  : ORIGIN = 0x00002000, LENGTH = 0x0003E000 /* 248 kB */
}

STACK_LEN = 0x4000; /* 16 kB */

SECTIONS
{
    .vectors 0 : {
        *(.vectors)
    } >boot

    .text : {
        . = ALIGN(4);
        _stext = .;
        *(.text)
        *(.text.*)
        _etext  =  .;
        __CTOR_LIST__ = .;
        LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
        *(.ctors)
        LONG(0)
        __CTOR_END__ = .;
        __DTOR_LIST__ = .;
        LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
        *(.dtors)
        LONG(0)
        __DTOR_END__ = .;
        *(.lit)
        *(.shdata)
        . = ALIGN(4);
        _endtext = .;
    } >ram

    .rodata : {
        . = ALIGN(4);
        *(.rodata);
        *(.rodata.*)
    } >ram

    .shbss : {
        . = ALIGN(4);
        *(.shbss)
    } >ram

    .data : {
        . = ALIGN(4);
        sdata = .;
        _sdata = .;
        *(.data);
        *(.data.*)
        edata = .;
        _edata = .;
    } >ram

    .bss (NOLOAD) : {
        . = ALIGN(4);
        _bss_start = .;
        *(.bss)
        *(.bss.*)
        *(.sbss)
        *(.sbss.*)
        *(COMMON)
        _bss_end = .;
    } >ram

    .user_align (NOLOAD) : {
        . = ALIGN(0x1000);
        _user_start = .;
    } >ram

    .stack ORIGIN(ram) + LENGTH(ram) - STACK_LEN (NOLOAD) : {
        . = ALIGN(16);
        _stack_start = .;
        . = . + STACK_LEN;
        . = ALIGN(16);
        stack = .;
        _stack = .;
        _stack_end = .;
    } >ram

    .stab 0 (NOLOAD) : {
        [ .stab ]
    }

    .stabstr 0 (NOLOAD) : {
        [ .stabstr ]
    }
}

I have compiled a simple code with this setups and first after running make I got following error: memcpy I searched the internet and I found two pices of code that could handle this error: one is this:

void *memcpy(void *dest, const void *src, size_t n)

{

    for (size_t i = 0; i < n; i++)

    {

        ((char*)dest)[i] = ((char*)src)[i];

    }

}

And second one:

void * memcpy ( void * destination, const void * source, int num ){
  int i=0;
  *((int*)destination) = *((int*)source);
}

both of them cleared the error but first one with correct output and second one with different (wrong) output... How can I handle this problem? I even added -lc and -lgcc in linker:

/* Copyright TU Wien                                                          */
/* Licensed under the ISC license, see LICENSE.txt for details                */
/* SPDX-License-Identifier: ISC                                               */

OUTPUT_ARCH(riscv)
GROUP( -lc -lgcc )
ENTRY(_start)

SEARCH_DIR(.)
__DYNAMIC = 0;

MEMORY
{
    boot : ORIGIN = 0x00000000, LENGTH = 0x00002000 /*   8 kB */
    ram  : ORIGIN = 0x00002000, LENGTH = 0x0003E000 /* 248 kB */
}

but I get this error now: soft

Sorry it is very long but I am really confused right now...

Mousavikia commented 2 years ago

And my second question is following: I have changed the simple code and added some malloc and free functions but even after adding

void *memcpy(void *dest, const void *src, size_t n)

{

    for (size_t i = 0; i < n; i++)

    {

        ((char*)dest)[i] = ((char*)src)[i];

    }

}

which was the corrrect form of memcpy for my code at least I got this errors: undefined reference to malloc or undefined reference to free I added version of sbrk for baremetal systems and .end at the end of .bss section of my linker but the errors are still there:

/* Version of sbrk for no operating system.  */
void*
_sbrk(incr)
int incr;
{
    extern char   end; /* Set by linker.  */
    static char* heap_end;
    char* prev_heap_end;

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

    prev_heap_end = heap_end;
    heap_end += incr;

    return (void*)prev_heap_end;
}
TommyMurphyTM1234 commented 2 years ago

Your link command is using -nostdlib so no standard C library is being linked so no implementation of memcpy() and other standard library functions is available. You should look at the GCC documentation about this option.

https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/Link-Options.html#Link-Options

TommyMurphyTM1234 commented 1 year ago

Not a RISC-V GCC toolchain issue.