当前位置: 首页 > 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;我将分享一些模块化编程的技巧和经验&…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...