zoukankan      html  css  js  c++  java
  • 编译链接符号重定位流程简述

    Undefined symbols for architecture x86_64:

    这里是说链接器找不到符号的定义。代码改改就好,但实际上整个编译链接的过程可以了解一下。

    1 void test();
    2 
    3 int main(int argc, char **argv) {
    4     test();
    5     return 0;
    6 }

     编译:

    gcc -c -g a.c

    得到a.o目标文件,看看编译后的代码段:

    objdump -S a.o
     1 a.o:    file format Mach-O 64-bit x86-64
     2 
     3 Disassembly of section __TEXT,__text:
     4 _main:
     5 ; int main(int argc, char **argv) {
     6        0:    55     pushq    %rbp
     7        1:    48 89 e5     movq    %rsp, %rbp
     8        4:    48 83 ec 10     subq    $16, %rsp
     9        8:    c7 45 fc 00 00 00 00     movl    $0, -4(%rbp)
    10        f:    89 7d f8     movl    %edi, -8(%rbp)
    11       12:    48 89 75 f0     movq    %rsi, -16(%rbp)
    12 ; test();
    13       16:    b0 00     movb    $0, %al
    14       18:    e8 00 00 00 00     callq    0 <_main+0x1d>
    15       1d:    31 c0     xorl    %eax, %eax
    16 ; return 0;
    17       1f:    48 83 c4 10     addq    $16, %rsp
    18       23:    5d     popq    %rbp
    19       24:    c3     retq

    可以看到对应test的调用指令为:

    e8 00 00 00 00

    由于a.c里没有对test进行定义,所以编译器只能暂且将test的地址用00 00 00 00来代替,同时将这个需要重定位的地方记录在a.o的重定位表里:

    ➜  ld_test objdump -r a.o
    
    a.o:    file format Mach-O 64-bit x86-64
    
    RELOCATION RECORDS FOR [__text]:
    0000000000000019 X86_64_RELOC_BRANCH _test

    假如说最终链接的时候还是找不到该符号的定义,自然就报最开始那个错误提示了。而如果在另外的模块里有定义这个test,那链接器自然就能以正确的地址替换那个00 00 00 00了。

    对了,这里只说静态链接,动态链接会更复杂一些。

  • 相关阅读:
    centos7&redhat7修改密码
    memcached安裝部署文檔
    cronolog安装部署文檔
    ftp安裝部署文檔
    cacti安裝部署文檔
    php安裝部署文檔
    MYSQL-5.5安装部署文档
    MySQL5.1安裝部署文檔
    nginx進階
    IO进程疏漏
  • 原文地址:https://www.cnblogs.com/madao/p/10706399.html
Copyright © 2011-2022 走看看