ld - the GNU linker

【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 

ld - the GNU linker

1. 链接器的主要作用

  把各个模块(.o 目标文件)之间相互引用的部分处理好, 使得各个模块(.o 目标文件)之间能够正常地衔接, 最终生成可执行程序.

链接器整合的对象是目标文件(*.o), 离开链接器, 目标文件就像无头苍蝇一样无法执行.

目标文件的秘密
  • 各个段没有具体的起始地址, 只有段大小信息;
  • 各个标识符没有实际地址, 只有段中的相对地址;
  • 段与标识符的实际地址需要链接器具体确定.
$nm file.o 
0000000000000000 T func
                 U _GLOBAL_OFFSET_TABLE_
0000000000000013 T main
                 U puts

2. 链接器的工作内容

将目标文件与库文件整合成为最终的可执行程序:

  • 合并各个目标文件中的段(.text .data .bss)
  • 确定各个段和段中标识符的最终地址(重定位)
$nm file
0000000000000830 t atexit
0000000000201010 B __bss_start
0000000000201010 b called.4604
0000000000201014 b completed.7698
                 U __cxa_atexit@@GLIBC_2.2.5
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
00000000000006a0 t deregister_tm_clones
0000000000000690 T _dl_relocate_static_pie
0000000000000730 t __do_global_dtors_aux
0000000000200da8 t __do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200db0 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000849 T etext
0000000000000840 T _fini
0000000000000770 t frame_dummy
0000000000200da0 t __frame_dummy_init_array_entry
0000000000000a1c r __FRAME_END__
000000000000077a T func
0000000000200fa0 d _GLOBAL_OFFSET_TABLE_
0000000000000640 T __gmon_start__
0000000000000858 r __GNU_EH_FRAME_HDR
00000000000005a0 T _init
0000000000200da8 t __init_array_end
0000000000200da0 t __init_array_start
000000000000084c R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000820 T __libc_csu_fini
00000000000007b0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000000793 T main
                 U _mcleanup@@GLIBC_2.2.5
                 U mcount@@GLIBC_2.2.5
                 U __monstartup@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
00000000000006e0 t register_tm_clones
0000000000000610 T _start
0000000000201010 D __TMC_END__

由上述结果可见, func.o的0000000000000000 T func0000000000000013 T main被成功整合到了最终的可执行文件中, 且由相对地址变成了绝对地址(即当程序运行时会被放置的地址): 000000000000077a T func0000000000000793 T main.

3. 结语

在本文章中, 我只想表现出链接器的作用, 而没有告诉大家怎么使用ld命令. 因为我发现, ld命令还真的挺难用的. 举个例子, 还是回到了我们的file,c文件.

$ld file.o 
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
file.o: In function `func':
file.c:(.text+0xc): undefined reference to `puts'

实际上我们的gcc也是调用了ld命令完成了链接操作, 具体的链接参数(链接脚本)可以通过以下方式获得:

$ld --verbose > default.lds

ld命令我没有细看, 毕竟我觉得看太深对自己没有用处, 而且, gcc不香吗?

$gcc file.o -o file
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安河桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值