GNU ld(链接器)的主要功能
作用: 链接器linker是Bintutils的一种重要工具,负责将编译后的目标文件(.o)合并成一个可执行文件或者共享库。
一、链接器的文件结构可以概括为以下几个关键部分:
-
输入文件 (Input Files): 输入文件通常是目标文件(.o 文件)或共享库(.so 文件),它们包含了已编译的程序代码、数据和其他相关信息。链接器将这些文件合并在一起以创建最终的可执行文件或共享库。
-
符号表 (Symbol Table): 符号表是一个数据结构,包含了输入文件中定义的符号(如函数、变量等)以及它们的地址和属性。链接器使用符号表来解析符号之间的关系,以便正确地解决符号引用。
-
重定位表 (Relocation Table): 重定位表包含了目标文件中的重定位信息,它告诉链接器在合并文件时如何调整符号的地址。这些信息是在编译时由编译器生成的,以确保程序正确地链接并运行。
-
输出文件 (Output File): 输出文件是链接器的结果,它可以是可执行文件、共享库或者其他类型的二进制文件。输出文件包含了输入文件中的代码和数据,以及链接器解析后的符号和重定位信息。
二、链接器主要任务:
GNU ld(链接器)是用于将多个目标文件(包括目标文件、共享库、目标文件的归档文件等)合并成一个可执行文件或共享库的重要工具。它的主要功能包括:
-
符号解析和重定位:链接器识别并解析输入文件中的符号引用,然后执行重定位操作以确保这些引用指向正确的地址。这包括将模块中的符号引用与其定义进行匹配,以便在合并时连接它们。
-
合并输入文件:链接器将多个输入文件中的代码段、数据段等模块合并成一个单一的地址空间。这包括将不同模块中的代码和数据安排到正确的内存地址中。
-
生成输出文件:链接器将合并的模块和符号表等信息写入输出文件中,该输出文件可以是可执行文件、共享库、目标文件等,具体类型取决于链接器的参数和配置。
-
符号表处理:链接器生成输出文件的符号表,其中包含了可供调试和动态链接器使用的符号信息。
-
处理重定位信息:如果存在重定位信息,链接器将生成重定位表,用于在加载时修正代码和数据的地址。这使得程序可以在不同的内存地址上运行。
-
处理链接器脚本:链接器可以根据链接器脚本(linker script)中的规则和指令来组织和排列模块,以满足特定需求。链接器脚本可以自定义连接操作的方式。
-
共享库支持:链接器可以将多个目标文件合并成共享库(动态链接库),以供其他程序动态链接使用。
-
生成调试信息:链接器可以生成调试信息,以支持调试器在程序运行时进行源代码级别的调试。
-
解决符号冲突:链接器负责处理不同输入文件之间的符号冲突,以确保所有符号都能正确解析和定位。
-
目标文件格式转换:链接器可以将输入文件从一种目标文件格式转换为另一种格式,以支持不同的目标平台。
GNU ld是编译工具链的一部分,它的主要任务是将源代码和目标文件合并为可执行的、可部署的程序或库。它是将软件编译成可执行程序的关键组件之一,同时也支持许多高级功能,如动态链接、共享库创建等。
三、简单介绍ldmain.c的一些函数
1. 整个链接器的入口main函数
int
main (int argc, char **argv) // 主程序入口
{char *emulation;long start_time = get_run_time ();
#ifdef HAVE_SBRKchar *start_sbrk = (char *) sbrk (0);
#endif
2. 处理命令行参数
expandargv (&argc, &argv);
expandargv(&argc, &argv)
主要用于处理命令行参数中的通配符,将通配符展开为实际文件名,并将它们添加到 argv
数组中。这有助于链接器识别实际要处理的文件。通常在链接器的早期阶段执行,以确保命令行参数的正确处理。
3. 初始化BFD库,BFD库用于处理二进制文件格式。
bfd_init (); // bfd_init():
bfd_init()
的主要目的是为 Binutils 链接器(ld
)的运行做准备,确保 BFD库正确配置,并能够处理各种不同的二进制文件格式,以进行链接和生成目标文件。它是 Binutils 中的一个重要初始化步骤,使链接器能够有效地操作不同类型的二进制文件。
4. bfd_set_default_target
是用于设置链接器的默认 BFD 目标
bfd_set_default_target (TARGET)
具体来说,bfd_set_default_target
的作用包括:
-
设置默认 BFD 目标:链接器需要了解应该如何处理不同类型和体系结构的二进制文件。通过调用
bfd_set_default_target
,可以设置默认的 BFD 目标,该目标通常基于链接器的配置或用户指定的目标。 -
确保正确的配置:设置正确的默认目标可确保链接器能够正确地解释和处理不同类型的目标文件。这包括目标文件的格式、字节顺序、体系结构等方面的信息。
-
适应多样性:链接器需要适应各种不同的目标文件类型,包括 ELF、COFF、a.out 等,以及不同的体系结构,如 x86、ARM、MIPS 等。通过设置默认 BFD 目标,链接器可以根据需要进行适应,而不需要每次都手动指定目标。
5. ld的初始化
ldemul_before_parse ();
ldemul_before_parse
函数是GNU Binutils链接器中的一个函数,用于在解析链接器脚本之前执行特定于仿真模式的准备工作。仿真模式是链接器根据目标文件的类型和体系结构来选择的一种配置模式。这个函数通常用于设置特定仿真模式下的链接器行为。
具体来说,ldemul_before_parse
函数的作用包括但不限于:
针对特定仿真模式的初始化:在某些仿真模式下,可能需要执行特定的初始化步骤,以确保链接器能够正确处理这种模式下的输入文件。
设置特定模式下的默认行为:一些仿真模式可能需要不同于默认配置的链接器行为。
ldemul_before_parse
可能会设置这些特定模式下的默认选项或处理。处理模拟模式下的特定逻辑:一些仿真模式可能需要额外的逻辑来处理链接器脚本或其他配置。
总之,ldemul_before_parse
函数用于在链接器开始解析链接器脚本之前,根据所选的仿真模式执行与特定模式相关的准备工作。这有助于确保链接器能够正确地处理输入文件和执行链接操作。这个函数在链接器的初始化过程中非常重要,以确保链接器适应不同的仿真模式和配置。
下是一些常见的仿真模式示例:
ELF仿真模式 | ELF(Executable and Linkable Format)是一种通用的可执行文件格式,通常用于Linux系统。ELF仿真模式用于处理与ELF格式相关的目标文件,例如可执行文件和共享库。 |
a.out仿真模式 | a.out是早期UNIX系统中使用的一种可执行文件格式。a.out仿真模式用于处理a.out格式的目标文件。 |
COFF仿真模式 | COFF(Common Object File Format)是一种用于Windows和其他系统的可执行文件格式。COFF仿真模式用于处理COFF格式的目标文件。 |
Mach-O仿真模式 | Mach-O是用于macOS系统的可执行文件格式。Mach-O仿真模式用于处理Mach-O格式的目标文件。 |
PE仿真模式 | PE(Portable Executable)是一种用于Windows系统的可执行文件格式。PE仿真模式用于处理PE格式的目标文件。 |
Hex仿真模式 | Hex仿真模式用于处理十六进制文件,这种文件格式包含以十六进制编码的二进制数据。 |
SREC仿真模式 | SREC仿真模式用于处理S-Record文件格式,这是一种通用的二进制文件格式,通常用于嵌入式系统。 |
Tekhex仿真模式 | Tekhex仿真模式用于处理Tektronix HEX文件格式,这是一种包含以十进制编码的二进制数据的文件格式。 |
每个仿真模式都定义了一组规则和配置,以确保链接器能够正确地处理特定类型的目标文件。通过选择适当的仿真模式,链接器可以了解目标文件的格式和要求,并正确执行链接操作,包括符号解析、重定位和生成可执行文件或共享库。这有助于确保不同类型的目标文件可以在同一个链接过程中正确地结合在一起。
6.命令行参数解析
parse_args()
parse_args(argc, argv)
主要用于解析已展开的命令行参数。它负责解释用户提供的各种选项和参数,以确定链接器的配置和操作方式。这个函数在链接器初始化的稍后阶段执行,它依赖于 expandargv
的输出,以正确解释和处理用户提供的信息
7. 链接脚本词法语法分析
yyparser()
yyparse()
是与语法分析器生成器(如Yacc/Bison)生成的语法分析器相关的函数。它通常在编译器、解释器、链接器等工具中的语法分析阶段使用。
具体来说,yyparse()
用于执行以下操作:
-
语法分析:它调用语法分析器,开始解析输入的源代码或源文件。语法分析是编译器前端的一个关键步骤,用于将源代码转换为抽象语法树(AST)或中间表示(IR)等数据结构。
-
语法规则匹配:
yyparse()
通过语法规则来匹配输入的代码,以确定代码的结构和语法是否符合规范。如果发现语法错误,它可能会报告错误或抛出异常。 -
AST构建:在分析过程中,
yyparse()
会构建抽象语法树(AST),这是一个表示源代码结构的树状数据结构。AST对后续的语义分析和代码生成非常重要。 -
解释或生成中间代码:一旦语法分析完成,
yyparse()
可能会将源代码翻译成中间表示或执行代码生成。这取决于编译器或工具的具体需求。
yyparse()
通常与词法分析器(如Lex/Flex)一起使用,词法分析器负责将源代码分割成标记(tokens),然后 yyparse()
利用这些标记来构建语法树。
需要注意的是,yyparse()
是由语法分析器生成器生成的,通常与特定的语法规则文件一起使用。它实际上是一个无限循环,不断读取输入,分析语法,生成语法树,并执行相关操作,直到达到输入的结尾或发现语法错误。在编译器和解释器的设计中,yyparse()
扮演了一个非常重要的角色,确保源代码被正确分析和处理。
8. 获取链接脚本
ldemul_get_script (&isfile)
链接器脚本是一种特殊的配置文件,它定义了链接器在连接目标文件时的行为。这些脚本可以包含指令和规则,用于定义符号的位置、如何分配内存、如何将节(sections)映射到输出文件等。不同的目标文件类型和体系结构可能需要不同的链接器脚本,因此链接器需要了解所处的仿真模式以获取适当的链接器脚本。
ldemul_get_script
函数的主要目的是返回当前仿真模式下应使用的链接器脚本的内容或文件路径。它可能会返回链接器脚本的文本内容,也可能返回脚本文件的路径,取决于具体的实现。链接器在初始化过程中需要加载和解释链接器脚本,以根据目标文件的类型和体系结构进行正确的连接。
这个函数通常在链接器初始化的早期阶段被调用,以获取默认的链接器脚本。链接器可以根据仿真模式来选择不同的链接器脚本,确保在不同情况下使用正确的配置。这有助于链接器正确地执行连接操作,以生成可执行文件或共享库。
9.设置特定模式下的链接器选项、规则和行为,以确保连接操作能够正确执行。
ldemul_after_parse ();
ldemul_after_parse
函数是 GNU Binutils 链接器(ld)中的一个函数,它通常在链接器解析链接器脚本(linker script)之后执行。该函数用于执行仿真模式(emulation mode)特定的操作,以确保链接器根据所选的仿真模式正确配置和执行连接操作。
以下是 ldemul_after_parse
函数的主要作用:
-
特定仿真模式的配置:不同的仿真模式可能需要不同的配置和行为。
ldemul_after_parse
用于设置特定模式下的链接器选项、规则和行为,以确保连接操作能够正确执行。 -
链接器脚本的进一步处理:在链接器解析链接器脚本后,某些特定模式可能需要进一步处理脚本内容,以执行特殊操作。例如,某些模式可能需要处理特定的段(sections)分配规则或符号位置规则。
-
模拟模式下的特殊逻辑:链接器在不同的仿真模式下可能需要执行不同的逻辑,以确保连接操作适应目标文件类型和体系结构。
ldemul_after_parse
允许在特定模式下执行这种特殊逻辑。
总之,ldemul_after_parse
函数用于在链接器解析链接器脚本之后,根据所选的仿真模式执行特定于模式的配置和操作。这有助于确保链接器能够正确地执行连接操作,以生成可执行文件或共享库,同时适应不同的目标文件类型和体系结构。这是链接器初始化过程中的重要步骤,用于确保正确的链接器行为。
区别和联系
ldemul_before_parse
和 ldemul_after_parse
都是GNU Binutils链接器(ld)中的函数,用于在特定仿真模式(emulation mode)下执行特定操作。它们之间的主要区别在于执行的时间点和任务。
-
ldemul_before_parse:
- 执行时间:
ldemul_before_parse
在解析链接器脚本之前执行。 - 主要任务:它用于在解析链接器脚本之前执行特定于仿真模式的准备工作,通常用于设置模式特定的配置选项,初始化特定于模式的数据结构,以确保链接器能够正确处理该模式下的输入文件。
- 执行时间:
-
ldemul_after_parse:
- 执行时间:
ldemul_after_parse
在解析链接器脚本之后执行。 - 主要任务:它用于在解析链接器脚本之后执行特定于仿真模式的配置和操作。通常包括配置特定模式下的链接选项、处理特定脚本规则、执行特殊逻辑等,以确保连接操作适应不同的目标文件类型和体系结构。
- 执行时间:
联系和区别:
- 联系:两者都用于配置和准备链接器以适应不同的仿真模式。它们都执行特定于模式的操作,以确保链接器正确处理输入文件和链接操作。
- 区别:主要区别在于执行时间点。
ldemul_before_parse
在解析链接器脚本之前执行,而ldemul_after_parse
在解析链接器脚本之后执行。ldemul_before_parse
主要用于初始化和配置,以便正确解释链接器脚本,而ldemul_after_parse
主要用于在脚本解析后执行与模式相关的操作。
这两个函数的组合确保了链接器在不同仿真模式下能够正确配置和执行连接操作,以生成适用于特定目标文件类型和体系结构的可执行文件或共享库
相关文章:

GNU ld(链接器)的主要功能
作用: 链接器linker是Bintutils的一种重要工具,负责将编译后的目标文件(.o)合并成一个可执行文件或者共享库。 一、链接器的文件结构可以概括为以下几个关键部分: 输入文件 (Input Files): 输入文件通常是目标文件(.o 文件&#…...

springboot整合FTP实现文件传输
实现ftp文件传输的步骤: 1.ftp绑定ip端口登录 2.切换到指定地址 3.文件下载 4.关闭ftp连接 项目中使用的jar包 <!-- ftp包--><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><vers…...

Spring Boot 2.x.x 升级至 Spring Boot 3.x.x
小伙伴们,你们好呀,好久不见,我是老寇,跟我一起升级Spring Boot版本 一、JDK 版本 JDK8 需要升级至 JDK17 二、Spring Boot 版本 Spring Boot 2.x.x 升级至 Spring Boot 3.x.x 三、Java Api 变更 javax 变更成 jakarta 四、…...

光电直读水表支持短时间多次抄表吗
传统的水表读数方式已经逐渐无法满足人们对于便捷、准确的需求。为此,光电直读水表应运而生,它凭借出色的读数性能和稳定的准确性,赢得了广大用户的一致好评。那么,光电直读水表支持短时间多次抄表吗?答案是肯定的&…...

家庭私人影院 - Windows搭建Emby媒体库服务器并远程访问 「无公网IP」
文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中,观看视频绝对是主力应用场景之一&…...

核心舱在轨飞行VR沉浸式互动体验满足大家宇宙探险的心愿
近日神州十七号载人飞船迎来发射,随着我国载人航天工程进入空间站应用与发展阶段,在轨航天探索和运维工作进入常态化阶段,然而每次出征都牵动着亿万人民的心,对航天航空的好奇和向往也越来越强烈。为了让普通人也能体验乘坐飞船上…...

k8s集群中namespace状态一直显示Terminating
一、问题现象 今天在做测试时,在一个namespace下无法启动pod,查看ns状态一直显示Terminating [rootnode1 ~]# kubectl get ns NAME STATUS AGE configmap Terminating 135d default Active …...

数据库高速缓存配置
数据库一般都配置数据高速缓存,并且可以高速缓存中按页大小分不同的缓冲池。 Oracle: db_cache_size是指db_block_size对应的缓冲池,也可以指定非db_block_size的缓冲池,一般也都会再配置一个32K的缓冲池,两个缓冲池加…...

性能优化之懒加载 - 基于观察者模式和单例模式的实现
一、引入 在前端性能优化中,关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时,才去请求加载对应的图像。 原理也很简单,通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org),…...

【LeetCode刷题-链表】--1290.二进制链表转整数
1290.二进制链表转整数 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }*…...

