C程序的链接

符号表

/* main.c */
#include <stdio.h>

int g_a = 0x11;
int g_b = 0x22;

extern int e_a;
extern int e_b;

void fun() {
	static int s_a = 0x33;
	static int s_b = 0x44;
	return ;
}

int main() {
	int a = 0xaa;
	int b = 0xbb;
	e_a = 0x55;
	e_b = 0x66;
	printf("hello world\n");
	return 0;
}
/* test.c */
int e_a = 10;
int e_b = 20;

单独查看main.o看看那些值变了,对比a.out的符号表

extern其实就是告诉编译器,只是在这个编译单元里,这个符号的类型和值还不能确定,但是兴许定义在了其他.o文件里,你先别报错,链接的时候自己找找看,。

符号决议

  • 一山不容二虎
  • 强弱可以共存
  • 体积大者胜出。

已初始化的全局变量、函数名默认是强符号。
未初始化的全局变量默认是弱符号。
__attribute__((weak))可以将强符号转变成弱符号

  1. 强符号不能同时出现,编译会报错

  2. 可以有多个同样的弱符号,不会报错

/* test.c */
int i;
/* main.c */
int i;
int main() {
	return 0;
}
  1. 如果没有强符号,所占体积最大的弱符号会最终被选中。
/* test.c */
int i;
/* main.c */
char i;
int main() {
	return 0;
}
  1. 通过强弱符号,方便用户“重载”函数
/* test.c */
#include <stdio.h>
/*
int fun(int a, int b) {
	a = a;
	b = b;
	printf("wait for user\n");
	return 0;
}
*/
__attribute__((weak)) int fun(int a, int b) {
	a = a;
	b = b;
	printf("wait for user\n");
	return 0;
}
/* main.c */
#include <stdio.h>
int i;
int main() {
	i = fun(1, 2);
	printf("i = %d", i);
	return 0;
}

int fun(int a, int b) {
	return a + b;
}

指定所属段

__attribute__(section)

重定位表

刚才所说的变化其实就是重定位的结果
还是刚才的例子,通过下面的命令
readeelf -r main.o
可查看重定位的符号
那么新地址 = 段基地址 + 段内偏移

链接ld脚本

但是谁告诉它到底怎么链接,入口地址在哪里,需要那些文件?

https://mp.weixin.qq.com/s/VbmCHb72Pm_9Uc5jf2wgKw

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值