【Linux】详解动态库链接和加载对可执行程序底层的理解
一、动静态库链接的几种情况
- 如果我们同时提供动态库和静态库,gcc默认使用的是动态库。如果我们非要使用静态库,要加-static选项。
- 如果我们只提供静态库,那可执行程序没办法,只能对该库进行静态链接,但程序不一定整体式静态链接的。
- 如果我们只提供了动态库而我们要进行静态链接会发生链接错误,程序此时默认只能进行动态链接。
二、理解动态库加载
我们的动态库默认就是一个磁盘级别的文件。当我们的程序开始运行时,当程序运行到需要用到库中的实现方法时,库的代码和数据就会被加载到物理内存当中。库的实现方法一定是要跟程序运行起来所形成的进程产生关联的,动态库加载后,会被映射到该进程的地址空间中,准确来说,是先在页表中填写好对应虚拟地址和物理地址之间的映射关系,才被映射到进程地址空间中的共享区中。
如果此时另一个进程也要加载该动态库,只需要填写它的页表的映射关系即可,不需要再从磁盘中加载一份动态库代码和数据,如果所需库不在内存中才需要加载。这样就保证了一个动态库最多只在内存中存在一份,大大节省了内存开销。这里的本质就是说其实所有系统进程中公共的代码和数据,只需要存在一份。
三、可执行程序的理解
3.1、可执行程序中区域的划分
可执行程序本身是有自己的格式信息的。我们的可执行程序在被加载到内存中之前,程序当中本身就有地址,可执行程序的每一行都是被编址的。我们的可执行程序在没有加载之前,也已经基本被按照类别(比如权限,访问属性等),已经将可执行程序划分成了各个区域。
text (或 code):
- 这部分包含了程序的机器代码,即CPU执行的指令。
- 通常,text (或 code)的大小表示了程序中的指令数量。
data:
- 这部分包含了程序中已经初始化的全局变量和静态变量的值。
- data段的大小表示了程序中已初始化数据的大小。
bss:
- 这部分用于存储未初始化的全局变量和静态变量。
- 与 data不同,bss段在程序加载到内存时并不包含实际的数据值,而是只预留了足够的空间。这些变量的初始值通常是0。
dec (decimal):
- 这通常表示某个段或整个程序大小的十进制表示。
- 当你看到dec 值时,它可能是text、data、bss或整个程序大小的十进制表示。
hex (hexadecimal):
- 这表示某个段或整个程序大小的十六进制表示。
- 与 dec类似,hex值可能是 text、data、bss或整个程序大小的十六进制表示。
可执行程序中除了上述说到的信息外,可执行程序的头部信息(表头)包含了关于程序执行所必需的一系列元数据和结构信息, 头部信息中就保存了main函数的起始地址,所以我们的可执行程序本身就知道要从哪里开始执行。
3.2、可执行程序的编址
首先在这里需要跟大家明确一个概念,我们进程地址空间中的很多地址数据,都是从可执行程序中来的。将我们可执行程序中的每一行都以绝对编址的方式进行编址,每一行就对应一个地址,这就相当于我们进程地址空间中的虚拟地址。也就是说,虚拟地址需要我们的操作系统、编译器和计算机体系结构共同配合才能形成。当我们的静态库被我们的可执行程序加载时,静态库的代码就要被写到我们可执行程序text部分,静态库代码在text部分的绝对编址是确定的,当然静态库数据的编址也是确定的。
3.3、理解动态库动态链接和加载
在进程在被创建的时候是要先创建PCB,初始化它对应的进程地址空间,然后再将磁盘中的数据加载到内存的。为了初始化进程地址空间,操作系统读取可执行程序的表头。在磁盘中存放着的可执行程序的表头中就包含了关于程序执行所必需的一系列元数据和结构信息,操作系统通过读取表头中的信息初始化对应地址空间中的正文代码,已初始化数据和未初始化数据,所以我们也就能理解了为什么不同可执行程序加载完进程地址空间中有数据的地址范围不一样了。
当可执行程序的代码和数据加载到内存中时,因为可执行程序的每一行对应一个虚拟地址,加载到内存中又有了一个实际的物理地址,拿着物理地址和虚拟地址操作系统就可以填写页表对应的映射关系了。当这个进程要被CPU调度执行时,CPU的pc指针就保存了main函数的入口地址(pc指针内保存的是虚拟地址),CPU内部可以帮我们读取页表的内容将虚拟地址转换为物理地址,CPU去到相应的物理地址取到指令放到CPU内部的指令寄存器中,通过解析指令完成工作或是指明下一个虚拟地址,再让CPU解析虚拟地址找到物理地址中的内容,这样周而复始,我们的程序就跑起来了。
现在假设我们的可执行程序调用了某一个动态库,在我们程序的就会有这个动态库的调用信息(比如说_start(这里的_start可以看成库名,最后会被转换成库在共享区中的地址)+0x10,print,就是指我们的可执行程序调用了动态库中相对动态库首地址偏移量为0x10处的print函数),可执行程序的表头会记录调用了这个动态库。 我们调用的动态库也是要被加载到内存中的,并被映射到进程地址空间的共享区中。当我们的程序执行到动态库调用处,就会根据动态库首地址加偏移量找到页表中在内存中的物理地址,进而就能调用动态库中的方法了。所以库中代码和数据的访问,都是可以通过库在地址空间上的起始地址加上我们程序内部的偏移量就可以访问。
相关文章:

【Linux】详解动态库链接和加载对可执行程序底层的理解
一、动静态库链接的几种情况 如果我们同时提供动态库和静态库,gcc默认使用的是动态库。如果我们非要使用静态库,要加-static选项。如果我们只提供静态库,那可执行程序没办法,只能对该库进行静态链接,但程序不一定整体…...