搭建Radius认证服务器 安当加密
搭建Radius认证服务器需要完成以下步骤: 安装Radius服务器软件。可以选择使用FreeRadius、Radiusd或WinRadius等开源软件,也可以选择使用商业软件如Cisco或安当ASP等。配置认证数据库。在Radius服务器上配置认证数据库,用于存储用户信息和认…...

Windows11恢复组策略编辑器功能的方法
原因分析 日常工作学习中,对 Windows 计算机上的问题进行故障排除时,有些高级用户经常使用组策略编辑器轻松修复它。通过其分层结构,您可以快速调整应用于用户或计算机的设置。如果搜索结果中缺少组策略编辑器,则可能必须使用注册表编辑器作为疑难解答工具,这是一种更复杂…...

Django实战项目-学习任务系统-查询列表分页显示
接着上期代码框架,6个主要功能基本实现,剩下的就是细节点的完善优化了。 接着优化查询列表分页显示功能,有很多菜单功能都有查询列表显示页面情况,如果数据量多,不分页显示的话,页面展示效果就不太好。 本…...

Git 拉取指定TAG/分支的代码
像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)。 1.创建 tag 标签 $ git tag <tagname&…...

2-爬虫-代理池搭建、代理池使用(搭建django后端测试)、爬取某视频网站、爬取某视频网站、bs4介绍和遍历文档树
1 代理池搭建 2 代理池使用 2.1 搭建django后端测试 3 爬取某视频网站 4爬取某视频网站 5 bs4介绍和遍历文档树 1 代理池搭建 # ip代理-每个设备都会有自己的IP地址-电脑有ip地址---》访问一个网站---》访问太频繁---》封ip-收费:靠谱稳定--提供api-免费ÿ…...

