[英]How to override C lib functions like _sbrk with user-defined one?
我想在由newlib
提供的 RISCV 上的 C 和 C++ 中使用 STL 函数。 为了使用这些,我必须替换_sbrk
、 _read
、 _write
和其他一些函数的默认实现。 默认情况下, newlib
提供这些函数,它们使用syscalls
的ecall
指令使用系统调用。 但是,我不想实现ecall
指令,而是为它们提供新功能。
问题是我不知道如何替换 C 和 C++ 中的 function。 所以我的问题基本上是,如何在 C/C++ 中覆盖 function? 特别是_sbrk
和其他syscall
函数。
注意:因为我没有 RiscV 的交叉编译器,所以这个例子使用malloc()
而不是_sbrk()
。 原理是一样的。
自己实现这些功能。
#include <stdlib.h> void* malloc(size_t size) { (void)size; return NULL; }
然后将该模块链接到您的其他模块,这些功能将不会从库中获取。
假设我们有这个简单的程序:
#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
生成的 map 文件并不简单,但是,这些是相关行:
[--- 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()
。
这就是您所需要的: https://github.com/openhwgroup/cv32e40p/blob/master/example_tb/core/custom/syscalls.c所有必需的系统调用都在那里,malloc() 使用此tub 函数功能齐全...假设 UART 位于 0x10000000(使用 qemu-system-riscv32 -machine virt 测试),其他类似 printf() 的东西也可以工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.