中文Mistral模型介绍(Chinese-Mistral)——中文大语言模型
中文Mistral简介 Chinese-Mistral由清华大学地学系地球空间信息科学实验室开发。 该模型基于Mistral发布的Mistral-7B-v0.1训练得到。首先进行中文词表扩充,然后采用实验室提出的PREPARED训练框架(under review)在中英双语语料上进行增量预训…...

yolo v5 中 letterbox对不规则矩形框的输入调整
在对数据或特征的处理中,为了避免输入图像或特征,经过resize等等操作,改变了目标特征的尺度信息,一般会引入一些操作,比如: 在特征维度,加入SPP(空间金字塔池化)&#x…...

STL是什么?如何理解STL?
文章目录 1. 什么是STL2. STL的版本3. STL的六大组件4. 如何学习STL5.STL的缺陷 1. 什么是STL STL(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。 2. …...

【Spring篇】Spring IoC DI
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【Spring系列】 本专栏旨在分享学习Spring MVC的一点学习心得,欢迎大家在评论区交流讨论💌 目录 前言一、IoC二、…...
Python语言例题集(010)
#!/usr/bin/python3 #在链表的末端插入新的节点。 class Node(): def init(self,dataNone): self.datadata self.nextNone class LinkedList(): def init(self): self.headNone def printList(self):ptrself.headwhile ptr:print(ptr.data)ptrptr.nextdef ending(self,newd…...

redis---主从复制
主从复制是指将一台redis服务器的数据复制到其他redis服务器,也叫主节点和从节点。 一个主节点可以有多个从节点。而每个从节点只能有一个主节点。数据的复制是单向的,只能由主节点到从节点。一般来说,主节点负责写操作,从节点负…...
搜索引擎-03-搜索引擎原理
拓展阅读 搜索引擎-01-概览 搜索引擎-02-分词与全文索引 搜索引擎-03-搜索引擎原理 Crawl htmlunit 模拟浏览器动态 js 爬虫入门使用简介 Crawl jsoup 爬虫使用 jsoup 无法抓取动态 js 生成的内容 Crawl WebMagic 爬虫入门使用简介 webmagic 全网搜索引擎架构与流程如何…...

mysql语句学习
SQL Select语句完整的执行顺序: 1、from子句组装来自不同数据源的数据; (先join在on) 2、where子句基于指定的条件对记录行进行筛选; 3、group by子句将数据划分为多个分组; 4、使用聚集函数进行计算&a…...

【Apache Doris】周FAQ集锦:第 1 期
【Apache Doris】周FAQ集锦:第 1 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目! 在这个栏目中,每周将筛选社区反馈的热门问题和话题,重点回答并进行深入探讨。旨在为广大用户和…...
Windows创建远程线程学习
CreateRemoteThread是一个Windows API函数,它能够创建一个在其它进程地址空间中运行的线程; 下面来简单做一下,配合procexp工具; VC代码如下,我是写到一个菜单单击处理函数中, void CCrrmthView::OnMenuitem32771() {// TODO: Add your command handler code hereHAN…...

使用c语言libexpat开源库解析XML数据
1 libexpat简介 Expat 是一个用 C 语言编写的开源 XML 解析库,以其高性能和小巧的体积著称。Expat 兼容多种操作系统平台,包括但不限于 Windows、Linux、macOS 等。由于其跨平台特性和简单易用的API,Expat 成为了许多C/C程序员解析XML文档的…...

51单片机入门_江协科技_19~20_OB记录的笔记
19. 串口通讯 19.1. 串口介绍: •串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。 •单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的…...

基于k8s的高性能综合web服务器搭建
目录 基于k8s的高性能综合web服务器搭建 项目描述: 项目规划图: 项目环境: k8s, docker centos7.9 nginx prometheus grafana flask ansible Jenkins等 1.规划设计整个集群的架构,k8s单master的集群环境&…...

Folder Icons for Mac v1.8 激活版文件夹个性化图标修改软件
Folder Icons for Mac是一款Mac OS平台上的文件夹图标修改软件,同时也是一款非常有意思的系统美化软件。这款软件的主要功能是可以将Mac的默认文件夹图标更改为非常漂亮有趣的个性化图标。 软件下载:Folder Icons for Mac v1.8 激活版 以下是这款软件的一…...

Gitee上传私有仓库
个人记录 Gitee创建账号 以KS进销存系统为例,下载到本地电脑解压。 新建私有仓库 仓库名称:ks-vue3,选择‘私有’ 本地配置 下载安装git配置git 第一次配置可以在本地目录右键【Open Git Bash here】输入【Git 全局设置】再输入【创…...

HTMLCSSJS
HTML基本结构 <html><head><title>标题</title></head><body>页面内容</body> </html> html是一棵DOM树, html是根标签, head和body是兄弟标签, body包括内容相关, head包含对内容的编写相关, title 与标题有关.类似html这种…...

第14章 数据结构与集合源码
一 数据结构剖析 我们举一个形象的例子来理解数据结构的作用: 战场:程序运行所需的软件、硬件环境 战术和策略:数据结构 敌人:项目或模块的功能需求 指挥官:编写程序的程序员 士兵和装备:一行一行的代码 …...

分享react+three.js展示温湿度采集终端
前言 气象站将采集到的相关气象数据通过GPRS/3G/4G无线网络发送到气象站监测中心,摆脱了地理空间的限制。 前端:气象站主机将采集好的气象数据存储到本地,通过RS485等线路与GPRS/3G/4G无线设备相连。 通信:GPRS/3G/4G无线设备通…...

易宝OA ExecuteSqlForDataSet SQL注入漏洞复现
0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA ExecuteSqlForDataSet接口处存在SQL注入漏洞,未经身份认证的攻击者可以通过…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...