如何将ELF文件转换为二进制文件?

8

我理解的二进制文件是处理器指令的十六进制代码(可以加载到内存并从入口点开始执行),而ELF文件与此相同,没有为数据等分配固定的内存地址。

现在,我该如何将ELF转换为二进制文件?

转换过程是如何工作的?我的意思是内存地址是如何分配的?


我猜你在谈论ARM纯二进制文件。(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/ch06s04s03.html) - ysdx
可能是如何使用GNU GAS汇编器生成类似nasm -f bin的纯二进制文件?的重复问题。 - Ciro Santilli OurBigBook.com
3个回答

7

一般情况下

ELF文件不需要使用“无固定内存地址”。事实上,典型的ELF可执行文件(ET_EXEC)使用固定地址。

二进制文件通常被理解为包含非文本数据的文件。在程序的上下文中,它通常被理解为程序的编译形式(与通常是一堆文本文件的源代码形式相对)。ELF文件是二进制文件。

现在你可能想知道ELF文件如何转换成程序的内存表示:ELF文件包含了额外的信息,例如程序中每个段应该加载到(虚拟)地址空间的位置,应该加载哪些动态库,如何将主程序和动态库链接在一起,如何初始化程序,程序的入口点在哪里等等。

可执行文件或共享对象的一个重要部分是必须加载到程序地址空间的段的位置。您可以使用readelf -l查看它们:

$ readelf -l /bin/bash

Elf file type is EXEC (Executable file)
Entry point 0x4205bc
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000f1a74 0x00000000000f1a74  R E    200000
  LOAD           0x00000000000f1de0 0x00000000006f1de0 0x00000000006f1de0
                 0x0000000000009068 0x000000000000f298  RW     200000
  DYNAMIC        0x00000000000f1df8 0x00000000006f1df8 0x00000000006f1df8
                 0x0000000000000200 0x0000000000000200  RW     8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044  R      4
  GNU_EH_FRAME   0x00000000000d6af0 0x00000000004d6af0 0x00000000004d6af0
                 0x000000000000407c 0x000000000000407c  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x00000000000f1de0 0x00000000006f1de0 0x00000000006f1de0
                 0x0000000000000220 0x0000000000000220  R      1

每个LOAD (PT_LOAD) 条目描述了一个必须加载到程序地址空间中的段。
读取和处理此信息是ELF加载程序的工作:在您的典型操作系统上,这部分由内核和动态链接器(ld.so,也称为ELF术语中的“程序解释器”)共同完成。
ARM纯二进制文件
(我不太了解ARM相关的东西。)
你显然在谈论嵌入式平台。在ARM上,纯二进制文件包含程序初始内存的原始内容。它不包含诸如字符串表、符号表、重定位表、调试信息等内容,只包含(PT_LOAD)段的数据。
它是一个二进制文件,不是十六进制编码的。vhx文件是十六进制编码的。

使用fromelf可以从ELF文件生成纯二进制文件。

基本思想是将ELF文件的每个PT_LOAD条目转储到文件中的正确位置,并用零填充它们之间的任何剩余间隙(如果有的话)。

ELF文件已经在每个段的p_vaddr字段中分配了地址,因此这个转换过程不需要确定地址:这已经由链接器(和链接脚本)完成了。

参考文献


3

我在搜索“将.elf转换为二进制文件”(主要是针对ARM文件)时来到这里。

结果发现,在我的情况下,最简单的方法是使用

    arm-none-eabi-objcopy -O binary kernel.elf kernel.bin


-1

我不明白你想说什么,但ELF(可执行链接格式)是一种新的可执行格式。当然,它的部分包括.text需要在内存中映射以进行执行。但如果你想将ELF转换为二进制,请查看 ELF文件和bin文件之间的区别。一些答案包含了如何将ELF转换为其他二进制格式的信息。

为了清楚ELF如何加载到内存中,请查看http://www.gsp.com/cgi-bin/man.cgi?topic=elf。如果你仍然有问题,请提出具体的问题。


1
这里的“新可执行格式”指的是追溯到1988年的格式 :) - ysdx
我认为是这样,但 a.out 和其他文件与操作系统的年龄几乎相同 :) - incompetent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接