GNU ld链接器 lang_process()(二)

news2025/1/10 2:06:10

一、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, and
     is normally the empty string.  ENTRY is the lang_input_statement
     that 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 if
     the default action should be taken.  This field may be NULL, in
     which 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 before
     reading 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 to
     getopt_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 is
     one of our options.  */
  bfd_boolean (*handle_option) (int);  // 20

  /* Run to handle files which are not recognized as object files or
     archives.  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 object
     files 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 specified
     via 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 uses
     this 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 are
     emulation-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,  // T
		      bfd_boolean copy,  // F
		      bfd_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,  // T
		 bfd_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 alloc
	 that 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;
}

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

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

相关文章

PS Raw中文增效工具Camera Raw 16

Camera Raw 16 for mac&#xff08;PS Raw增效工具&#xff09;的功能特色包括强大的图像调整工具。例如&#xff0c;它提供白平衡、曝光、对比度、饱和度等调整选项&#xff0c;帮助用户优化图像的色彩和细节。此外&#xff0c;Camera Raw 16的界面简洁易用&#xff0c;用户可…

每日一题 187. 重复的DNA序列(中等)

由于今天做了周赛&#xff0c;每日一题就简单点直接暴力哈希 class Solution:def findRepeatedDnaSequences(self, s: str) -> List[str]:d defaultdict(int)ans []for i in range(len(s) - 9):t s[i: i 10]d[t] 1if d[t] 2:ans.append(t)return ans

CCC数字钥匙设计【NFC】 --通过NFC进行车主配对Phase4

1、车主配对流程介绍 车主配对可以通过车内NFC进行&#xff0c;若支持UWB测距&#xff0c;也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase4进行介绍。 1) Phase0&#xff1a;准备阶段&#xff1b; 2) Phase1&#xff1a;启动流程&#xff1…

凸优化问题(最简单)

一、凸优化问题 1.1 概念 凸优化问题minf(x)&#xff1a;需要同时满足两个条件&#xff1a;变量可行域时凸的(convex)&#xff1b;目标函数也是凸函数(convex)。 &#xff08;1&#xff09;变量x的可行域Ω为凸集&#xff0c;即对于集合Ω中任意两点x1、x2∈Ω&#xff0c;他…

使用阿里云服务器,httplib库在listen过程中,出现Cannot assign requested address错误???

今天&#xff0c;在做一个小项目的时候&#xff0c;使用httplib库进行建立tcp连接&#xff0c;但是一旦程序开始&#xff0c;并没有等待tcp连接的到来&#xff0c;而是直接结束了。 打印一下strerror(errno) 根本就没有进行客户端的连接。 找了一下午&#xff0c;检测是否…

SEO优化的好帮手,5个必备的好工具

做海外市场的企业&#xff0c;谷歌SEO是一个非常重要的方式&#xff0c;帮助提高自己企业的网站曝光&#xff0c;起着至关重要的作用&#xff0c;因为人们普遍会通过网上搜索来找到那些适合的商品&#xff0c;与排名靠后的公司相比&#xff0c;出现在搜索结果顶部的公司往往能吸…

有人物联网模块连接阿里云物联网平台的方法

摘要&#xff1a;本文介绍有人物联网模块M100连接阿里云的参数设置&#xff0c;作为说明书的补充。 没有阿里云功能需求的请略过本文&#xff0c;不要浪费您宝贵的时间。 网络选择LTE&#xff0c;请先确保插入的SIM卡有流量。 接下来配置阿里云云服务。如下图所示&#xff0c;…

802.11 CSMA/CA协议

《计算机网络自顶向下》P351的总结提炼

Linux应用开发基础知识——交叉编译与gcc编译(一)

前言&#xff1a; 源文件需要经过编译才能生成可执行文件。在 Windows 下进行开发时&#xff0c;只需 要点几个按钮即可编译&#xff0c;集成开发环境(比如 Visual studio)已经将各种编译 工具的使用封装好了。Linux 下也有很优秀的集成开发工具&#xff0c;但是更多的时候是 直…

x264交叉编译(ubuntu+arm)

1.下载源码 https://code.videolan.org/videolan/x264 在windows下解压&#xff1b;复制到ubuntu&#xff1b; 2.进入源码文件夹-新建脚本文件 touch sp_run.sh 3.在sp_run.sh文件中输入 #!/bin/sh./configure --prefix/home/alientek/sp_test/x264/sp_install --enable-…

Gradle中的依赖Dependencies说明与使用总结

【1】依赖的方式 Gradle 中的依赖分别为直接依赖&#xff0c;项目依赖&#xff0c;本地jar 依赖。 dependencies {//①.依赖当前项目下的某个模块[子工程]implementation project(:subject01)//②.直接依赖本地的某个jar文件implementation files(libs/foo.jar, libs/bar.jar…

Vue3.0 路由

简介 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。功能包括&#xff1a; 嵌套路由映射动态路由选择模块化、基于组件的路由配置路由参数、查询、通配符展示由 Vue.js 的过渡系统提供的过渡效果细致的导航控…

思考的起点(一): 事实与判断

事实与判断是思考的主要组成部分&#xff0c;深入理解事实与判断的基本概念&#xff0c;了解其应用可以提升个体的思考质量; 关于事实真相 事实是认知的基础 1.很多事情没有真相, 或者说真相陷入历史的迷雾中, 无法被发现; 2.世界不需要真相&#xff0c;真相往往都是复杂又残…

算法题:144.二叉树的前序遍历(递归、迭代)Java Python部分

1、递归法 其实递归法提交结果也挺好看的&#xff0c;代码如下&#xff1a; class Solution {//前序遍历public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res new ArrayList<Integer>();preorder(root, res);return res;}public vo…

木马捆绑+签名修改(CobaltStrike免杀)

今天我们就来聊一下什么是捆绑木马,说起捆绑木马我相信一些人肯定觉得很陌生。在日常中我相信大家经常可能会遇到这样的一个问题,在一些网站上下载一个电脑软件结果电脑上就被莫名其妙的安装上了一个全家桶(流氓软件)。这就是通过简单的捆绑技术将一些你不需要的广告软件安…

【漏洞复现】Apache_HTTP_2.4.50_路径穿越漏洞(CVE-2021-42013)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证方式一 curl方式二 bp抓捕 1.5、修复建议 说明内容漏洞编号CVE-2021-42013漏洞名称…

CUMT-----Java课后第五章编程题

文章目录 一、题11.1 问题描述1.2 代码块1.3 运行截图 二、题22.1 问题描述2.2 代码块2.3 运行截图 一、题1 1.1 问题描述 (1)使用继承编写人类、教师、学生类的实体类。(2)编写测试类&#xff0c;实例化教师和学生类对象并显示。 1.2 代码块 public class Human {private S…

【Spring Security】Spring Security 认证过程源码分析

项目启动 我们在前面有了解到可以在application.yml中配置用户名密码,那么可以猜想:肯定是在项目启动的时候加载的,我们通过鼠标点击 进入SecurityProperties,我们在User中的getName上打断点,这样项目启动的时候就可以走到这里 之后我们通过点击:Drop Frame可以往回走进…

MapReduce WordCount程序实践(IDEA版)

环境 Linux&#xff1a;Hadoop2.x Windows&#xff1a;jdk1.8、Maven3、IDEA2021 步骤 编程分析 编程分析包括&#xff1a; 1.数据过程分析&#xff1a;数据从输入到输出的过程分析。 2.数据类型分析&#xff1a;Map的输入输出类型&#xff0c;Reduce的输入输出类型&#x…

C++指针笔记

一.定义 是什么&#xff1f; 指针就是地址&#xff0c;相当于门牌号。通过 0x0000也可以拿到该地址里的数据&#xff0c; 可是如果每创建一个变量都要去记住地址编号不太方便我们使用数据&#xff0c;所以才有变量。作用&#xff1f; 通过指针(地址)间接访问内存。内存的编号…