静态链接——重定位

本文围绕静态链接展开,介绍编译器驱动程序会按需调用多种工具。静态链接器以可重定位目标文件等为输入,生成可执行目标文件,需完成符号解析和重定位两大任务。文中还阐述了重定位类型,通过示例演示了重定位PC相对引用和绝对引用的计算过程。

静态链接

想要理解静态链接这一过程,首先我们需要明白编译器驱动程序,它代表用户在需要时调用语言预处理器编译器汇编器链接器
示例程序:

//main.c
int sum(int *a, int n);
int array[2] = {1, 2};
int main(){
	int val = sum(array, 2);
	return val;
}
//sum.c
int sum(int *a, int n){
	int i, s = 0;
	for(i=0; i<n; i++){
		s += a[i];
	}
	return s;
}

当我们编辑完源代码需要运行时,大致过程如下图所示:
编译器驱动程序大致过程
其中,标红的地方就是这篇文章要讲述的过程。
像Linux LD程序这样的静态链接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出。
为了构造可执行文件,链接器必须完成两个主要任务:符号解析重定位

符号解析

目标文件中,会定义与引用符号。
符号包括:函数、全局变量、静态变量(在C语言中任何以static属性声明的变量)
注意:局部变量不属于符号。
符号解析的目的是将每个符号引用正好和一个符号定义关联起来

重定位

编译器和汇编器生成从地址0开始的代码和数据节。
链接器通过把每个符号定义与一个内存位置关联起来,从而重定位这些节。
然后修改所有对这些符号的引用,使它们准确指向定义的内存位置。
(简单来说,就是对符号定义进行重新定位,再修改符号引用指向的地址)
链接器使用汇编器产生的重定位条目的详细指令,不加甄别地执行这样的重定位。

重定位类型

当汇编器遇到对最终位置未知的目标引用时,会生成一个重定位条目:其目的是告诉链接器在将目标文件合并成可执行文件时应该如何修改这个引用。

ELF重定位条目的格式如下(offset、type、symbol、addend):

typedef struct{
	long offset; //需要被修改的引用的偏移量,也就是入口点偏移量
	long type:32, //声明重定位的类型(相对地址引用or绝对地址引用)
		 symbol:32; //标识被修改的符号,(例如sum函数,这里就是sum)
	long addend; //有符号常数,有时候需要用该值做重定位偏移调整
}Elf64_Rela;

其中最基本的两种类型(type):

R_X86_64_PC32: 重定位一个使用32位PC相对地址的引用。将指令中编码的32位值加上PC的当前运行值作为有效地址。(PC值通常是下一条指令在内存中的地址)
R_X86_64_32: 重定位一个使用32位绝对地址的引用。CPU直接使用在指令中编码的32位值作为有效地址。

重定位符号引用

两种重定位算法如下:

foreach section s {
	foreach relocation entry r {
		refptr = s + r.offset; //s是每个节,r是相关联重定位条目

		//相对寻址
		if (r.type == R_X86_64_PC32) {
			refaddr = ADDR(s) + r.offset; 
			//计算引用的运行时的地址。如果写题,题目会给出ADDR(s)
			*refptr = (unsigned)(ADDR(r.symbol) + r.addend - refaddr); 
			//refaddr = ADDR(s) + r.offset
			//*refptr是指令中编码的32位值(重定位引用值)。
			//后续还需读出PC值。
			//有效地址为:下一条指令地址(PC值)+ *refptr
		}

		//绝对寻址
		if (r.type == R_X86_64_32){
			*refptr = (unsigned)(ADDR(r.symbol) + r.addend);
			//*refptr是指令中编码的32位值(重定位引用值),即有效地址。
		}
	}
}

接下来我们用以下示例图(反汇编代码)来演示相对寻址与绝对寻址。
已知:
ADDR(s) = 0x4004d0;
ADDR(sum) = 0x400e8;
ADDR(array) = 0x601018;
在这里插入图片描述
这里main函数引用了两个全局符号:array和sum。从图中我们可以得知:
array的type是R_X86_64_32(绝对寻址)
sum的type是R_X86_64_PC32(相对寻址)
在这里插入图片描述

重定位PC相对引用

第一步,我们需要列出上述示例中,sum的重定位条目:
在这里插入图片描述
从题目图中可以得知以下信息:
在这里插入图片描述
所以sum的重定位条目为:

r.offset = 0xf
r.symbol = sum
r.type = R_X86_64_PC32
r.addend = -0x4

且题目已告知:

ADDR(s) = 0x4004d0; ADDR(sum) = 0x400e8;

第二步,根据公式可做如下计算:

refaddr = ADDR(s) + r.offset
    = 0x4004d0 + 0xf
    = 0x4004df

*refptr = (unsigned)(ADDR(r.symbol) + r.addend - refaddr)
    = 0x4004e8 + (-0x4) - 0x4004df
    = 0x5

得到重定位引用值:0x5

重定位绝对引用

第一步,我们需要列出上述示例中,sum的重定位条目:
在这里插入图片描述
从题目图中可以得知以下信息:
在这里插入图片描述
所以array的重定位条目为:

r.offset = 0xa
r.symbol = array
r.type = R_X86_64_32
r.addend = 0

且题目已告知:

ADDR(array) = 0x601018;

第二步,根据公式可做如下计算:

*refptr = (unsigned)(ADDR(r.symbol) + r.addend)
    = 0x601018 + 0
    = 0x4601018

得到重定位引用值:0x4601018(同时也是有效地址)

内容概要:本报告基于寻汇与万事达卡在2026年联合发布的《超越自动化:定义智能体驱动的全球支付》白皮书,系统分析了AI智能体在B2B跨境支付领域的应用与发展。报告指出,传统跨境支付存在效率低、人工干预多、合规风险高等问题,当前正从数字化、数据化迈向“自主化”新阶段。AI智能体可在授权下自主完成支付、换汇、合规审核、对账等全流程操作,核心技术包括深度强化学习、自然语言处理和图神经网络,用于路径优化、合规解析与异常检测。报告揭示了决策可解释性不足、跨系统协同标准缺失、安全审计机制缺位三大研究空白,并探讨了法律责任归属、监管碎片化、数据主权与技术可靠性四大现实挑战。寻汇与万事达卡的合作构建了“智能体编排引擎”与全球合规决策网络,首次提出L0-L5的智能体自主化等级框架,推动行业标准化。预计2026至2027年将实现首批大规模商业部署,提升支付效率超30%。; 适合人群:金融科技研究人员、AI技术开发者、跨境支付行业从业者、企业财资管理人员及政策监管机构相关人员。; 使用场景及目标:①理解AI智能体在跨境支付中的技术架构与应用场景;②把握自主化支付的演进趋势与商业化前景;③为金融机构和技术公司布局AI驱动型支付系统提供战略参考;④助力监管机构制定适应智能体时代的合规框架。; 阅读建议:本报告兼具技术深度与产业视野,建议结合白皮书原文及相关技术文献对照研读,重点关注智能体决策逻辑、合规实现机制与跨系统集成方案,并关注后续试点项目的实际成效与监管反馈。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值