确定Linux中二进制文件的目标体系结构(库或可执行文件)
我们遇到一个问题,这个问题涉及到一个运行在带有Via C3处理器的研华POS板上(相当老的)FC3下的Java应用程序。 Java应用程序有几个编译的共享库,通过JNI访问。
通过C3处理器被认为是i686兼容。 前一段时间,在MiniItx板上安装相同处理器的Ubuntu 6.10之后,我发现前面的语句不是100%正确的。 由于在C3处理器中缺乏一些特定和可选的i686指令,Ubuntu内核在启动时被挂起。 在使用i686优化时,GCC编译器默认使用缺lessC3实现i686集的这些指令。 在这种情况下,解决scheme是使用i386编译版本的Ubuntu发行版。
Java应用程序的基本问题是FC3发行版是通过从另一台PC的HD图像克隆而安装在HD上的,这次是Intel P4。 之后的发行需要一些黑客运行,如用i383编译版本replace一些软件包(如内核之一)。
问题是,工作一段时间后,系统完全挂起没有痕迹。 我担心一些i686代码会留在系统的某个地方,并可能随时随机执行(例如从挂起模式恢复之类的东西)。
我的问题是:
- 有没有什么工具或方法可以找出特定的体系结构是二进制文件(可执行文件或库)的目标,只要“ 文件 ”不能提供太多的信息?
我认为你需要一个工具来检查每一条指令,确定它属于哪个集合。 C3处理器实现的特定指令集还有一个官方名称吗? 如果不是的话,那就更加有趣了。
如果可以确定不允许的指令的位模式,则快速变体可能是在文件中执行原始search。 直接testing它们,可以通过一个简单的objdump | grep
来完成 objdump | grep
链,例如。
unix.linux的“文件”命令对此很有帮助。 它通常可以检测给定二进制文件的目标架构和操作系统(自1973年以来一直保持closures状态)。哇!
当然,如果你不是在unix / linux下运行的 – 你有点卡住了。 我目前正在试图find一个基于Java的端口,我可以在运行时调用..但没有这样的运气。
unix的'file'命令给出了这样的信息:
hex:ELF 32位LSB可执行文件,ARM,版本1(SYSV),dynamic链接(使用共享库),用于GNU / Linux 2.4.17,不剥离
(unix)'objdump -f'命令会提示关于体系结构细节的更多详细信息,该命令返回:
架构:arm,flags 0x00000112:EXEC_P,HAS_SYMS,D_PAGED起始地址0x0000876c
这个可执行文件是由一个gcc交叉编译器编译的(在ARM处理器的i86机器上编译为一个目标)
我决定给任何人添加一个解决scheme,谁来到这里:亲自在我的情况下,由file
和objdump
提供的信息是不够的,和grep
是没有太大的帮助 – 我通过readelf -a -W
解决我的情况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
要回答Via C3是否是i686类处理器的模糊性:不是,它是一个i586类处理器。
Cyrix从未生产出真正的686级处理器,尽pipe他们在6x86MX和MII部件的市场宣称。 在其他丢失的指令中,他们没有的两个重要指令是CMPXCHG8b和CPUID,它们是运行Windows XP及更高版本所必需的。
美国国家半导体,AMD和VIA都生产了基于Cyrix 5×86 / 6×86内核(NxP MediaGX,AMD Geode,VIA C3 / C7,VIA Corefusion等)的CPUdevise,这些devise产生了古怪的devise,其中有586级处理器用SSE1 / 2/3指令集。
我的build议,如果你遇到任何上面列出的CPU,而不是一个复古的电脑项目(即Windows 98SE和之前),然后运行尖叫远离它。 您将停留在慢速i386 / 486 Linux上,或者必须使用特定于Cyrix的优化工具重新编译您的所有软件。
扩展@ Hi-Angel的答案我发现了一个简单的方法来检查静态库的位宽:
readelf -a -W libsomefile.a | grep Class: | sort | uniq
libsomefile.a
是我的静态库。 还应该为其他ELF文件工作。
findbuild筑最快的事情就是执行:
objdump -f testFile | grep architecture
即使对于二进制文件也是如此