GNU ld(链接器)的主要功能

       作用: 链接器linker是Bintutils的一种重要工具,负责将编译后的目标文件(.o)合并成一个可执行文件或者共享库。

一、链接器的文件结构可以概括为以下几个关键部分:

  1. 输入文件 (Input Files): 输入文件通常是目标文件(.o 文件)或共享库(.so 文件),它们包含了已编译的程序代码、数据和其他相关信息。链接器将这些文件合并在一起以创建最终的可执行文件或共享库。

  2. 符号表 (Symbol Table): 符号表是一个数据结构,包含了输入文件中定义的符号(如函数、变量等)以及它们的地址和属性。链接器使用符号表来解析符号之间的关系,以便正确地解决符号引用。

  3. 重定位表 (Relocation Table): 重定位表包含了目标文件中的重定位信息,它告诉链接器在合并文件时如何调整符号的地址。这些信息是在编译时由编译器生成的,以确保程序正确地链接并运行。

  4. 输出文件 (Output File): 输出文件是链接器的结果,它可以是可执行文件、共享库或者其他类型的二进制文件。输出文件包含了输入文件中的代码和数据,以及链接器解析后的符号和重定位信息。

 二、链接器主要任务:

        GNU ld(链接器)是用于将多个目标文件(包括目标文件、共享库、目标文件的归档文件等)合并成一个可执行文件或共享库的重要工具。它的主要功能包括:

  1. 符号解析和重定位:链接器识别并解析输入文件中的符号引用,然后执行重定位操作以确保这些引用指向正确的地址。这包括将模块中的符号引用与其定义进行匹配,以便在合并时连接它们。

  2. 合并输入文件:链接器将多个输入文件中的代码段、数据段等模块合并成一个单一的地址空间。这包括将不同模块中的代码和数据安排到正确的内存地址中。

  3. 生成输出文件:链接器将合并的模块和符号表等信息写入输出文件中,该输出文件可以是可执行文件、共享库、目标文件等,具体类型取决于链接器的参数和配置。

  4. 符号表处理:链接器生成输出文件的符号表,其中包含了可供调试和动态链接器使用的符号信息。

  5. 处理重定位信息:如果存在重定位信息,链接器将生成重定位表,用于在加载时修正代码和数据的地址。这使得程序可以在不同的内存地址上运行。

  6. 处理链接器脚本:链接器可以根据链接器脚本(linker script)中的规则和指令来组织和排列模块,以满足特定需求。链接器脚本可以自定义连接操作的方式。

  7. 共享库支持:链接器可以将多个目标文件合并成共享库(动态链接库),以供其他程序动态链接使用。

  8. 生成调试信息:链接器可以生成调试信息,以支持调试器在程序运行时进行源代码级别的调试。

  9. 解决符号冲突:链接器负责处理不同输入文件之间的符号冲突,以确保所有符号都能正确解析和定位。

  10. 目标文件格式转换:链接器可以将输入文件从一种目标文件格式转换为另一种格式,以支持不同的目标平台。

        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 的作用包括:

  1. 设置默认 BFD 目标:链接器需要了解应该如何处理不同类型和体系结构的二进制文件。通过调用 bfd_set_default_target,可以设置默认的 BFD 目标,该目标通常基于链接器的配置或用户指定的目标。

  2. 确保正确的配置:设置正确的默认目标可确保链接器能够正确地解释和处理不同类型的目标文件。这包括目标文件的格式、字节顺序、体系结构等方面的信息。

  3. 适应多样性:链接器需要适应各种不同的目标文件类型,包括 ELF、COFF、a.out 等,以及不同的体系结构,如 x86、ARM、MIPS 等。通过设置默认 BFD 目标,链接器可以根据需要进行适应,而不需要每次都手动指定目标。

5. ld的初始化

ldemul_before_parse ();  

ldemul_before_parse 函数是GNU Binutils链接器中的一个函数,用于在解析链接器脚本之前执行特定于仿真模式的准备工作。仿真模式是链接器根据目标文件的类型和体系结构来选择的一种配置模式。这个函数通常用于设置特定仿真模式下的链接器行为。

具体来说,ldemul_before_parse 函数的作用包括但不限于:

  1. 针对特定仿真模式的初始化:在某些仿真模式下,可能需要执行特定的初始化步骤,以确保链接器能够正确处理这种模式下的输入文件。

  2. 设置特定模式下的默认行为:一些仿真模式可能需要不同于默认配置的链接器行为。ldemul_before_parse 可能会设置这些特定模式下的默认选项或处理。

  3. 处理模拟模式下的特定逻辑:一些仿真模式可能需要额外的逻辑来处理链接器脚本或其他配置。

