为什么同一文件中的全局符号需要重新定位?

2023-12-06

我有一个用于测试的 C 程序:a.c

int a = 0;

static int fa_local()
{
    a = 78; 
    int b;
    int c;
}

int fa_global()
{
    a = 7777;
    fa_local();
}

int test()
{
    a = 6666;
    fa_global();

}

这是构建后的重定位表:

[freeman@centos-7 link_symbol_test]$ gcc -c a.c
[freeman@centos-7 link_symbol_test]$ readelf -r a.o

Relocation section '.rela.text' at offset 0x5d0 contains 4 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000006  000900000002 R_X86_64_PC32     0000000000000000 a - 8
000000000016  000900000002 R_X86_64_PC32     0000000000000000 a - 8
000000000030  000900000002 R_X86_64_PC32     0000000000000000 a - 8
00000000003e  000a00000002 R_X86_64_PC32     0000000000000010 fa_global - 4

重定位入口是test()中的函数调用fa_global(),其偏移量为00000000003e。

[freeman@centos-7 link_symbol_test]$ objdump -dS a.o:

0000000000000010 <fa_global>:

int fa_global()
{
  10:   55                      push   %rbp
  11:   48 89 e5                mov    %rsp,%rbp
    a = 7777;
  14:   c7 05 00 00 00 00 61    movl   $0x1e61,0x0(%rip)        # 1e <fa_global+0xe>
  1b:   1e 00 00 
    fa_local();
  1e:   b8 00 00 00 00          mov    $0x0,%eax
  23:   e8 d8 ff ff ff          callq  0 <fa_local>
}
  28:   5d                      pop    %rbp
  29:   c3                      retq   

000000000000002a <test>:

int test()
{
  2a:   55                      push   %rbp
  2b:   48 89 e5                mov    %rsp,%rbp
    a = 6666;
  2e:   c7 05 00 00 00 00 0a    movl   $0x1a0a,0x0(%rip)        # 38 <test+0xe>
  35:   1a 00 00 
    fa_global();
  38:   b8 00 00 00 00          mov    $0x0,%eax
  3d:   e8 00 00 00 00          callq  42 <test+0x18>
}
  42:   5d                      pop    %rbp
  43:   c3                      retq

对于 fa_global(),它位于同一个文件中。

为什么这个符号需要重新定位, 而静态符号 fa_local() 则不然?


2017.9.12更新:优化后的汇编代码

[freeman@centos-7 relocation_test]$ gcc -fno-inline -O2 -c a.c
[freeman@centos-7 relocation_test]$ objdump -dS a.o

a.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <fa_local>:
   0:   c7 05 00 00 00 00 4e    movl   $0x4e,0x0(%rip)        # a <fa_local+0xa>
   7:   00 00 00 
   a:   c3                      retq   
   b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

0000000000000010 <fa_global>:
  10:   31 c0                   xor    %eax,%eax
  12:   c7 05 00 00 00 00 61    movl   $0x1e61,0x0(%rip)        # 1c <fa_global+0xc>
  19:   1e 00 00 
  1c:   eb e2                   jmp    0 <fa_local>
  1e:   66 90                   xchg   %ax,%ax

0000000000000020 <test>:
  20:   31 c0                   xor    %eax,%eax
  22:   c7 05 00 00 00 00 0a    movl   $0x1a0a,0x0(%rip)        # 2c <test+0xc>
  29:   1a 00 00 
  2c:   e9 00 00 00 00          jmpq   31 <test+0x11>

但我仍然看到重定位条目:

000000000000002d R_X86_64_PC32 fa_global-0x0000000000000004


fa_local是一个函数。编译器可以确定其距调用点的偏移量。它对调用指令使用PC相对寻址模式,因此不需要绝对地址,可以直接发出代码。

相反,a符号位于内存的不同部分,这是一个可写段,其偏移量在编译时无法确定。链接器在重定位阶段执行此操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么同一文件中的全局符号需要重新定位? 的相关文章

