0

来自 musl libc 常见问题解答

问:ldd 在哪里?

musl 的动态链接器带有内置的 ldd 功能。只需创建一个从 ld-musl-$ARCH.so 到 /bin/ldd 的符号链接。如果动态链接器以“ldd”启动,它将检测到并打印适当的 DSO 信息。

检查ld-musl-$ARCH.so我发现它是 musl 的符号链接/usr/local/musl/lib/libc.so

那绝对是一个共享库

$ file /usr/local/musl/lib/libc.so
/usr/local/musl/lib/libc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=068deca2fec0ea2c50ec1e11166d25b3bb057431, not stripped

它确实有效,这太疯狂了,哈哈。我实际上可以这样做:

$ /usr/local/musl/lib/libc.so ./a.out

它会起作用。但是我怎么可能从终端调用共享库呢?

4

1 回答 1

1

好吧,我想我明白了。

所以基本上一个共享库实际上是一个可执行文件。而且因为 musl 是一个 libc 实现,它定义了_start()作为程序真正入口点的函数。然后该_start()函数将调用主函数。

musl 的开发人员这样做是为了如果您调用他们的libc.soasldldd他们会检测到并采取相应的行动。

他们可以检测到,因为_start()确实需要argcand argv(然后将传递给main()),因此他们可以查看argv[0]是“ld”还是“ldd”。

并感谢@that other guy 和 @David C. Rankin 链接这个。那里的答案说您甚至可以拥有一个定义main().

所以我自己尝试了。

这里是_start.c

void
_start()
{
    asm("mov $60,%rax; mov $0,%rdi; syscall");
}

我在带有 gcc 7.4.0 的 x86_64 ubuntu linux 机器上编译它,如下所示:

$ gcc -shared -nostdlib _start.c -o libwow.so

然后我称之为:

$ ./libwow.so
$

它当然没有做任何事情,但它确实运行了。

我们生活在一个疯狂的世界:D

编辑:

在一个更疯狂的音符上。可以使用dlopen(3)将可执行文件作为动态库加载。查看此答案以了解更多信息。

结论:

共享库和可执行文件几乎是一回事(ELF二进制文件)。

除了共享库没有固定的入口点地址,而可执行文件有。

共享库也是PIE默认情况下不是二进制文件。

我想还有一些其他的细微差别:p

存在于我们中间的可执行文件(叛徒:p)一直是真正共享的库,我们不知道gawkntfsck.

查看此问题/答案以获取更多信息。

于 2019-07-17T00:09:04.230 回答