总之,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() 用于执行以下操作:

  1. 语法分析:它调用语法分析器,开始解析输入的源代码或源文件。语法分析是编译器前端的一个关键步骤,用于将源代码转换为抽象语法树(AST)或中间表示(IR)等数据结构。

  2. 语法规则匹配yyparse() 通过语法规则来匹配输入的代码,以确定代码的结构和语法是否符合规范。如果发现语法错误,它可能会报告错误或抛出异常。

  3. AST构建:在分析过程中,yyparse() 会构建抽象语法树(AST),这是一个表示源代码结构的树状数据结构。AST对后续的语义分析和代码生成非常重要。

  4. 解释或生成中间代码:一旦语法分析完成,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 函数的主要作用:

  1. 特定仿真模式的配置:不同的仿真模式可能需要不同的配置和行为。ldemul_after_parse 用于设置特定模式下的链接器选项、规则和行为,以确保连接操作能够正确执行。

  2. 链接器脚本的进一步处理:在链接器解析链接器脚本后,某些特定模式可能需要进一步处理脚本内容,以执行特殊操作。例如,某些模式可能需要处理特定的段(sections)分配规则或符号位置规则。

  3. 模拟模式下的特殊逻辑:链接器在不同的仿真模式下可能需要执行不同的逻辑,以确保连接操作适应目标文件类型和体系结构。ldemul_after_parse 允许在特定模式下执行这种特殊逻辑。

        总之,ldemul_after_parse 函数用于在链接器解析链接器脚本之后,根据所选的仿真模式执行特定于模式的配置和操作。这有助于确保链接器能够正确地执行连接操作,以生成可执行文件或共享库,同时适应不同的目标文件类型和体系结构。这是链接器初始化过程中的重要步骤,用于确保正确的链接器行为。

区别和联系

ldemul_before_parseldemul_after_parse 都是GNU Binutils链接器(ld)中的函数,用于在特定仿真模式(emulation mode)下执行特定操作。它们之间的主要区别在于执行的时间点和任务。

  1. ldemul_before_parse

    • 执行时间:ldemul_before_parse 在解析链接器脚本之前执行。
    • 主要任务:它用于在解析链接器脚本之前执行特定于仿真模式的准备工作,通常用于设置模式特定的配置选项,初始化特定于模式的数据结构,以确保链接器能够正确处理该模式下的输入文件。
  2. ldemul_after_parse

    • 执行时间:ldemul_after_parse 在解析链接器脚本之后执行
    • 主要任务:它用于在解析链接器脚本之后执行特定于仿真模式的配置和操作。通常包括配置特定模式下的链接选项、处理特定脚本规则、执行特殊逻辑等,以确保连接操作适应不同的目标文件类型和体系结构。

联系和区别:

  • 联系:两者都用于配置和准备链接器以适应不同的仿真模式。它们都执行特定于模式的操作,以确保链接器正确处理输入文件和链接操作。
  • 区别:主要区别在于执行时间点。ldemul_before_parse 在解析链接器脚本之前执行,而 ldemul_after_parse 在解析链接器脚本之后执行。ldemul_before_parse 主要用于初始化和配置,以便正确解释链接器脚本,而 ldemul_after_parse 主要用于在脚本解析后执行与模式相关的操作。

这两个函数的组合确保了链接器在不同仿真模式下能够正确配置和执行连接操作,以生成适用于特定目标文件类型和体系结构的可执行文件或共享库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/127458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

源码配置nginx,分别编写基于RHEL6、RHEL7的脚本

配置nginx 安装软件 [rootlocalhost ~]# wget https://nginx.org/download/nginx-1.20.2.tar.gz [rootlocalhost ~]# ls 公共 视频 文档 音乐 anaconda-ks.cfg 模板 图片 下载 桌面 nginx-1.20.2.tar.gz创建系统用户 [rootlocalhost ~]# useradd -r -M -s /sbin/nol…

销售人员拒绝CRM系统的原因?如何解决?

尽管如今的CRM客户管理系统已经足够的轻量化,实施起来并不复杂,但还是会被销售团队抱怨,认为CRM系统和他们想象的有很大差距。甚至销售团队根本不理睬新的CRM系统直接拒绝使用。那么,销售人员拒绝CRM系统的原因是什么?…

Midjourney干货篇 - 与AI对话,如何写好prompt

文章目录 1、语法2、单词3、要学习prompt 框架4、善用参数(注意版本)5、善用模版6、临摹7、垫图 木匠不会因为电动工具的出现而被淘汰,反而善用工具的木匠,收入更高了。 想要驾驭好Midjourney,可以从以下方面出发调整&…

基于springboot实现原创歌曲分享平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现原创歌曲分享平台演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理平台应运而生&am…

保护听力戴什么耳机比较好?开放式耳机能保护听力吗?

如果想要在保护听力的前提下戴耳机,那么我是推荐戴骨传导耳机的!!! 所谓骨传导即是一种声音传递的方式,跟普通耳机不同的是传统耳机是通过空气将声音通过耳膜以此完成传递,而骨传导耳机的原理是将声音以不同…