动手学深度学习——残差网络ResNet(原理解释+代码详解)
残差网络ResNet 1. 函数类2. 残差块3. ResNet模型4. 训练模型 ResNet为了解决“新添加的层如何提升神经网络的性能”,它在2015年的ImageNet图像识别挑战赛夺魁 它深刻影响了后来的深度神经网络的设计,ResNet的被引用量更是达到了19万。 1. 函数类 假…...

MYSQL 8.0 配置CDC(binlog)
CDC(Change Data Capture)即数据变更抓取,通过源端数据源开启CDC,ROMA Connect 可实现数据源的实时数据同步以及物理表的物理删除同步。这里介绍通过开启Binlog模式CDC功能。 注意:1、使用MYSQL8.0及以上版本。 2、不…...

软件测试/测试开发丨ChatGPT能否成为PPT最佳伴侣
点此获取更多相关资料 简介 PPT 已经渗透到我们的日常工作中,无论是工作汇报、商务报告、学术演讲、培训材料都常常要求编写一个正式的 PPT,协助完成一次汇报或一次演讲。PPT相比于传统文本的就是有布局、图片、动画效果等,可以给到观众更好…...

java对象的创建过程
一.类的加载与检查 当我们new了一个对象的时候,首先会去检查一下这个指令是否在常量池中存在符号引用,并且检查这个符号引用代表的对象是否被加载,解析初始化过,如果没有就要先去进行类加载过程 二.分配内存 我们通过第一步的检…...

