究竟什么是目标文件中的符号引用?

用户名

我从程序员的角度阅读计算机系统,这是关于链接的章节。它说明了如何使用程序ld在Linux x86-64中进行链接。作者声称,为了从可重定位的目标文件构建可执行文件,链接器执行两件事:符号解析和重定位。这是他们对什么是符号解析的简要概述:

目标文件定义和引用符号,其中每个符号对应于一个函数,一个全局变量或一个静态变量(即,用static属性声明的任何C变量)。符号解析的目的是将每个符号引用与一个符号定义完全关联。

但是,即使他们开始深入描述符号分辨率,也无法弄清楚符号引用的含义。那么可重定位目标文件中引用的符号究竟有多精确?

受雇于俄罗斯

考虑以下来源:

static int foo() { return 42; }
static int bar() { return foo() + 1; }

extern int baz();

int main()
{
  return foo() + bar() + baz();
}

在之后gcc -c foo.cobjdump -d foo.ox86_64 Linux上的输出是:

foo.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <foo>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 2a 00 00 00          mov    $0x2a,%eax
   9:   5d                      pop    %rbp
   a:   c3                      retq

000000000000000b <bar>:
   b:   55                      push   %rbp
   c:   48 89 e5                mov    %rsp,%rbp
   f:   b8 00 00 00 00          mov    $0x0,%eax
  14:   e8 e7 ff ff ff          callq  0 <foo>
  19:   83 c0 01                add    $0x1,%eax
  1c:   5d                      pop    %rbp
  1d:   c3                      retq

000000000000001e <main>:
  1e:   55                      push   %rbp
  1f:   48 89 e5                mov    %rsp,%rbp
  22:   53                      push   %rbx
  23:   48 83 ec 08             sub    $0x8,%rsp
  27:   b8 00 00 00 00          mov    $0x0,%eax
  2c:   e8 cf ff ff ff          callq  0 <foo>
  31:   89 c3                   mov    %eax,%ebx
  33:   b8 00 00 00 00          mov    $0x0,%eax
  38:   e8 ce ff ff ff          callq  b <bar>
  3d:   01 c3                   add    %eax,%ebx
  3f:   b8 00 00 00 00          mov    $0x0,%eax
  44:   e8 00 00 00 00          callq  49 <main+0x2b>
  49:   01 d8                   add    %ebx,%eax
  4b:   48 83 c4 08             add    $0x8,%rsp
  4f:   5b                      pop    %rbx
  50:   5d                      pop    %rbp
  51:   c3                      retq

这里有几件事要注意:

  1. 请注意地址处的bar呼叫方式怎么知道那是被叫?真的可以在地址0吗?(大多数现代系统都使用来映射虚拟内存的零页,因此那里没有读写访问权限。)foo0objdumpfooPROT_NONE
  2. 请注意如何调用bazmain是从调用不同的foobar编译器知道调用指令本身的位置foobar位置,但不知道调用位置baz

因此,根据上述信息,链接器如何将其转变为明智的选择?不能:这里没有足够的信息。

为了使链接器能够将对baz(我们尚未看到的)引用链接到的调用中baz,它需要其他信息。在ELF系统上,该附加信息被写入.rela.text此处的特殊部分,其中包括:

$ readelf -Wr foo.o

Relocation section '.rela.text' at offset 0x5d0 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000045  0000000b00000002 R_X86_64_PC32          0000000000000000 baz - 4

是书中谈到但没有定义的“参考”。它告诉链接:如果可以找到baz(在其他对象中)一个定义,则获取其地址,然后将其放入(实际上,&baz - 4因为该CALL指令是相对于指令之后的下一条指令而言CALL)放入.text节的字节[45-48]中foo.o

如果没有这样的定义?链接器将产生错误:

$ gcc foo.o
foo.o: In function `main':
foo.c:(.text+0x45): undefined reference to `baz'
collect2: error: ld returned 1 exit status

最后,到达以上第1点:foo真的可以在地址0处吗?

