链接

链接

1.回顾一下

hello.c的编译过程:

①预处理器cpp     gcc -E hello.c  -o hello.i  (ascii码中间文件)

将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码

②编译器ccl          gcc -S hello.i   -o hello.s (ascii码汇编语言文件)

“翻译”成汇编代码

③汇编器as           gcc -c hello.s   -o hello.o  (可重定位目标文件)

汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现位ELF目标文件(OBJ文件)

④链接器ld           gcc     hello.o  -o hello    (可执行目标文件)

将汇编生成的OBJ文件、系统库的OBJ文件、库文件链接起来,最终生成可以在特定平台运行的可执行程序 


2.链接器

question1:为什么要用它?

①模块化

程序可以写成一组小规模的源代码,对于通用的功能写成库。例如Math library, standard C library。

②效率

时间上单独编译。一个源文件发生变化,单独编译,重新链接。

空间上:库。功能函数聚合为一个单独的文件,可执行文件仅包括其实际使用的代码。

question2:它做了什么?

①符号解析:

  • 在这个程序里面定义或者引用的符号(函数、变量)。
  • 符号表:保存符号定义(编译器干的),是一个结构数组,每个条目有符号名,大小,保存位置。
  • 链接器将符号引用符号定义关联起来。

②重定位

  • 各自的代码和数据段合并。
  • 符号的相对位置重定位到绝对存储位置
  • 更新所有符号引用到绝对位置。

 

a.目标文件有哪些

①可重定位目标文件

编译时可以与其他可重定位合并。

②可执行目标文件

可以直接复制到存储器并执行。

③共享目标文件

特殊的可重定位目标文件。可以在加载或运行时,动态地加载到存储器并链接。(windows内称为动态链接库)

b.可执行和可链接格式ELF 

 目标文件的标准二进制格式,统一的格式。

ELF header (16 字节的序列)

描述了生成该文件的系统的字的大小和字节顺序,剩下的部包含帮助链接器语法分析和解释目标文件的信息

 ELF 头的大小、目标文件的类型 (如可重定位、可执行或者是共享的)、机器类型(如 IA32) 、节头部表 (section header table) 文件偏移,以及节头部表中的条目大小和数量。

Segment header table:页大小,虚地址内存段,段大小

.text: 已编译程序的机器代码。

.rodata: 只读数据,比如 printf 语句中的格式串和开关语句的跳转表。

.data: 已初始化的全局变量。

.bss: 未初始化的全局变量。目标文件种不需要占据任何实际的磁盘空间。

.symtab:

  • 符号表
  • 函数和静态变量名
  • Section名与位置
  • 和编译器中的符号表不同不包含局部变量的条目

. rel .text:

  •  .text 节中位置的列表。
  • 执行时需要修改的指令地址。
  • 可执行目标文件中并不需要重定位信息因此通常省略。

.rel.data:

  • .data中重定位信息
  • 被模块引用或定义的任何全局变量的重定位信息

.debug:

  • 一个调试符号表
  • 其条目是程序中定义的局部变量和类型定义,程序中定义和引用的全局变量,以及原始的源文件。
  • gcc -g

节头部表: 每个section的偏移与大小

c.符号和符号表

① 全局符号global 。本模块定义,外模块能引用(非静态c函数和全局变量)。

②外部符号external。 外模块定义本模块引用。

③本地符号local。本模块定义外模块不能引用。static。不是本地程序变量。

链接器的符号规则

strong:函数,已初始化的全局变量

weak: 未初始化的全局变量

①不允许多个强符号。

②一个强符号和多个弱符号:选择强

③多个弱符号:任意选择一个 

*全局变量尽可能不使用,否则加上static或者初始化,外部extern。

symtab节中包含符号表,每个条目的格式:

d.与静态库链接

所有的编译系统都提供一种机制,将所有相关的目标模块打包成为一个单独的文件,称为静态库 (static library) , 它可以用做链接器的输入。当链接器构造一个输出的可执行文件时,它 只拷贝静态库里被应用程序引用的目标模块。

