当前位置: 首页 > news >正文

GNU ld链接器 lang_process()(二)

一、ldemul_create_output_section_statements()

位于lang_process()中11行  。  该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。

void
ldemul_create_output_section_statements (void)
{if (ld_emulation->create_output_section_statements)ld_emulation->create_output_section_statements ();
}
static ld_emulation_xfer_type *ld_emulation;
  /* Create any output sections needed by the target.  */void	(*create_output_section_statements) (void);  // 14
typedef struct ld_emulation_xfer_struct {/* Run before parsing the command line and script file.Set the architecture, maybe other things.  */void   (*before_parse) (void); // 1/* Handle the SYSLIB (low level library) script command.  */void   (*syslib) (char *);  // 2/* Handle the HLL (high level library) script command.  */void   (*hll) (char *);  // 3/* Run after parsing the command line and script file.  */void   (*after_parse) (void);  // 4/* Run after opening all input files, and loading the symbols.  */void   (*after_open) (void);  // 5/* Run after allocating output sections.  */void   (*after_allocation)  (void);  // 6/* Set the output architecture and machine if possible.  */void   (*set_output_arch) (void);  // 7/* Decide which target name to use.  */char * (*choose_target) (int, char**);  // 8/* Run before allocating output sections.  */void   (*before_allocation) (void);  // 9/* Return the appropriate linker script.  */char * (*get_script) (int *isfile);  // 10/* The name of this emulation.  */char *emulation_name;  // 11/* The output format.  */char *target_name;  // 12/* Run after assigning values from the script.  */void	(*finish) (void);  // 13/* Create any output sections needed by the target.  */void	(*create_output_section_statements) (void);  // 14/* Try to open a dynamic library.  ARCH is an architecture name, andis normally the empty string.  ENTRY is the lang_input_statementthat should be opened.  */bfd_boolean (*open_dynamic_archive)(const char *arch, struct search_dirs *,struct lang_input_statement_struct *entry);  // 15/* Place an orphan section.  Return TRUE if it was placed, FALSE ifthe default action should be taken.  This field may be NULL, inwhich case the default action will always be taken.  */lang_output_section_statement_type *(*place_orphan)(asection *, const char *, int);  // 16/* Run after assigning parsing with the args, but beforereading the script.  Used to initialize symbols used in the script.  */void	(*set_symbols) (void);  // 17/* Parse args which the base linker doesn't understand.Return TRUE if the arg needs no further processing.  */bfd_boolean (*parse_args) (int, char **);  // 18/* Hook to add options to parameters passed by the base linker togetopt_long and getopt_long_only calls.  */void (*add_options)(int, char **, int, struct option **, int, struct option **);  // 19/* Companion to the above to handle an option.  Returns TRUE if it isone of our options.  */bfd_boolean (*handle_option) (int);  // 20/* Run to handle files which are not recognized as object files orarchives.  Return TRUE if the file was handled.  */bfd_boolean (*unrecognized_file)(struct lang_input_statement_struct *);  // 21/* Run to list the command line options which parse_args handles.  */void (* list_options) (FILE *);  // 22/* Run to specially handle files which *are* recognized as objectfiles or archives.  Return TRUE if the file was handled.  */bfd_boolean (*recognized_file)(struct lang_input_statement_struct *);  // 23/* Called when looking for libraries in a directory specifiedvia a linker command line option or linker script option.Files that match the pattern "lib*.a" have already been scanned.(For VMS files matching ":lib*.a" have also been scanned).  */int (* find_potential_libraries)(char *, struct lang_input_statement_struct *);  // 24/* Called when adding a new version pattern.  PowerPC64-ELF usesthis hook to add a pattern matching ".foo" for every "foo".  */struct bfd_elf_version_expr * (*new_vers_pattern)(struct bfd_elf_version_expr *);  // 25/* Called when printing the map file, in case there areemulation-specific sections for it.  */void (*extra_map_file_text)(bfd *, struct bfd_link_info *, FILE *);  // 26} ld_emulation_xfer_type;

二、lang_place_undefineds ()

 将命令行中所有未定义的符号加入哈希表中

结构体类型:

struct bfd_sym_chain

  • 这是一个结构体定义,表示符号链的链接列表节点。每个节点包含指向下一个节点的指针和指向字符字符串的指针(可能是符号名称)。
  • typedef struct bfd_sym_chain ldlang_undef_chain_list_type

  • 这行代码为struct bfd_sym_chain创建了类型别名ldlang_undef_chain_list_type,以便更容易使用和声明这种类型的变量。
  • #define ldlang_undef_chain_list_head entry_symbol.next

  • 这似乎是一个预处理器宏,将ldlang_undef_chain_list_head定义为entry_symbol.next。它可能用作访问符号链节点的next字段的简写。
struct bfd_sym_chain
{struct bfd_sym_chain *next;const char *name;
};typedef struct bfd_sym_chain ldlang_undef_chain_list_type;#define ldlang_undef_chain_list_head entry_symbol.next
函数: 

static void lang_place_undefineds(void)

  • 这是一个函数定义的开始,名为lang_place_undefineds。它是一个静态函数,意味着它仅限于当前的翻译单元。这个函数的目的是遍历未定义符号(ldlang_undef_chain_list_type)的列表,并为每个符号的名称调用insert_undefined
static void
lang_place_undefineds (void)
//   /* Add to the hash table all undefineds on the command line.  */
{ldlang_undef_chain_list_type *ptr;for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next)insert_undefined (ptr->name);
}

