Unix 编程 -- 静态链接 & 重定位

静态链接·重定位

静态链接过程会将汇编器生成的可重定位文件(*.o)合并到一个可执行文件中。当链接器完成符号解析后,就会执行重定位过程。重定位过程分为两步:

  • 重定位节及符号定义。相同类型的节会被聚合到可执行文件的同一类型的节中,如下图的步骤一。符号解析过程已经确定了符号被定义的模块及节位置,所以重定位节后,每个符号的运行时地址也已经确定了。
  • 重定位节中的符号引用。如下图的步骤二,在编译main.o时,引用的符号func是由其它模块定义的,编译器无法确定该符号的运时地址,此时编译器所做的是为每个引用的位置记录一个重定位条目信息。链接器根据此信息进行符号引用重定位。

程序代码

main.c

#include <stdio.h>

const static char *s_str = "a static string";
extern int g_num;

int func();

static int func_st()
{
	return --g_num;
}

int main()
{
    int ret = func();
	int ret2 = func_st();

	printf("str: %s, ret: %d, ret2: %d\n", s_str, ret, ret2);	

	return 0;
}

func.c

static int s_num = 200;
int g_num = 200;

int func()
{
	s_num++;
    return s_num;
}

链接示意

       main.o中引用了三个外部符号,其中g_num、func由func.o定义,使用静态的链接方式。printf是标准库定义的函数,如果其它模块都没定义,链接器会默认从标准库libc.so中查找。可以使用-static选项表明要生成一个完全的可执行文件,这样链接器会选择从libc.a库静态链接相应模块到可执行文件里。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值