Salesforce创建一个页面,能够配置各种提示语,而不需要修改代码
在Salesforce中创建一个页面,并使其能够配置各种提示语,可以使用自定义设置、自定义对象或自定义标签等方法来实现。以下是一种常见的方法: 自定义对象或自定义设置:您可以创建一个自定义对象或自定义设置来存储各种提示语的信息。…...

轻松管理MySQL权限:Python脚本带你飞
数据库管理是 IT 专家和开发者日常工作中的重要组成部分。一个合适的用户权限管理系统不仅确保了数据的安全性,还能确保数据能够按照预期的方式被正确地访问和修改。在本文中,我们将探讨如何使用 Python 脚本来管理和查询 MySQL 数据库中的用户权限。 用户权限管理:创建或修…...

Py之transformers_stream_generator:transformers_stream_generator的简介、安装、使用方法之详细攻略
Py之transformers_stream_generator:transformers_stream_generator的简介、安装、使用方法之详细攻略 目录 transformers_stream_generator的简介 1、Web Demo T1、original T2、stream transformers_stream_generator的安装 transformers_stream_generator的…...

2023年Zotero最新同步教程-使用TeraCloud的25G免费空间实时跨设备同步文献
文章目录 1. 前言2.1. 注册账号2.1.1. 填写注册信息2.1.2. 创建账号成功2.1.3. 注意2.2. 扩容空间2.3. 打开WebDAV 3. Zotero配置WebDAV同步3.1. 设置网址3.2. 验证服务器3.3. 文件同步成功 4. 结语 1. 前言 Zotero免费版的存储空间是300m,一个图文PDF动辄两三M&am…...

