确定 Linux 中二进制文件的目标 ISA 扩展名(库或可执行文件)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/267941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:42:06  来源:igfitidea点击:

Determine target ISA extensions of binary file in Linux (library or executable)

linuxshared-librariesexecutablecpu-architectureinstruction-set

提问by Fernando Miguélez

We have an issue related to a Java application running under a (rather old) FC3 on an Advantech POS board with a Via C3 processor. The java application has several compiled shared libs that are accessed via JNI.

我们有一个与 Java 应用程序相关的问题,该应用程序在带有 Via C3 处理器的 Advantech POS 板上(相当旧的)FC3 下运行。Java 应用程序有几个编译共享库,可通过 JNI 访问。

Via C3 processor is supposed to be i686 compatible. Some time ago after installing Ubuntu 6.10 on a MiniItx board with the same processor, I found out that the previous statement is not 100% true. The Ubuntu kernel hanged on startup due to the lack of some specific and optional instructions of the i686 set in the C3 processor. These instructions missing in C3 implementation of i686 set are used by default by GCC compiler when using i686 optimizations. The solution, in this case, was to go with an i386 compiled version of Ubuntu distribution.

Via C3 处理器应该是 i686 兼容的。前段时间在相同处理器的MiniItx板上安装Ubuntu 6.10后,发现之前的说法不是100%正确。Ubuntu内核在启动时挂了,是因为缺少C3处理器中设置的i686的一些特定和可选的指令。在使用 i686 优化时,GCC 编译器默认使用 i686 集的 C3 实现中缺少的这些指令。在这种情况下,解决方案是使用 i386 编译版本的 Ubuntu 发行版。

The base problem with the Java application is that the FC3 distribution was installed on the HD by cloning from an image of the HD of another PC, this time an Intel P4. Afterwards, the distribution needed some hacking to have it running such as replacing some packages (such as the kernel one) with the i386 compiled version.

Java 应用程序的基本问题是,FC3 发行版是通过从另一台 PC(这次是 Intel P4)的 HD 映像克隆而安装在 HD 上的。之后,该发行版需要一些黑客才能运行,例如用 i386 编译版本替换一些包(例如内核包)。

The problem is that after working for a while the system completely hangs without a trace. I am afraid that some i686 code is left somewhere in the system and could be executed randomly at any time (for example after recovering from suspend mode or something like that).

问题是,工作一段时间后,系统完全挂起,无影无踪。我担心一些 i686 代码会留在系统中的某个地方,并且可以随时随机执行(例如从挂起模式恢复后或类似的东西)。

My question is:

我的问题是:

  • Is there any tool or way to find out at what specific architecture extensions a binary file (executable or library) requires? filedoes not give enough information.
  • 是否有任何工具或方法可以找出二进制文件(可执行文件或库)需要哪些特定的体系结构扩展?file没有提供足够的信息。

采纳答案by unwind

I think you need a tool that checks every instruction, to determine exactly which set it belongs to. Is there even an offical name for the specific set of instructions implemented by the C3 processor? If not, it's even hairier.

我认为您需要一个工具来检查每条指令,以确定它属于哪个指令集。C3 处理器实现的特定指令集是否有官方名称?如果没有,它甚至更毛茸茸。

A quick'n'dirty variant might be to do a raw search in the file, if you can determine the bit pattern of the disallowed instructions. Just test for them directly, could be done by a simple objdump | grepchain, for instance.

如果您可以确定不允许使用的指令的位模式,那么快速的变体可能是在文件中进行原始搜索。只需直接测试它们,例如可以通过一个简单的objdump | grep链来完成。

回答by Tim Kane

The unix.linux filecommand is great for this. It can generally detect the target architecture and operating system for a given binary (and has been maintained on and off since 1973. wow!)

unix.linuxfile命令非常适合这个。它通常可以检测给定二进制文件的目标体系结构和操作系统(并且自 1973 年以来一直保持断断续续。哇!)

