程序解释器在可执行文件中的作用是什么?
What is the role of program interpreters in executable files?
我正在对 elf 可执行文件进行反汇编并了解 elf 格式。在那里,我看到 lib64/ld-linux-x86-64.so.2
在生成的可执行文件中用作程序解释器。
我的猜测是:我在源代码中使用了printf
,它必须是动态链接的。当我检查动态部分时,我能够找到对 libc.so.6
共享库(标签:DT_NEEDED)的引用。在我的系统中,我在不同的目录中找到了多个具有该名称的文件:
sourav@ubuntu-VirtualBox:/$ sudo find / -name libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so.6
find: ‘/run/user/1000/doc’: Permission denied
find: ‘/run/user/1000/gvfs’: Permission denied
/snap/snapd/13170/lib/x86_64-linux-gnu/libc.so.6
/snap/snapd/11107/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/1988/lib/i386-linux-gnu/libc.so.6
/snap/core18/1988/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/2128/lib/i386-linux-gnu/libc.so.6
/snap/core18/2128/lib/x86_64-linux-gnu/libc.so.6
所以,我猜程序解释器的目的是将这些名称解析为正确的库并在执行期间加载它们。这是正确的吗?
看来,我们也可以拥有没有程序解释器的可执行文件(程序解释器本身就是这种情况)。在那种情况下, system/os 本身会加载共享库吗?如果是,它是如何解析库的路径的?
是否可以使用 gcc 在没有程序解释器的情况下生成可执行文件?我的 gcc 版本是 'gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)'.
So, I guess purpose of program interpreter is to resolve these names to the proper libraries and load them during execution. Is this correct?
是的,但这有点简约。加载动态库涉及定位它们,必要时将它们加载或映射到内存中,并可能延迟地解析动态符号以进行多种重定位。它涉及递归加载库自己需要的库。此外,在动态 linked 可执行文件中,程序解释器提供程序入口点(从内核的角度来看),因此它还负责设置和进入 program-specific 入口点(例如, main()
在 C 或 C++ 程序中)。
It seems, we can also have executables with no program interpreter (which is the case for program interpreter itself). In that case, does system/os itself loads the shared library? If so, how does it resolves the path of library?
您可以拥有没有程序解释器的 ELF 可执行文件,但它们不是动态 linked,至少不是在 ELF 意义上。没有要加载的共享库,当然系统也不会加载。
Is it possible to generate executable with no program interpreter using gcc? My gcc version is 'gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)'.
如果您有所有需要的库的静态版本可用,那么您应该能够通过在 link 程序时在命令行中包含 -static
选项来实现这一点。然而,您完全有可能没有所需的静态库,即使 libc 是您唯一需要的库。
我正在对 elf 可执行文件进行反汇编并了解 elf 格式。在那里,我看到 lib64/ld-linux-x86-64.so.2
在生成的可执行文件中用作程序解释器。
我的猜测是:我在源代码中使用了printf
,它必须是动态链接的。当我检查动态部分时,我能够找到对 libc.so.6
共享库(标签:DT_NEEDED)的引用。在我的系统中,我在不同的目录中找到了多个具有该名称的文件:
sourav@ubuntu-VirtualBox:/$ sudo find / -name libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so.6
find: ‘/run/user/1000/doc’: Permission denied
find: ‘/run/user/1000/gvfs’: Permission denied
/snap/snapd/13170/lib/x86_64-linux-gnu/libc.so.6
/snap/snapd/11107/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/1988/lib/i386-linux-gnu/libc.so.6
/snap/core18/1988/lib/x86_64-linux-gnu/libc.so.6
/snap/core18/2128/lib/i386-linux-gnu/libc.so.6
/snap/core18/2128/lib/x86_64-linux-gnu/libc.so.6
所以,我猜程序解释器的目的是将这些名称解析为正确的库并在执行期间加载它们。这是正确的吗?
看来,我们也可以拥有没有程序解释器的可执行文件(程序解释器本身就是这种情况)。在那种情况下, system/os 本身会加载共享库吗?如果是,它是如何解析库的路径的?
是否可以使用 gcc 在没有程序解释器的情况下生成可执行文件?我的 gcc 版本是 'gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)'.
So, I guess purpose of program interpreter is to resolve these names to the proper libraries and load them during execution. Is this correct?
是的,但这有点简约。加载动态库涉及定位它们,必要时将它们加载或映射到内存中,并可能延迟地解析动态符号以进行多种重定位。它涉及递归加载库自己需要的库。此外,在动态 linked 可执行文件中,程序解释器提供程序入口点(从内核的角度来看),因此它还负责设置和进入 program-specific 入口点(例如, main()
在 C 或 C++ 程序中)。
It seems, we can also have executables with no program interpreter (which is the case for program interpreter itself). In that case, does system/os itself loads the shared library? If so, how does it resolves the path of library?
您可以拥有没有程序解释器的 ELF 可执行文件,但它们不是动态 linked,至少不是在 ELF 意义上。没有要加载的共享库,当然系统也不会加载。
Is it possible to generate executable with no program interpreter using gcc? My gcc version is 'gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)'.
如果您有所有需要的库的静态版本可用,那么您应该能够通过在 link 程序时在命令行中包含 -static
选项来实现这一点。然而,您完全有可能没有所需的静态库,即使 libc 是您唯一需要的库。