确定 Linux 中二进制文件的目标 ISA 扩展名(库或可执行文件)
Posted
技术标签:
【中文标题】确定 Linux 中二进制文件的目标 ISA 扩展名(库或可执行文件)【英文标题】:Determine target ISA extensions of binary file in Linux (library or executable) 【发布时间】:2010-09-21 01:01:47 【问题描述】:我们遇到了一个问题,该问题与在带有 Via C3 处理器的 Advantech POS 板上的(相当旧的)FC3 下运行的 Java 应用程序有关。 Java 应用程序有几个通过 JNI 访问的已编译共享库。
Via C3 处理器应该与 i686 兼容。前段时间在具有相同处理器的 MiniItx 板上安装 Ubuntu 6.10 后,我发现前面的说法并非 100% 正确。由于缺少C3处理器中设置的i686的一些特定和可选指令,Ubuntu内核在启动时挂起。在使用 i686 优化时,GCC 编译器默认使用 i686 集的 C3 实现中缺少的这些指令。在这种情况下,解决方案是使用 i386 编译版本的 Ubuntu 发行版。
Java 应用程序的基本问题是 FC3 发行版是通过从另一台 PC(这次是 Intel P4)的 HD 映像克隆而安装在 HD 上的。之后,该发行版需要进行一些修改才能使其运行,例如用 i386 编译版本替换一些软件包(例如内核)。
问题是工作一段时间后系统完全挂掉了。恐怕有些 i686 代码会留在系统某处,随时可能随机执行(例如从挂起模式恢复后或类似的情况)。
我的问题是:
是否有任何工具或方法可以找出二进制文件(可执行文件或库)需要哪些特定架构扩展?file
没有提供足够的信息。
【问题讨论】:
【参考方案1】:unix.linux file
命令非常适合这个。它通常可以检测给定二进制文件的目标架构和操作系统(并且自 1973 年以来一直保持开启和关闭。哇!)
当然,如果你不是在 unix/linux 下运行 - 你有点卡住了。我目前正在尝试找到一个可以在运行时调用的基于 java 的端口。但没有这样的运气。
unix file
命令提供如下信息:
hex: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.17, not stripped
有关架构细节的更多详细信息通过 (unix) objdump -f <fileName>
命令返回:
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000876c
此可执行文件由 gcc 交叉编译器编译(在 i86 机器上编译,以 ARM 处理器为目标)
【讨论】:
这个问题特别要求超越file,但我是根据标题来到这里的,而file正是我想要的。所以这是否真的是一个好的答案值得怀疑,因为它没有回答实际的问题,但它确实回答了我的问题,而且显然 aaronstacy 也是! (我添加了一些关于(unix)“objdump -f”命令的信息,这些信息超出了“文件”命令。遗憾的是,我不知道“标志”中的位是什么意思——可能需要搜索gcc代码。(或使用它们来比较各种目标机器上的设置)) 当我尝试最后一个时,我得到objdump: Unknown command line argument '-f'. Try: 'objdump -help'
【参考方案2】:
我决定为任何来到这里的人添加一个解决方案:就我个人而言,file
和 objdump
提供的信息还不够,grep
也没有太大帮助-- 我通过readelf -a -W
解决了我的问题。
请注意,这为您提供了很多信息。拱相关信息存在于开头和结尾。这是一个例子:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x83f8
Start of program headers: 52 (bytes into file)
Start of section headers: 2388 (bytes into file)
Flags: 0x5000202, has entry point, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28
...
Displaying notes found at file offset 0x00000148 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.16
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "7-A"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_rounding: Needed
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP
Tag_CPU_unaligned_access: v6
【讨论】:
免责声明:这仅在您已经知道该文件是 ELF 文件时才有效。 Mach-O 二进制文件(在 iPhone 和 Macbook 上运行)是非 ELF 二进制格式的一个示例。 @ryanrhee 好吧,如果你还不知道它是不是 ELF,那么在你运行命令之后你一定会知道☺ 我只想要架构信息,可以使用readelf -A
【参考方案3】:
我认为您需要一个工具来检查每条指令,以确定它属于哪个集合。 C3 处理器实现的特定指令集是否有正式名称?如果没有,那就更毛了。
如果您可以确定不允许的指令的位模式,那么快速的变体可能是在文件中进行原始搜索。直接测试它们,例如可以通过一个简单的objdump | grep
链来完成。
【讨论】:
objdump -d 应该为您提供 ASM 表示,然后您可以使用 grep 查找错误的操作码。 我想我会按照你建议的方式去做。我只需要了解如何反编译vmlinuz(我无法确定内核本身是i386还是i686版本)。 +1。这对我来说没有多大帮助,但我真的很喜欢这种 hacky 方式! 我用这个命令提取目标文件架构信息...objdump -x <file> | grep Architektur: | cut --delimiter=" " -f 2 | cut --delimiter="," -f 1
【参考方案4】:
回答 Via C3 是否是 i686 类处理器的歧义:不是,它是 i586 类处理器。
Cyrix 从未生产过真正的 686 级处理器,尽管他们在市场上声称使用 6x86MX 和 MII 部件。在其他缺失的指令中,他们没有的两个重要指令是 CMPXCHG8b 和 CPUID,它们是运行 Windows XP 及更高版本所必需的。
美国国家半导体、AMD 和威盛都生产了基于 Cyrix 5x86/6x86 内核(NxP MediaGX、AMD Geode、威盛 C3/C7、威盛 Corefusion 等)的 CPU 设计,这导致了奇特的设计,你有具有 SSE1/2/3 指令集的 586 类处理器。
我的建议是,如果您遇到上面列出的任何 CPU 并且它不是用于老式计算机项目(即 Windows 98SE 和更早版本),那么请远离它。您将被困在缓慢的 i386/486 Linux 上,或者必须使用 Cyrix 特定的优化重新编译所有软件。
【讨论】:
【参考方案5】:根据@Hi-Angel 的回答,我找到了一种检查静态库位宽的简单方法:
readelf -a -W libsomefile.a | grep Class: | sort | uniq
libsomefile.a
是我的静态库。应该也适用于其他 ELF 文件。
【讨论】:
【参考方案6】:找到架构的最快方法是执行:
objdump -f testFile | grep architecture
这甚至适用于二进制。
【讨论】:
我收到objdump: Unknown command line argument '-f'. Try: 'objdump -help'
以上是关于确定 Linux 中二进制文件的目标 ISA 扩展名(库或可执行文件)的主要内容,如果未能解决你的问题,请参考以下文章