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中创建一个页面,并使其能够配置各种提示语,可以使用自定义设置、自定义对象或自定义标签等方法来实现。以下是一种常见的方法: 自定义对象或自定义设置:您可以创建一个自定义对象或自定义设置来存储各种提示语的信息。…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