static void insert_undefined(const char *name)

  • 这是另一个静态函数定义,名为insert_undefined。它以字符串(name)作为参数。这个函数的目的是将未定义符号插入符号表中。它首先使用bfd_link_hash_lookup在哈希表中查找符号,如果找不到,则使用bfd_link_add_undef添加它。

 

/* Insert NAME as undefined in the symbol table.  */static void
insert_undefined (const char *name)
{struct bfd_link_hash_entry *h;h = bfd_link_hash_lookup (link_info.hash, name, TRUE, FALSE, TRUE);if (h == NULL)einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));if (h->type == bfd_link_hash_new){h->type = bfd_link_hash_undefined;h->u.undef.abfd = NULL;bfd_link_add_undef (link_info.hash, h);}
}

bfd_link_hash_lookupbfd_hash_lookup函数:

  • 这些函数用于在哈希表中查找条目。bfd_link_hash_lookup似乎用于在符号哈希表中查找条目,而bfd_hash_lookup是一个更一般的哈希表查找函数。这些函数通过对输入字符串进行哈希并在哈希表中搜索相应的条目来工作。
  • bfd_hash_insert函数:

  • 此函数用于将新条目插入哈希表。它为条目分配内存,计算哈希值,并将条目插入哈希表的适当位置。如果需要,它还处理表的大小调整。
struct bfd_link_hash_entry *
bfd_link_hash_lookup (struct bfd_link_hash_table *table,const char *string,bfd_boolean create,  // Tbfd_boolean copy,  // Fbfd_boolean follow)  // T
{struct bfd_link_hash_entry *ret;ret = ((struct bfd_link_hash_entry *)bfd_hash_lookup (&table->table, string, create, copy));if (follow && ret != NULL){while (ret->type == bfd_link_hash_indirect|| ret->type == bfd_link_hash_warning)ret = ret->u.i.link;}return ret;
}
struct bfd_hash_entry *
bfd_hash_lookup (struct bfd_hash_table *table,const char *string,bfd_boolean create,  // Tbfd_boolean copy)  // F
{unsigned long hash;struct bfd_hash_entry *hashp;unsigned int len;unsigned int _index;hash = bfd_hash_hash (string, &len);_index = hash % table->size;for (hashp = table->table[_index];hashp != NULL;hashp = hashp->next){if (hashp->hash == hash&& strcmp (hashp->string, string) == 0)return hashp;}if (! create)return NULL;if (copy){char *new_string;new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory,len + 1);if (!new_string){bfd_set_error (bfd_error_no_memory);return NULL;}memcpy (new_string, string, len + 1);string = new_string;}return bfd_hash_insert (table, string, hash);
}
struct bfd_hash_entry *
bfd_hash_insert (struct bfd_hash_table *table,const char *string,unsigned long hash)
{struct bfd_hash_entry *hashp;unsigned int _index;hashp = (*table->newfunc) (NULL, table, string);if (hashp == NULL)return NULL;hashp->string = string;hashp->hash = hash;_index = hash % table->size;hashp->next = table->table[_index];table->table[_index] = hashp;table->count++;if (!table->frozen && table->count > table->size * 3 / 4){unsigned long newsize = higher_prime_number (table->size);struct bfd_hash_entry **newtable;unsigned int hi;unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *);/* If we can't find a higher prime, or we can't possibly allocthat much memory, don't try to grow the table.  */if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize){table->frozen = 1;return hashp;}newtable = ((struct bfd_hash_entry **)objalloc_alloc ((struct objalloc *) table->memory, alloc));if (newtable == NULL){table->frozen = 1;return hashp;}memset (newtable, 0, alloc);for (hi = 0; hi < table->size; hi ++)while (table->table[hi]){struct bfd_hash_entry *chain = table->table[hi];struct bfd_hash_entry *chain_end = chain;while (chain_end->next && chain_end->next->hash == chain->hash)chain_end = chain_end->next;table->table[hi] = chain_end->next;_index = chain->hash % newsize;chain_end->next = newtable[_index];newtable[_index] = chain;}table->table = newtable;table->size = newsize;}return hashp;
}

