程序的链接和装载(6)--链接过程控制

在特殊场景如内核、BIOS等,需要显式指定程序段地址、链接选项等。本文介绍了通过ld命令行选项和链接脚本来控制链接过程。ld命令提供了多种选项,如'-e'设定程序起始地址,'-o'指定输出文件等。此外,自定义链接脚本提供更灵活的控制,如LdScript.lds文件中定义了输出格式、架构、入口点及段布局。链接脚本中的SECTIONS部分详细指定了各段的起始地址和组合方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    正常情况下,我们使用链接器的默认规则对目标文件进行链接是没问题的。但是在一些特殊的场景,比如操作系统内核,BIOS,嵌入式软件,BootLoader,内核驱动程序下,因为一些受限制的条件,我们需要显示的指明程序的各个段的起始地址,段的名称,段存放的顺序等等。

    而且连接过程中有很多内容需要我们显示的确定,比如该使用哪些目标文件,使用哪些库文件,是否在最终的可执行文件中保留调试信息,输出哪种文件格式(可执行程序还是动态链接库程序)等等。

    因此这些场景下我们需要自己控制链接的过程。控制链接过程的方法有两种:使用ld的命令行选项和使用链接脚本。

    1.ld命令

    ld是GNU提供的链接器,它有许许多多的命令行选项来完成不同的功能配置。例如前文中我们把a.o和b.o链接成可执行文件ab时,命令如下:

    ld a.o b.o -e main -o ab

    这里的-e和-o都是命令行选项,作用如下:

  • '-o  output'  使用output作为链接后输出的可执行程序的名称
  • '-e  entry'   使用符号entry作为程序的起始地址

    除此之外,ld还有很多其他的命令行选项,诸如:

  • '-s'  去除输出文件的所有符号信息
  • '-S'  去除输出文件的所有调试符号信息
  • '-N'  将.text段和.data段设置为可读,同时取消.data段的页对齐,并取消共享库的链接称
  • '--no-omagic'  将.text段设置为只读,强制.data段的页对齐
  • '-T ScriptFile'  使用ScriptFile作为链接器脚本,该脚本会替代连接器的缺省脚本

    ld作为内置在几乎所有类unix操作系统发行版中的链接器,他的功能十分强大,完整的命令行选项和使用方法可以参考GNU手册:ld(1): GNU linker - Linux man page

   2.链接脚本

    除了命令行之外,更灵活的方法是我们自定义链接脚本来替代默认的链接缺省脚本来进行链接处理。例如链接脚本文件LdScript.lds如下所示:

    我们使用刚刚介绍的方法,指定使用该链接脚本作为链接的缺省脚本,命令如下,最终生成了可执行文件ab_Manu。

    ld a.o b.o -T LdScript.lds -o ab_Manu

    我们简单介绍一下LdScript.lds中的每行语句的意思:OUTPUT_FORMAT("elf64-x86-64")表示输出文件的格式为x86平台,64位的Elf64文件格式;OUTPUT_ARCH(i386:x86-64)表示输出文件对应的机器体系结构是x86-64;ENTRY(main)表示使用main函数作为输出程序的程序起始地址;SECTIONS{...}表示定义输出文件的段。

    我们观察SECTIONS{...}内部定义的段,. = SEGMENT_START("text-segment", 0x400000);表示当前的地址为.text段的起始地址,若该段不存在,则当前地址为0x400000;.text : { *(.text) }表示输出文件的.text段由所有输入文件的.text段合并组成;因为当前地址为0x400000,而.text段紧跟在当前地址后面排列,因此可以知道.text段的起始地址为0x400000。同理,我们可知.data段的起始地址为0x600000,.bss段紧跟在.data段后排列; /DISCARD/ : { *(.comment) }表示丢弃所有输入文件的.comment段。

    所以使用readelf查看链接生成的可执行程序ab_Manu,可以发现.text段和.data段的起始地址确实为0x400000和0x600000。

     这里只对ld脚本做了一个简单地介绍,关于ld脚本的详细语法,可以查看ld语法手册Scripts (LD)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值