网站如何改成HTTPS访问

在今天的互联网环境中,将网站更改成HTTPS访问已经成为了一种标准做法。HTTPS不仅有助于提高网站的安全性,还可以提高搜索引擎排名,并增强用户信任。因此,转换为HTTPS是一个重要的举措,无论您拥有个人博客、电子商务网站…

面试流程之——程序员如何写项目经验

在简历中介绍IT项目经验,你可以遵循以下步骤: 明确项目目标:首先,清晰地阐述项目的目标。这可以是提升某个软件的性能,改进某个系统的用户界面,或者增加某款产品的功能。让读者了解你的工作与项目的整体目…

Chatgpt批量改写文章网页版可多开软件-自动登录换号生成word或者TXT

Chatgpt批量改写文章网页版可多开软件介绍: 1、改写后生成docx格式文档和生成txt文档二选一。 2、支持原来docx文档里带图片的改写,改写伪原创后的docx里也带图片。 3、软件可以设置是否开启标题改写,可以自定义标题改写指令。 4、可以设置…

创新驱动发展 国家创新型城市试点名单2006-2018年(已整理DID格式)

数据简介:创新型城市是指在经济、科技和社会方面具有卓越创新能力的城市,这些城市通过提供良好的创新环境和支持系统,吸引和培养创新人才,促进新兴产业发展,推动经济增长和社会进步。创新型城市提供了丰富的就业机会和…

YOLOV8 NANO手势识别

采用YOLOV8 NANO训练,得到pt模型,然后转换成ONNX模型,OPENCV DNN调用,支持C,PYTHON,ANDROID开发。CPU每帧20MS左右,可以达到实时性 YOLOV8NANO手势识别

Vue纯CSS实现掷色子

效果图&#xff1a; 实现代码 直接利用CSS3动画实现的效果&#xff0c;无js代码。 <template><div class"wrap"><input type"checkbox" id"roll"><label for"roll"><div class"content"><…

Http代理与socks5代理有何区别?如何选择?(一)

了解SOCKS和HTTP代理之间的区别对于优化您的在线活动至关重要&#xff0c;无论您是技术娴熟的个人、现代互联网用户还是企业所有者。在使用代理IP时&#xff0c;您需要先了解这两种协议之间的不同。 一、了解HTTP代理 HTTP&#xff08;超文本传输协议&#xff09;代理专门设计…

Uni-App 快捷登录

uniapp 实现一键登录前置条件: 开通uniCloud, 开通一键登录功能参考的文档 : 官网 - 一键登录uniapp指南 : https://uniapp.dcloud.net.cn/univerify.html#%E6%A6%82%E8%BF%B0 官网 - 一键登录开通指南 : https://ask.dcloud.net.cn/article/37965 官网 - unicloud使用指南 htt…

基于深度学习的植物识别算法 - cnn opencv python 计算机竞赛

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 MobileNetV2网络4 损失函数softmax 交叉熵4.1 softmax函数4.2 交叉熵损失函数 5 优化器SGD6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的植物识别算法 ** …

投资者如何保障个人利益?行业律师与欧科云链专家给出建议

香港作为全球加速拥抱Web3变革的引领之地&#xff0c;规定自今年6月起在香港经营虚拟资产服务业务需申领牌照。蜂拥而至的Web3创业公司&#xff0c;伺机而动的加密货币交易所&#xff0c;以及跃跃欲试的行业从业者&#xff0c;都让这座金融之都热闹非凡。但近期伴随JPEX诈骗案等…

【案例】3D地球

效果图&#xff1a; 直接放源码 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name"viewport" content"initial-scale1.0, user-scalableno" …

window10 mysql8.0 修改端口port不生效

mysql的默认端口是3306&#xff0c;我想修改成3307。 查了一下资料&#xff0c;基本上都是说先进入C:\Program Files\MySQL\MySQL Server 8.0这个目录。 看看有没有my.ini&#xff0c;没有就新建。 我这里没有&#xff0c;就新建一个&#xff0c;然后修改port&#xff1a; […

云原生相关概念

云计算 指托管在外部数据中心并按使用量付费提供给用户的软件基础设施。公司不必为昂贵的服务器付费并进行维护。相反&#xff0c;他们可以使用云提供商提供的按需云原生服务&#xff0c;例如存储、数据库和分析。 云原生 是在 云计算环境 中构建、部署和管理现代应用程序的…

IMX6ULL——GPIO

本章目的&#xff1a;使用GPIO点亮一个LED灯 1.LED原理 &#xff08;1&#xff09;LED类型&#xff1a;插脚LED&#xff1b;贴片LED。 &#xff08;2&#xff09;LED点亮电路 法一&#xff1a; 法二&#xff1a; 我们本章使用法二&#xff0c;使用IMX6ULL的GPIO引脚输出高低电…