相关文章:

GNU ld链接器 lang_process()(二)

一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…...

《国产服务器操作系统发展报告(2023)》重磅发布

11月1日&#xff0c;《国产服务器操作系统发展报告&#xff08;2023&#xff09;》&#xff08;以下简称“报告”&#xff09;在 2023 云栖大会上正式发布&#xff0c;开放原子开源基金会理事长孙文龙、中国信息通信研究院副总工程师石友康、阿里云基础软件部副总裁马涛、浪潮信…...

【PTE-day03 报错注入】

报错注入 1、报错注入 group by count2、报错注入 extractvalue3、报错注入updatexml1、报错注入 group by count http://124.222.124.9:8888/Less-5/?id=-1 union select 1,count(*),concat((select database()),ceil(rand(0)*2)) as a from information_schema.tables grou…...

jenkins gitlab CI/CD

jenkins的安装教程就不说了&#xff1a;Jenkins docker 一键发布 (一)_jenkins 一键发布-CSDN博客 最近打算从svn切换到gitlab&#xff0c;所以配置了一下jenkins的git 很简单&#xff0c;直接上图 1 选择 Git 2 录入gitlab的http地址&#xff08;由于我的git地址不是22端口&…...

Java 中的数据类型有哪些?

Java中主要有八种基本数据类型&#xff1a; 1、整型&#xff1a;byte、short、int、long 2、字符型&#xff1a;char 3、浮点型&#xff1a;float、double 4、布尔型&#xff1a;boolean 一、整型 Java中整型数据属于有符号数&#xff0c;即第一个bit位为0表示正整数&…...

基于SSM的大学学生成长系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…...

369B1860G0028 44A730240-G01 IC697ACC722B

369B1860G0028 44A730240-G01 IC697ACC722B 在NOA&#xff0c;一个名为MO(监控和优化)的独立领域与现有系统分开准备&#xff0c;数据直接从机器人、无人机和新传感器收集&#xff0c;例如腐蚀、声音和振动传感器。此外&#xff0c;现有系统中的数据通过OPC UA导入&#xff0c…...

系列十一、拦截器(二)#案例演示

一、案例演示 说明&#xff1a;如下案例通过springboot的方式演示拦截器是如何使用的&#xff0c;以获取Controller中的请求参数为切入点进行演示 1.1、前置准备工作 1.1.1、pom <dependencies><!-- spring-boot --><dependency><groupId>org.spring…...

数据分析实战 | 关联规则分析——购物车分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据预处理 七、生成频繁项集 八、计算关联度 九、可视化 一、数据及分析对象 数据集链接&#xff1a;Online Retail.xlsx 该数据集记录了2010年12月01日至2011年12月09日…...

maven 添加 checkstyle 插件约束代码规范

