我想构建一个静态的ELF程序,而不使用(g)libc,而是使用Linux头文件提供的unistd.h。
我已经阅读了这些文章/问题,大致了解了我正在尝试做什么,但还不够清楚:
http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free
我有基本的代码,只依赖于unistd.h,我的理解是每个函数都由内核提供,并且不需要libc。以下是我采取的似乎最有前途的路径:
$ gcc -I /usr/include/asm/ -nostdlib grabbytes.c -o grabbytesstatic
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400144
/tmp/ccn1mSkn.o: In function `main':
grabbytes.c:(.text+0x38): undefined reference to `open'
grabbytes.c:(.text+0x64): undefined reference to `lseek'
grabbytes.c:(.text+0x8f): undefined reference to `lseek'
grabbytes.c:(.text+0xaa): undefined reference to `read'
grabbytes.c:(.text+0xc5): undefined reference to `write'
grabbytes.c:(.text+0xe0): undefined reference to `read'
collect2: error: ld returned 1 exit status
在此之前,我必须根据内核头文件中找到的值手动定义SEEK_END和SEEK_SET。否则,它会报错,指出这些未被定义,这是有道理的。
我想我需要链接到未剥离的vmlinux以提供符号以供使用。但是,我已经阅读了符号,尽管有很多llseek,但它们并不完全匹配llseek。
因此,我的问题可以分为几个方向:
如何指定要使用符号的ELF文件?如果/如何可能,我猜符号将无法匹配。如果正确,是否存在现有的头文件,该文件将重新定义llseek和default_llseek或与内核中实际情况完全相同的内容?
是否有更好的方法在C中编写没有libc的Posix代码?
我的目标是编写或移植相当标准的C代码,只使用(也许仅限于)unistd.h,并在没有libc的情况下调用它。我可能不需要一些unistd函数,而且不确定哪些函数“纯粹”作为内核调用存在。我喜欢汇编语言,但这不是我的目标。希望尽可能严格地保持C(如果必须,我可以使用一些外部汇编文件),以便在某个时候实现一个没有libc的静态系统。
谢谢您的阅读!