随机推荐

  • 在 Matlab 中将字符串单元格转换为双精度型

    我如何转换单元格如下 gt gt A 2 2 23 23 6 A 2 2 23 23 6 为以下双倍 A 2 0000 2 0000 NaN 23 0000 23 6000 str2double可以直接在字符串元胞数组上调用 gt gt X
  • 重新检查文档的拼写是否与 VBA 代码不同

    我想在添加字典后重新检查文档中的拼写 问题是下面的代码 大部分来自宏记录器 CustomDictionaries Add FileName c test dictionary dic Application ResetIgnoreAll A
  • NoClassDefFoundError FirebaseOptions,android?

    当我在设备上运行我的应用程序时 我收到此异常 java lang NoClassDefFoundError com google firebase FirebaseOptions at com google firebase Firebas
  • 如何使用字符串联合填充对象类型的可选嵌套关系?

    我正在尝试创建一个Populate需要 2 个泛型的类型 具有可选关系的对象类型 引用其他对象类型的键 以及可以深度填充 或者更确切地说 设置为非可选 关系的 Path 字符串的联合 例如 有 3 个实体 它们都可以选择性地相互引用 typ
  • 将Actionbarsherlock导入到eclipse中

    有人可以告诉我如何正确导入 SherlockFragmentActivity java 和 ActionBarSherlock 文件夹的步骤吗 我不太确定如何做到这一点 并且在尝试时遇到很多错误 提取 ActionBarSherlock 项
  • javascript eval 可能会带来哪些问题

    我尝试谷歌搜索 但没有得到非常具体的答案 话又说回来 我可能没有使用正确的关键字 有人能指出 javascript eval 可能导致的 安全 问题吗 举个例子 非常好 如果您可以指向具有相同功能的现有网络资源 也可以 Edit 我只需要评
  • MS Access 在传递查询中使用表单

    我有一个名为菲茨 安特 达根 一个名为查询FietsAantDagen和一个名为Txtinput 我正在尝试使用 SQL Server 的直通查询 并使用文本表单的输入作为查询中的输入 Query SELECT Fiets id Fiets
  • 在c++/windows中获取线程状态

    必须有一个函数来获取系统中线程的当前状态 因为有这个应用程序 http www softwareverify com cpp thread status monitor index html 它必须使用某种 API 函数或其他东西 如何在
  • d3嵌套分组条形图

    首先 如果我的英语很难理解 我会尽力的 我对 D3 js 相当陌生 我正在尝试使用嵌套数据创建 D3 分组条形图 我查看了此处共享的一些解决方案 但它们仅显示一级分组 就我而言 数据将来自具有以下数据结构的 csv 文件 groups ca
  • 多次调用 Looper 会导致“向死线程上的处理程序发送消息”

    我使用 Executor 固定线程池 和我自己的 ThreadFactory 添加了 Looper Handler HANDLER new Handler Executor THREADS Executors newFixedThreadP
  • 将 boost::transform_iterator 与非常量函子一起使用

    I want to use a transform iterator to make a delta transformation on a range By delta transformation I mean that r0 shou
  • 你能将 UIImage exif 数据复制到缩放后的 UIImage 中吗?

    我目前正在用户拍照时抓取照片 void imagePickerController UIImagePickerController picker didFinishPickingMediaWithInfo NSDictionary info
  • 升级到 Worklight 6.2

    我在升级到 Worklight 6 2 时遇到问题 请找出下面的错误 ERROR transport error 202 bind failed Address already in use ERROR JDWP Transport dt
  • PHP:将字符串拆分为数组,就像不带分隔符的爆炸一样

    我有一个字符串 例如 0123456789 我需要分开each字符放入数组中 我 为了它 尝试了 explode 123545789 但它给了我明显的信息 警告 爆炸中未定义分隔符 我怎么会遇到这个 我看不到任何方法 尤其是一个函数 arr
  • 在 C# 中生成随机小数

    如何获得随机的 System Decimal System Random不直接支持 编辑 删除旧版本 这与 Daniel 的版本类似 但会给出完整的范围 它还引入了一种新的扩展方法来获取随机的 任何整数 值 我认为这很方便 注意这里小数的分
  • 用于 C++ 的基于行的线程安全 std::cerr

    创建自己的最简单方法是什么std cerr这样它是逐行线程安全的 我最好寻找代码来做到这一点 我需要的是这样a line of output 终止于std endl 由一个线程生成as a line of output当我实际在控制台上看到
  • python3导入语句的变化

    我不明白以下内容pep 0404 在 Python 3 中 包内的隐式相对导入不再 可用 只有绝对导入和显式相对导入 支持的 此外 星号导入 例如 from x import 仅 允许在模块级代码中使用 什么是相对进口 python2中还有
  • C/C++,你可以将文件#include 到字符串中吗? [复制]

    这个问题在这里已经有答案了 我有一个 C 源文件和一个 Python 源文件 我希望 C 源文件能够将 Python 源文件的内容用作大字符串文字 我可以做这样的事情 char python code include script py 但
  • Nestjs:猫鼬中子文档数组的正确模式(没有默认_id或重新定义ObjectId)

    我正在使用 Nest js 并尝试使用包含子文档字段数组的装饰器创建一个架构 我在导入 导出架构并将其转换为模型方面没有任何麻烦 直到 我在我的中收到以下错误service file 经过几个小时的谷歌搜索后 我发现真正的原因是array子
  • 为什么同一文件中的全局符号需要重新定位?

    我有一个用于测试的 C 程序 a c int a 0 static int fa local a 78 int b int c int fa global a 7777 fa local int test a 6666 fa global