静态链接和静态库

简介: 静态链接和静态库

1.静态链接和静态库


静态链接是由链接器在链接时,将库的内容加入到示例程序中的过程。其中使用的库就是我们通常所说的静态库。


静态库可以简单的看成成一组目标文件的集合,即多个目标文件经过压缩打包形成的一个文件。(通过ar工具)


2.静态链接过程


现在的链接器空间分配策略基本上采用一种叫两步链接的方法。然后整个链接过程分为两步:


  • 第一步:空间与地址分配。


扫描所有的输入目标文件,获得他们的各个段的长度,属性和位置,并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个位数符号表。


这一步中,链接器将能够获得所有输入目标文件的段长,变为他们合并,计算出输出文件中各个段合并后的长度和位置,并建立映射关系。


  • 第二步:符号解析与重定位。


使用初步中收集到的所有信息,读取输入文件中段的数据,重定位信息,并进行符号解析和重定位,调整代码中的地址等。


image.png


3.静态库的制作和使用


查看静态库包含的目标文件


-t表示列出包含的所有目标文件



ar -t libc.a


    截取部分。可以看到glibc库包含了很多目标文件。


image.png


解压目标文件


-x表示解压库文件,交替解压所有

ar -x libc.a //解压指定文件
ar -x libc.a printf.o //从libc.a中解压指定printf.o


制作目标文件


-r:替换替换文件中已有的文件或加入新文件;-c:没有创建库的时候发出警告;-s:创建索引



ar -rcs libab.a a.o b.o
ar -rcs *.o libc.a


静态库使用


-L:指定链接链接;-l后面跟随链接的库名(去掉lib)


gcc -Llinkpath -lname
gcc -L./ -lab (libab.a 恰头去尾)


4.实例分析:最小的程序


知道了静态链接过程,以及程序大部分运行时都离不开libc,那么可不可以绕开glibc,写一个最小程序呢?


另外程序可以没有main 函数吗?


答案是可以,这里涉及到操作系统的系统调用和底层知识,如果对操作系统和汇编体系比较熟悉,当然可以绕开。系统调用留待后续介绍。


如图,为一个最小的程序,并且没有 main 函数入口:


image.png


手动链接


编译:gcc -c -fno-builtin nomain.c -m32


-fno-builtin:关闭 GCC 内置函数功能

-m32:指定 32 为系统。默认是 64 位的,不加会报错。


链接:ld -m elf_i386 -static -e nomain -o helloworld nomain.o


-m :设置文件输出格式为 elf_i386。

-static:表示静态链接.

-e nomain:设置程序入口函数为 nomain


使用链接脚本


事实上,链接器在链接时默认有个链接脚本。函数的入口地址,以及各段分部,都可以通过链接脚本控制。我们程序当然也可以指定链接脚本。链接脚本的语法规则本文暂不介绍。


链接:ld -m elf_i386 -static -T nomain.lds -o helloworld nomain.o


image.png


通过该脚本指定入口符号为nomain、将代码段、数据段和只读数据段合并为tinytext,同时舍弃.comment,编出来的程序只有几百个字节,大大缩小了空间。


-ENTRY:指定符号的值为入口地址。

-. = 0x80480000 + SIZEOF_HEADERS 。将当前虚拟地址设置为 0x80480000 + SIZEOF_HEADERS(为输出文件头大小)。

-tinytext : {*(.text) *(.data) *(.rodata)}。将代码段、数据段或者只读数据段合并为 tinytext 段。

-/DISCARD/ : {*(.comment)}。将.comment 丢弃


5.总结


本文主要介绍了,静态链接的过程以及静态库的制作和使用。旨在帮助大家理解库文件和目标文件的关系。


了解静态链接过程,有助于我们调试和分析问题。尤其是在没有源码的情况下,可以通过objdump找到符号表,对应的目标文件位置,然后通过ar将对应目标文件解压出来,最后通过反汇编来分析问题。


另外,main函数作为程序入口已经成为约定俗称,修改入口函数,仅作娱乐使用,切勿使用正式项目,毕竟代码还是要有可读性。


细心的朋友已经发现了,静态链接占的空间大,而且如果多个程序都用了同一份静态库,会极大的浪费资源。那么它存在的价值在哪里呢?

目录
打赏
0
0
0
0
13
分享
相关文章
区块链技术在数字身份认证中的应用与展望
【2月更文挑战第3天】 随着数字化时代的到来,个人身份认证的安全性和便捷性成为了重要的议题。区块链技术作为一种去中心化、不可篡改的分布式账本技术,具有很大潜力用于解决数字身份认证领域的问题。本文将探讨区块链技术在数字身份认证中的应用现状,分析其优势和挑战,并展望未来发展方向。
581 1
clion 一劳永逸 解决中文乱码
clion 一劳永逸 解决中文乱码
198 0
【密码学】一文读懂线性反馈移位寄存器
在正式介绍线性反馈移位寄存器(LFSR)之前,先来看一个小故事,相传在遥远的古代,住着4个奇怪的人。
1848 0
【密码学】一文读懂线性反馈移位寄存器
docker应用部署---Tomcat的部署配置
这篇文章介绍了如何使用Docker部署Tomcat服务器,包括搜索和拉取Tomcat镜像、创建容器并设置端口映射和目录映射,以及如何创建一个HTML页面并使用外部机器访问Tomcat服务器。
docker应用部署---Tomcat的部署配置
在计算机管理系统工程中,我们利用计算机技术来构建、优化和管理各种系统,如企业资源规划(ERP)、客户关系管理(CRM)等。
。在计算机管理系统工程中,我们利用计算机技术来构建、优化和管理各种系统,如企业资源规划(ERP)、客户关系管理(CRM)等。
Koordinator 助力云原生应用性能提升,小红书混部技术实践
本文基于 2023 云栖大会上关于 Koordinator 分享的实录,介绍小红书通过规模化落地混部技术来大幅提升集群资源效能,降低业务资源成本。
30行代码实现一个带UI界面的图片背景移除工具:并附带web网页
人工智能技术正处于蓬勃发展中,移除图片背景的方法众多,涵盖了各式各样的实现途径和模型。然而,这些方法往往在安装和配置环境方面稍显复杂。今天,介绍一种极其简便的方法——大约30行代码,就能实现这一功能。虽然相比之下可能稍显简单,但对于不太苛刻的需求来说,这种方法颇为方便实用。
VS、ReSharper 设置修改代码颜色、提高代码辨识度!附VS超实用快捷!
ReSharper 配置代码颜色 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) ...
5056 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问