我目前正在开发我的NASM x64版本的GLIBC,我在测试它时遇到了问题。ASM代码首先在.中编译,接下来我的测试代码(C语言)通过GCC编译,然后我通过LD_PRELOAD
加载我的共享库并执行我的二进制文件。
下面是我的putchar()
的ASM实现:
bits 64
STDOUT equ 1
section .text
global putchar
putchar:
push rdi
mov rax, 1
mov rdi, STDOUT
mov rsi, rsp
mov rdx, 1
syscall
pop rdi
ret
下面是测试main:
#include <stddef.h>
extern size_t putchar(const char str);
int main(void)
{
putchar('z');
return (0);
}
下面是Makefile:
CC = nasm
CFLAGS = -f elf64
SRC = $(wildcard src/*.asm)
OBJ = $(SRC:.asm=.o)
NAME = minilibc.so
all: $(NAME)
$(NAME): $(OBJ)
ld -fPIC -shared -o $(NAME) $(OBJ) -nostdlib
%.o: %.asm
$(CC) $(CFLAGS) $< -o $@
clean:
rm -f $(OBJ)
fclean: clean
rm -f $(NAME)
re: fclean all
test: re
gcc -o test/test test/main.c -g3
LD_PRELOAD=./minilibc.so ./test/test
.PHONY: all clean fclean re
问题是,当我尝试设置断点时,GDB继续使用glibc函数:
(gdb) b putchar
Breakpoint 1 at 0x1030
...
Breakpoint 1, 0x00007ffff7c7bb20 in putchar () from /usr/lib/libc.so.6
我也试过用-nostlib
编译(在make test中),但它不起作用:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001020
...
/home/mimahk/Documents/Workspace C/minilibc/test/main.c:7:(.text+0xa): undefined reference to `putchar'
我知道实际上二进制文件需要一个_start
标签来运行,但是尽管我进行了几次搜索,我还是不能编写它。
我试过了,但它不工作:
asm(".global _start; _start: call main; movq %rax, %rdi; movq $60, %rax;");
我得到:main.c:9:(.text+0x19): undefined reference to putchar
你能告诉我如何测试我的共享库吗?
1条答案
按热度按时间pftdvrlh1#
感谢@PeterCordes和@Jester的评论,我能够纠正这个问题。
首先,我必须修改代码,在
main()
前面加上一个名为_start
的ASM标签。然后我修改了Makefile中的一些选项,以便在运行时直接链接.so(并添加了基本的调试选项):
-g3
:启用GDB的深度调试。-fno-builtin
:GCC的自动代码替换(例如,printf("%s\n", str)
乘puts(str)
。-nostdlib
:不包括GLIBC。-fno-plt
:直接使用GOT而不使用PLT。-L./ -lminilibc
:指示链接器将我的可执行文件链接到minilibc
库(因此应该称为libminilibc.so
)。-Wl,-rpath=./
:告诉链接器我的库在运行时的位置(因为它不在/usr/lib/
中),省去了使用LD_PRELOAD
的麻烦。下面是完整的代码:
main.c
Makefile