Of course, if you're not running under unix/linux - you're a bit stuck. I'm currently trying to find a java based port that I can call at runtime.. but no such luck.

当然,如果你不是在 unix/linux 下运行——你就有点卡住了。我目前正在尝试找到一个可以在运行时调用的基于 Java 的端口......但没有这样的运气。

The unix filecommand gives information like this:

unixfile命令提供如下信息:

hex: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.17, not stripped

More detailed information about the details of the architecture are hinted at with the (unix) objdump -f <fileName>command which returns:

使用 (unix)objdump -f <fileName>命令提示有关架构细节的更多详细信息,该命令返回:

architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000876c

This executable was compiled by a gcc cross compiler (compiled on an i86 machine for the ARM processor as a target)

这个可执行文件是由 gcc 交叉编译器编译的(在 i86 机器上编译,以 ARM 处理器为目标)

回答by Hi-Angel

I decide to add one more solution for any, who got here: personally in my case the information provided by the fileand objdumpwasn't enough, and the grepisn't much of a help -- I resolve my case through the readelf -a -W.

我决定为任何来到这里的人添加一个更多的解决方案:就我个人而言,file和提供的信息还objdump不够,而且grep帮助不大——我通过readelf -a -W.

Note, that this gives you pretty much info. The arch related information resides in the very beginning and the very end. Here's an example:

请注意,这为您提供了很多信息。与拱门相关的信息存在于开头和结尾。下面是一个例子:

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

回答by jcoffland

Expanding upon @Hi-Angel's answer I found an easy way to check the bit width of a static library:

扩展@Hi-Angel 的回答,我找到了一种检查静态库位宽的简单方法:

readelf -a -W libsomefile.a | grep Class: | sort | uniq

Where libsomefile.ais my static library. Should work for other ELF files as well.

libsomefile.a我的静态库在哪里。也适用于其他 ELF 文件。

回答by Duke

To answer the ambiguity of whether a Via C3 is a i686 class processor: It's not, it's an i586 class processor.

回答 Via C3 是否是 i686 级处理器的歧义:不是,它是 i586 级处理器。

Cyrix never produced a true 686 class processor, despite their marketing claims with the 6x86MX and MII parts. Among other missing instructions, two important ones they didn't have were CMPXCHG8b and CPUID, which were required to run Windows XP and beyond.

Cyrix 从未生产过真正的 686 级处理器,尽管他们的营销声称是 6x86MX 和 MII 部件。在其他缺失的指令中,他们没有的两个重要指令是 CMPXCHG8b 和 CPUID,它们是运行 Windows XP 及更高版本所必需的。

National Semiconductor, AMD and VIA have all produced CPU designs based on the Cyrix 5x86/6x86 core (NxP MediaGX, AMD Geode, VIA C3/C7, VIA Corefusion, etc.) which have resulted in oddball designs where you have a 586 class processor with SSE1/2/3 instruction sets.

美国国家半导体、AMD 和 VIA 都基于 Cyrix 5x86/6x86 内核(NxP MediaGX、AMD Geode、VIA C3/C7、VIA Corefusion 等)生产了 CPU 设计,这些设计导致您拥有 586 级处理器的奇怪设计带有 SSE1/2/3 指令集。

My recommendation if you come across any of the CPUs listed above and it's not for a vintage computer project (ie. Windows 98SE and prior) then run screaming away from it. You'll be stuck on slow i386/486 Linux or have to recompile all of your software with Cyrix specific optimizations.

我的建议是,如果您遇到上面列出的任何 CPU 并且它不是用于老式计算机项目(即 Windows 98SE 和更早版本),那么请远离它。您将被困在缓慢的 i386/486 Linux 上,或者必须使用 Cyrix 特定优化重新编译所有软件。

回答by Shailesh

Quickest thing to find architecture would be to execute:

找到架构的最快方法是执行:

objdump -f testFile | grep architecture

This works even for binary.

这甚至适用于二进制。