elf格式中可执行文件和可重定位文件有什么区别?

26

ELF格式中的可执行文件和可重定位文件有何区别?

4个回答

17

正如您所知道的,每个编译的可执行文件都是一个具有相对和绝对地址的二进制文件,因此重新定位格式是一种格式,在该格式中,函数和其他符号仍然具有它们在其他单词中的名称定义,换句话说,函数和变量不绑定到任何特定的地址。相反,这些地址仍然是符号。

看:

unix > gcc -c main.c
unix > readelf --symbols main.o
Num:     Value   Size     Type      Bind       Vis     Ndx  Name
  0:  00000000      0   NOTYPE     LOCAL   DEFAULT     UND
  1:  00000000      0   FILE       LOCAL   DEFAULT     ABS  main.c
  2:  00000000      0   OBJECT    GLOBAL   DEFAULT     3    buf
  3:  00000000      0   OBJECT    GLOBAL   DEFAULT     1    main

unix > gcc main.c -o main
unix > readelf --symbols main
Num:     Value   Size     Type      Bind       Vis     Ndx  Name
 53:  08048460      2     FUNC    GLOBAL   DEFAULT     13   __libc_csu_fini
 54:  08048462      0     FUNC    GLOBAL   HIDDEN      13   __i686.get_pc_thunk.bx
 55:  0804a018      4     OBJECT  GLOBAL   DEFAULT     13   bufp0

你明白我在说什么吗?

大多数情况下,我们将它们用作静态库。

看这里的例子:

#ifndef MATH_H
#define MATH_H
int add(int a, int b);
#endif

/* math_test.c */
#include <stdio.h>
#include "math.h"

int main(void)
{
  int result = add(1, 2);
  printf("result: %d\n", result);
  return 0;
}

尝试编译它

unix > gcc math_test.c -o math_test
/tmp/cclRibQq.o: In function `main':
math_test.c:(.text+0x19): undefined reference to `add'
collect2: ld returned 1 exit status

由于 math_test.c 中的函数 add 没有函数体,我们可以这样做:

that due to function add has no body in math_test.c so we can do the flowing:

返回:

由于 math_test.c 中的函数 add 没有函数体,我们可以这样做:

int add(int a, int b)
{
  return a + b;
}

然后使用gcc将其编译为可重定位文件

unix > gcc -c math.c                      # Create relocatable obj file (math.o)
unix > readelf -h math.o | grep Type      # Read math.o with readelf
Type:            REL (Relocatable file)   # and verify its type

那么你可以像这样使用连接器将它链接:

unix > gcc math_test.c math.o -o math_test
unix > ./math_test
result: 3

您可以在这里找到一篇关于ELF格式可执行文件和可重定位文件之间区别的好文章。


请在这里总结一下,以便在链接失效时保留信息。 - sorak
@sorak,你能看一下并告诉我是否还有其他问题需要修复吗?谢谢。 - zerocool
干得好,谢谢。我添加了语法高亮。看看它是如何工作的。 - sorak

15

如下图所示,可重定位的ELF文件是链接器的输入,而可执行的ELF文件则是链接器的输出。

Freescale SC100 development tools example diagram


6

可重定位文件没有任何加载地址,它只是具有偏移量的二进制代码序列(例如与主函数相关的偏移量)。但是,可执行文件具有加载地址,而不仅仅是与任何函数相关的偏移量。

它们之间的另一个基本区别是可执行文件具有引导应用程序,而可重定位文件则没有。


6

ELF可执行文件,从其名称中可以理解,是一个可执行的文件。例如,这个文件可以从C代码生成。

重定位的过程是修复在代码中创建的标签和符号的地址。例如,如果你使用汇编语言编写程序,并查看源代码清单文件,你会发现某些地方写有[00000000],而不是这行提到的标签。这些零意味着链接器使用重定位来修复地址到其未来的值。


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