学习日志之链接

主要是链接中的可重定位目标文件和可执行目标文件

1.基本知识须知
2.相关代码文件
3.运行及解释
4.总结

1.基本知识须知

1.预处理,生成预编译文件(.i文件):
    gcc –E main.c –o main.i
2.编译,生成汇编代码(.s文件):
    gcc –S main.i –o main.s
3.汇编,生成目标文件(.o文件):
   gcc –c main.s –o main.o
4.链接,生成可执行文件:
    gcc -o prog main.o sum.o
(-o后为生成文件的命名,默认文件名为a.out)

2.相关代码文件
main.c如下

/* main.c */
/* $begin main */
int sum(int *a, int n);

int array[2] = {1, 2};

int main() 
{
    int val = sum(array, 2);
    return val;
}
/* $end main */

sum.c如下

/* sum.c */
/* $begin sum */
int sum(int *a, int n)
{
    int i, s = 0;
    
    for (i = 0; i < n; i++) { 
        s += a[i];
    }
    return s;
}        
/* $end sum */

3.运行及解释(以main.o为例,还可换为sum.o,prog)
1.在生成main.o,与sum.o链接(gcc -o prog main.o sum.o)后执行命令
objdump -dx main.o
反汇编那些特定指令机器码的section,详细信息如下
在这里插入图片描述
上图是main.o的节,包括.text,.data,.bss ,.rodata等,记录了各节的名称,大小,虚拟地址,装载地址,偏移,对齐。
在这里插入图片描述
上图是main.o的符号表。
其中有三个特殊的伪节,它们在节头部表中是没有条目的:ABS代表不该被重定位的符号;UNDEF代表未定义的符号,也就是在本目标模块中引用,但是却在其他地方定义的符号;COMMON表示还未被分配位置的未初始化的数据目标。
main.o的.text
从上图中我们可以看出.text是从0到20 共21个字节,正是第一幅图中.text的size。

如果想指定显示某个条目的信息可以用
objdump -dx -j .data main.o(输出.data的各项信息)
显示如下在这里插入图片描述
2.运用命令readelf -s main.o输出显示目标文件中所有的符号信息
在这里插入图片描述
符号的信息包括值,大小,类型,环境,访问等,其中Ndx=1表示.text节,Ndx=3表示.data节,以此类推。
此外,
readelf -h main.o (显示main.oELF头信息)
readelf -S main.o(显示main.o节头部表信息)
readelf -r main.o(显示main.o重定位条目信息)
readelf -l prog(显示prog程序头表信息)

注意,prog是main.o和sum.o及一些必要的系统目标文件组合而成的可执行目标文件
4.总结
可重定位目标文件格式在这里插入图片描述
在这里插入图片描述
可执行目标文件格式及与可重定位目标文件的区别
在这里插入图片描述
整体比较
在这里插入图片描述
补充知识:符号
每个可重定位目标模块m都有一个符号表,它包含m定义和引用的符号的信息。在链接器的上下文中,有三种不同的符号:

  1. 由模块m定义并能被其他模块引用的全局符号。全局链接器符号对应于非静态的C 函数和全局变量 。
  2. 由其他模块定义并被模块m引用的全局符号。这些符号称为外部符号,对应于在其他模块中定义的非静态C函数和全局变量。
  3. 只被模块m定义和引用的局部符号。它们对应于带static属性的C函数和全局变量。这些符号在模块m中任何位置都可见,但是不能被其他模块引用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值