如何用用户定义的一个覆盖_sbrk这样的C库函数?

时间:2020-06-13 21:44:21

标签: c++ c riscv newlib

我想使用newlib提供的RISCV上的C和C ++中的STL函数。为了使用这些功能,我必须替换_sbrk_read_write和其他一些功能的默认实现。默认情况下,newlib提供这些功能,并且它们通过RISCV的syscalls指令使用ecall。但是,我不想实现ecall指令,而是为其提供新功能。

问题是我不知道如何替换C和C ++中的函数。所以我的问题基本上是,如何覆盖C / C ++中的函数?特别是_sbrk和其他syscall函数。

2 个答案:

答案 0 :(得分:0)

注意:由于我没有针对RiscV的交叉编译器,因此本示例使用malloc()而不是_sbrk()。原理是一样的。

  1. 自己实现这些功能。

    #include <stdlib.h>
    
    void* malloc(size_t size) {
        (void)size;
        return NULL;
    }
    
  2. 然后将该模块链接到您的其他模块,这些功能将不会从库中获取。

    假设我们有一个简单的程序:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        printf("%p\n", malloc(23));
        return 0;
    }
    

    这是我编译和链接的方式:

    gcc -Wall -Wextra -pedantic -g -c main.c -o main.o
    gcc -Wall -Wextra -pedantic -g -c malloc.c -o malloc.o
    gcc -Wall -Wextra main.o malloc.o -g -Wl,-Map=my_own.map -o my_own
    

生成的地图文件并非无关紧要,但这是相关的几行:

[--- lines cut ---]

 .plt           0x0000000000001020       0x20 /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../lib/Scrt1.o
                0x0000000000001030                printf@@GLIBC_2.2.5
 *(.iplt)

[--- lines cut ---]

 .text          0x0000000000001040       0x2f /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../lib/Scrt1.o
                0x0000000000001040                _start
 .text          0x000000000000106f        0x0 /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../lib/crti.o
 *fill*         0x000000000000106f        0x1 
 .text          0x0000000000001070       0xc9 /usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/crtbeginS.o
 .text          0x0000000000001139       0x29 main.o
                0x0000000000001139                main
 .text          0x0000000000001162        0xf malloc.o
                0x0000000000001162                malloc

[--- lines cut ---]

如图所示,printf()是从库中获取的,但使用了我自己的malloc()

答案 1 :(得分:0)

这是您需要的: https://github.com/openhwgroup/cv32e40p/blob/master/example_tb/core/custom/syscalls.c 所有必需的系统调用都在那里,使用此存根函数,malloc()即可完全正常工作...假设UART为0x10000000(使用qemu-system-riscv32 -machine virt测试),诸如printf()之类的其他东西也能正常工作

相关问题