Unix 系统中,静态库以一种称为存档 (archive) 的特殊文件格式存放在磁盘中。 是一组连接起来的可重定位目标文件的集合。

使用静态库解析引用过程:

 链接器从左到右按命令行上出现顺序,扫描可重定位目标文件和存档文件。

  • E 可重定位目标文件的集合
  • U 未解析符号集合
  • D 前面输入文件中已经定义的符号集合

①f 是目标文件:f添加到E,修改U和D。

②f 是存档文件:匹配U和f中定义的符号,某个存档成员m匹配成功,m添加E,其他被丢弃,修改U和D。

③完成扫描后:  U非空,报错,U空合并和重定位E中目标文件。

e.重定位

①重定位节和符号定义 

  • 将所有相同类型的节合并为同一类型的新的聚合节
  • 将运行时存储器地址赋给新的聚合节
  • 使每个指令和全局变量有唯一的运行时存储地址
 

②重定位节中的符号引用

  • 修改代码节和数据节中对每个符号的引用
  • 依赖于重定位条目

重定位条目:

  • 无论何时汇编器遇到对最终位置未知的目标引用,它就会生成一个重定位条目,告诉链接器在将目标文件合并成可执行文件时如何修改这个引用。
  • 放在.rel.text中,已初始化的在.rel.data中

  • 两种最基本的重定位类型
  • R_386_PC32:  重定位一个使用 32 PC 相对地址的引用,总是与函数调用有关。
  • R_386_32: 重定位一个使用 32 位绝对地址的引用,总是与使用跨文件的全局变量有关。

 重定位符号引用

①重定位pc相对引用

②重定位绝对引用

重定位代码与数据

f.可执行目标文件

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
黑帽SEO站群软件:它不需要人工的更新网站,全自动混沌生成原创内容、全自动智能处理关键词、全自动智能交换链接,使您能够摆脱手工更新网站的烦恼,实现一键建站,快速大批量建站。通过泊君站群,您可以轻而易举的在短期内建立大量网站,轻而易举的建立和维护几百甚至几千个网站,以海量网站获取海量流量! 您可以使用泊君站群来做产品推广、网站排名、网赚等一切需要大量IP的工作。 技巧: 1、购置域名-购买那些老的有权重的域名,拿来重新建设站点。 2、虚假新闻-在那些模仿官网的站,为真实的事件创建真实的新闻。 3、链接工厂–创建小型的高质量的博客网络。一个全职的专业blogger能管理3到5个高质量的博客。 4、新的开发-查找新事物,报道他们并用博客记录下来。你最先发表的故事,因为你将会得到关注和链接。 5、隐藏联署链接–联署链接,特别是带有id形式的(example.com/ref?id=123)是最坏的情况。我们唯一能做的事就是自己申明这是一个联署链接。 6、桥页–有效的桥页可以称之为着落页面(landingpage)。唯一的区别是通常的桥页都是垃圾无价值的内容,而landingpage是为了简化网站为己所用。他们的共同点是他们都是为了从搜索引擎获取流量而优化的。 7、twitter自动化–只要你做的不过分,的自动化是完全可行的。计划你的tweets,甚至是通过其他博客的rss来自动发tweets都可以。只要你能表现出你的这个twitter账号是在进行“手动”的操作。即使是机器人账户,只要他对别人也有用那么他也是可行的。 8、隐藏链接–大部分免费统计工具都会使用隐藏链接。statcounter就是一个例子。当你从它那获取统计代码并嵌入到你的网页时动易站群,你就算是使用了隐藏链接。 9、给予搜索引擎不同的信息–你用wordpress么?那么你可以给你的评论链接加上个nofollow标签,这样搜索引擎将会和用户得到不同的信息。用户看到并点击一个链接,而搜索机器人则看到的是一个不要跟随的信号。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hnu哈哈

请接受直女的么么哒????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值