面试题:用宏定义写出swap(x,y),即交换两数。
鼠标选中查看答案↓: #define swap(x,y) do{(x)(x)(y);(y)(x)-(y);(x)(x)-(y);}while(0) 这个题考查宏定义的语法,尤其是多行代码的宏定义,加上do{}while(),,可以保证这些语句只执行一次。...

微服务框架SpringcloudAlibaba+Nacos集成RabbitMQ
目前公司使用jeepluscloud版本,这个版本没有集成消息队列,这里记录一下,集成的过程;这个框架跟ruoyi的那个微服务版本结构一模一样,所以也可以快速上手。 1.项目结构图: 配置类的东西做成一个公共的模块 …...

低代码开发,一场深度的IT效率革命
目录 一、前言 二、低代码迅速流行的理由 三、稳定性和生产率的最佳实践 四、程序员用低代码开发应用有哪些益处? 1、提升开发价值 2、利于团队升级 五、总结 一、前言 尽管IT技术支撑了全球的信息化浪潮,然而困扰行业已久的软件开发效率并未像摩尔定律那…...
虚拟串口软件使用介绍
对于上位机开发来说(特别是串口通信应用),上机位软件的调试尤为重要,但是上机位软件的调试并不关心硬件,只需要关注验证发送的数据帧的接收情况,为了便于调试,可以将上机位软件与串口软件互通,实现数据的交互,但由于互通需要串口,可以借助串口虚拟软件(VSPD),虚拟出…...

如何编写一份完整的软件测试报告?(进阶版)百分之90不知道
背景 作为测试从业者,编写测试用例,测试计划,测试报告都是必经之路,最近完成了年终述职以及版本准出,感觉测试报告或者各类报告真是职场人不可或缺的一项技能,趁着热乎劲🔥,写下一些…...

python企业微信小程序发送信息
python企业微信小程序发送信息 在使用下面代码之前先配置webhook 教程如下: https://www.bilibili.com/video/BV1oH4y1S7pN/?vd_sourcebee29ac3f59b719e046019f637738769 然后使用如下代码就可以发消息了: 代码如下: #codinggbk import r…...

Java入门篇 之 逻辑控制(练习题篇)
博主碎碎念: 练习题是需要大家自己打的请在自己尝试后再看答案哦; 个人认为,只要自己努力在将来的某一天一定会看到回报,在看这篇博客的你,不就是在努力吗,所以啊,不要放弃,路上必定坎坷&#x…...