不,但是CALL地址0x14指令实际上没有说CALL 0它说:“在调用之后的下一条指令的地址处,减去25,调用例程”。如果在最终的二进制端向上在地址调用指令0x400501,则该呼叫的目标将是0x4004ed,这是在foo将结束(之间的距离fooCALL将不会改变,当链接程序重定位.text的部分foo.o到不同的地址(接头松弛尽管如此;但这又是一个复杂的话题)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

g ++表示引用未定义,即使`nm`列出了我的目标文件中的符号定义

来自分类Dev

究竟什么是匿名文件

来自分类Dev

编写COFF目标文件...如何引用外部符号

来自分类Dev

在Windows上从目标文件中删除符号

来自分类Dev

目标文件中未解析的外部符号

来自分类Linux

如何查看目标文件中的符号?

来自分类Dev

为什么内部链接的名称会出现在目标文件的符号表中?

来自分类Dev

为什么不可能从Objective-C目标文件中隐藏符号?

来自分类Dev

什么是C中的目标文件?

来自分类Dev

Apache Ant java 目标中的 maxmemory 标志究竟有什么作用?

来自分类Dev

在R中,究竟是什么导致对名称(或符号)类型的对象进行求值?

来自分类Dev

gradle 中的“$”符号究竟是什么用于依赖项?

来自分类Dev

对目标文件的引用。为什么/如何创建和使用?

来自分类Dev

如何复制和重命名目标文件中的符号?

来自分类Dev

在COFF目标文件中检测C ++内联符号

来自分类Dev

NASM + GoLink:“目标文件中未定义以下符号”

来自分类Dev

从类AS3引用目标文件中的变量

来自分类Dev

NTFS 压缩究竟对文件做了什么?

来自分类Dev

文件中的E符号是什么?

来自分类Dev

WinDbg中“符号文件”的含义是什么?

来自分类Dev

链接目标文件时,为什么我的pdb文件缺少符号?

来自分类Dev

如何将.mht文件聚焦在iframe中打开?我究竟做错了什么?

来自分类Java

Java中的符号引用

来自分类Dev

Java中的.class究竟返回什么?

来自分类Dev

为什么LDFLAGS将我的库放在生成未定义引用的目标文件之前?

来自分类Dev

flatbuffers 中的引用究竟是如何工作的?

来自分类Dev

什么是 iOS 中的构建目标文件扩展名?

来自分类Dev

转到符号链接文件目标目录

来自分类Dev

按符号链接目标列出文件

Related 相关文章

  1. 1

    g ++表示引用未定义,即使`nm`列出了我的目标文件中的符号定义

  2. 2

    究竟什么是匿名文件

  3. 3

    编写COFF目标文件...如何引用外部符号

  4. 4

    在Windows上从目标文件中删除符号

  5. 5

    目标文件中未解析的外部符号

  6. 6

    如何查看目标文件中的符号?

  7. 7

    为什么内部链接的名称会出现在目标文件的符号表中?

  8. 8

    为什么不可能从Objective-C目标文件中隐藏符号?

  9. 9

    什么是C中的目标文件?

  10. 10

    Apache Ant java 目标中的 maxmemory 标志究竟有什么作用?

  11. 11

    在R中,究竟是什么导致对名称(或符号)类型的对象进行求值?

  12. 12

    gradle 中的“$”符号究竟是什么用于依赖项?

  13. 13

    对目标文件的引用。为什么/如何创建和使用?

  14. 14

    如何复制和重命名目标文件中的符号?

  15. 15

    在COFF目标文件中检测C ++内联符号

  16. 16

    NASM + GoLink:“目标文件中未定义以下符号”

  17. 17

    从类AS3引用目标文件中的变量

  18. 18

    NTFS 压缩究竟对文件做了什么?

  19. 19

    文件中的E符号是什么?

  20. 20

    WinDbg中“符号文件”的含义是什么?

  21. 21

    链接目标文件时,为什么我的pdb文件缺少符号?

  22. 22

    如何将.mht文件聚焦在iframe中打开?我究竟做错了什么?

  23. 23

    Java中的符号引用

  24. 24

    Java中的.class究竟返回什么?

  25. 25

    为什么LDFLAGS将我的库放在生成未定义引用的目标文件之前?

  26. 26

    flatbuffers 中的引用究竟是如何工作的?

  27. 27

    什么是 iOS 中的构建目标文件扩展名?

  28. 28

    转到符号链接文件目标目录

  29. 29

    按符号链接目标列出文件

热门标签

归档