检查库是32位还是64位
1. 概述
我们可以在 64 位 Linux 系统上安装 32 位和 64 位库来运行我们的应用程序。在这里,我们谈论的是为特定架构编译的 C/C++ 库。
我们有时可能想知道给定的库是 32 位还是 64 位。在这个简短的教程中,我们将学习几种确定库格式的方法。
2. 共享库和静态库
库将一组预编译的代码组合到一个文件中,以便可以在不同的程序中使用。
在 Linux 中,我们有两种类型的库:
- 静态——在编译时静态绑定到程序,通常命名为“ *.a ”
- Shared — 在程序启动时加载并在运行时加载到内存中,通常命名为“ *.so ”
静态库不是可执行文件。相反,它是ar 格式 的文件。它只是其他文件的存档,例如ELF 目标文件。
另一方面,共享库是 ELF 文件。
ELF 标头定义库是使用 32 位还是 64 位地址。
在本教程中,我们将使用file 和objdump 命令来确定库的格式。我们将看看这如何适用于静态库和共享库。
3. 使用file命令
file命令是检查文件类型的便捷实用程序。我们可以使用file 来告诉我们库的格式。
3.1.共享库
首先,让我们在两个共享库上对其进行测试:
$ file /usr/lib/libc-2.33.so
/usr/lib/libc-2.33.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, ....
$ file /usr/lib32/libc-2.33.so
/usr/lib32/libc-2.33.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, ...
在这里,我们在 32 位和 64 位库文件上执行了文件。正如我们所见,file命令读取 ELF 头并报告每个库的详细信息,包括它使用的地址宽度。
3.2. 静态库
接下来,让我们对静态库进行类似的测试:
$ file /usr/lib/libc.a
/usr/lib/libc.a: current ar archive
$ file /usr/lib32/libc.a
/usr/lib32/libc.a: current ar archive
这一次,file命令只是告诉我们它们是ar档案,但不报告它们是 32-bit 还是 64-bit。 这是因为静态库只是一个存档而不是 ELF 文件。file命令不会查看静态库中的所有 ELF 目标文件并读取它们的标题。
4. 使用objdump命令
objdump命令是GNU Binutils 包的成员 。它显示来自目标文件的信息。
我们可以使用*-f*选项来读取 ELF 文件的标头。
4.1. 共享库
首先,让我们看看 如果我们在一些共享库上执行objdump会输出什么:
$ objdump -f /usr/lib/libc-2.33.so
/usr/lib/libc-2.33.so: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000027c60
$ objdump -f /usr/lib32/libc-2.33.so
/usr/lib32/libc-2.33.so: file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0001ebc0
在上面的输出中,“文件格式”字段报告 ELF 文件使用 64 位 ( elf64-… ) 或 32 位 ( elf32-… ) 地址。
因此,“ /usr/lib/libc-2.33.so ”文件是64位库,另一个是32位库。此外,如果我们查看它们的“起始地址”字段,它们分别具有 64 位和 32 位宽的地址。
4.2. 静态库
接下来,让我们在静态库上运行相同的命令:
$ objdump -f /usr/lib/libc.a
In archive /usr/lib/libc.a:
init-first.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
libc-start.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x0000000000000000
sysdep.o: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000000:
start address 0x0000000000000000
...
上面的输出显示了objdump命令处理静态库中输出其 ELF 标头的所有目标文件。
**此解决方案有效,但可以产生大量输出。**例如,上面的输出运行超过 10,000 行。
4.3. 获得直接的输出
为了总结 ELF 头信息,我们可以通过管道将objdump的输出传递给awk ,以通过search 和 replace 提取文件格式值,并删除重复项 :
$ objdump -f /usr/lib/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf64-x86-64
现在,输出意味着静态库中的所有目标文件都使用 64 位地址。所以,我们可以说*/usr/lib/libc.a*是一个 64 位的静态库。
最后,让我们在 32 位静态库上测试该命令:
$ objdump -f /usr/lib32/libc.a | awk 'sub(/.*file format /,"") && !a[$0]++'
elf32-i386
“ elf32-*”表示库中的所有目标文件都使用 32 位地址。因此,它是一个 32 位库。