博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
链接器上——链接器的秘密
阅读量:5786 次
发布时间:2019-06-18

本文共 1845 字,大约阅读时间需要 6 分钟。

链接器的秘密

问题:源码被编译后生成目标文件,这些文件如何生成最终的可执行程序?

链接器的主要作用就是把各个模块之间的相互引用的部分处理好,使得各个模块之间能够正确的衔接
链接器上——链接器的秘密
源文件 func.c

#include 
int* g_pointer;void func(){ g_pointer = (int*)"D.T.Software"; return;}

原文件:test.c

#include 
int g_global = 0;int g_test = 1;extern int* g_pointer;extern void func();int main(int argc, char *argv[]){ printf("&g_global = %p\n", &g_global); printf("&g_test = %p\n", &g_test); printf("&g_pointer = %p\n", &g_pointer); printf("g_pointer = %p\n", g_pointer); printf("&func = %p\n", &func); printf("&main = %p\n", &main); func(); return 0;}

原文件:

#include 
#include
int program(){ printf("D.T.Software\n"); exit(0);}

1目标文件的特点:

1.各个段没有具体的起始地址,只有段大小信息

2.各个标识符没有实际地址,只有段中的相对地址
3.段和标识符的实际地址需要链接器具体确定

2链接器的工作内容

1.将目标文件和库文件整合为最终的可执行程序。

2.合并各个目标文件中的段(.test, .data, .bsss)
3.确定各个段和段之间的标识符的最终地址(重定位)

3 main函数的位置

3.1 mian函数的位置

问题main函数是第一个被执行的函数吗?

默认情况下(对gcc 编译器):
1.程序加载后,_start()函数是第一个被调用执行的函数(_start()函数的入口地址就是代码段(.text)的起始地址
2._start()函数准好参数(main函数、初始化函数libc_csu_fini,终止函数libc_csu_init)后立即调用_libc_start_main()函数
3._libc_start_main()函数初始化运行环境后调用main()函数
4._start 函数的地址是真个代码段的起始地址

3.1 _libc_start_main() 函数的作用:

1.调用_libc_csu_init()函数(完成必要的初始化操作)

2.启动程序的第一个线程(主线程),main()为线程入口
3.注册_libc_csu_fini()函数(程序运行终止时被调用)

3.2程序的启动过程:

链接器上——链接器的秘密

4自定义程序入口函数

gcc 提供 -e 选项用于在链接时指定入口函数

自定义入口函数必须使用 -nostartfiles 选项进行链接

#include 
#include
int program() // entry function{ printf(" Hello BT \n"); exit(0);}

首先直接编译程序:

链接器上——链接器的秘密
报错,找不到main函数,默认情况下,连接器工作是会去链接系统总提供的启动文件,当而默认的启动文件中最终会调用main函数。
使用编译选项 gcc -e program -nostartfiles program.c 则编译运行正常。
思考:
链接选项 -nostartfiles 的意义是什么?
在通常情况下,链接时都会使用系统启动文,该编译选项指定不使用系统的启动文件。
链接器根据说明原则完成具体的工作?
链接脚本。

5 重要链接选项

-nostartfiles // 指定入口函数

-nodefaultlibs // 不使用默认库文件
-nostdlib // 不使用标准库函数

转载于:https://blog.51cto.com/11134889/2072456

你可能感兴趣的文章
swift中的只读属性实现,很简单
查看>>
如何在网络视听行业建一扇内容安全大门?
查看>>
简单了解阿里云Web应用防火墙(下篇)
查看>>
HBase概述
查看>>
汽车短视频大行其道,新能源汽车平台杉车网如何“领风骚”?
查看>>
智能交通|智慧产业园区管理系统集成搭建
查看>>
从零开始学Koa2(一)
查看>>
Nodejs教程09:实现一个带接口请求的简单服务器
查看>>
MAC 显示隐藏文件
查看>>
【JZOF】已知前序遍历和中序遍历,求出其后序遍历
查看>>
[iOS] 使用 blockable NSTimer 避免内存泄漏
查看>>
Java执行shell、cmd命令
查看>>
JavaEE 微信支付
查看>>
理解BFC
查看>>
自制简易前端MVC框架
查看>>
聊聊flink的BlobServer
查看>>
HTTP全解析
查看>>
Netty+SpringBoot+FastDFS+Html5实现聊天App详解(一)
查看>>
区块链共识机制简述
查看>>
排序算法 JavaScript
查看>>