本例示例&#xff0c;是引用 http 链接这种在线 checkstyle.xml 文件的配置方式&#xff0c;如下示例&#xff1a; <properties><maven.checkstyle.plugin.version>3.3.0</maven.checkstyle.plugin.version><!--支持本地绝对路径、本地相对路径、HTTP远程…...

什么是MySQL的执行计划(Explain关键字)?

什么是Explain Explain被称为执行计划&#xff0c;在语句之前增加 explain 关键字&#xff0c;MySQL 会在查询上设置一个标记&#xff0c;模拟MySQL优化器来执行SQL语句&#xff0c;执行查询时&#xff0c;会返回执行计划的信息&#xff0c;并不执行这条SQL。&#xff08;注意&…...

编码格式科普ASCII unicode utf-8 usc-2 GB2312

1.ASCII&#xff08;标准版&#xff09; 可以表示所有英文字符&#xff08;包括大写和小写&#xff09;和数字&#xff0c;长度为7bit&#xff0c;最多可以表示0-127 个值&#xff0c;2的7次方个数字。比如比如“a” 对照ASCII码的值为97&#xff08;十进制&#xff09;或11000…...

Pycharm中新建一个文件夹下__init__.py文件有什么用

在PyCharm中新建一个文件夹下的__init__.py文件有以下几个作用&#xff1a; 声明文件夹为一个Python包&#xff1a;__init__.py文件的存在告诉Python解释器该文件夹是一个Python包。当你导入该文件夹下的模块时&#xff0c;Python会将其视为一个包而不是普通的文件夹。这允许你…...

OracleBulkCopy c#批量插入oracle数据库的方法

datatable中的数据 存入oracle表中&#xff0c;要求 二者字段名一致&#xff0c;如果不一致&#xff0c;通过这个实现对应&#xff1a; bulkCopy.ColumnMappings.Add("SERVNUMBER", "SN"); 首先要引入Oracle.DataAccess.dll文件&#xff08;在oracle客户端…...

046_第三代软件开发-虚拟屏幕键盘

第三代软件开发-虚拟屏幕键盘 文章目录 第三代软件开发-虚拟屏幕键盘项目介绍虚拟屏幕键盘 关键字&#xff1a; Qt、 Qml、 虚拟键盘、 qtvirtualkeyboard、 自定义 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object L…...

MySQL主从搭建,实现读写分离(基于docker)

一 主从配置原理 mysql主从配置的流程大体如图&#xff1a; 1&#xff09;master会将变动记录到二进制日志里面&#xff1b; 2&#xff09;master有一个I/O线程将二进制日志发送到slave; 3) slave有一个I/O线程把master发送的二进制写入到relay日志里面&#xff1b; 4&#xf…...

uni-app android picker选择默认月份

微信小程序选中月份后下次再点开是上次的选中的月份&#xff0c;而编译的android应用只默认当前月份 <picker mode"date" ref"picker" :disabled"disabled" :value"date" fields"month" change"bindDateChange&quo…...

Go 接口-契约介绍

Go 接口-契约介绍 文章目录 Go 接口-契约介绍一、接口基本介绍1.1 接口类型介绍1.2 为什么要使用接口1.3 面向接口编程1.4 接口的定义 二、空接口2.1 空接口的定义2.2 空接口的应用2.2.1 空接口作为函数的参数2.2.2 空接口作为map的值 2.3 接口类型变量2.4 类型断言 三、尽量定…...

变压器试验VR虚拟仿真操作培训提升受训者技能水平

VR电气设备安装模拟仿真实训系统是一种利用虚拟现实技术来模拟电气设备安装过程的培训系统。它能够为学员提供一个真实、安全、高效的学习环境&#xff0c;帮助他们更好地掌握电气设备的安装技能。 华锐视点采用VR虚拟现实技术、MR混合现实技术、虚拟仿真技术、三维建模技术、人…...

Mastering Makefile:模块化编程技巧与经验分享

在Linux项目管理中&#xff0c;Makefile是一个强大的工具&#xff0c;它可以帮助我们自动化编译和测试过程。然而&#xff0c;随着项目的增长&#xff0c;Makefile可能会变得越来越复杂&#xff0c;难以管理。在这篇文章中&#xff0c;我将分享一些模块化编程的技巧和经验&…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...