【Linux】详解动态库链接和加载对可执行程序底层的理解

一、动静态库链接的几种情况 

  1. 如果我们同时提供动态库和静态库,gcc默认使用的是动态库。如果我们非要使用静态库,要加-static选项。
  2. 如果我们只提供静态库,那可执行程序没办法,只能对该库进行静态链接,但程序不一定整体式静态链接的。
  3. 如果我们只提供了动态库而我们要进行静态链接会发生链接错误,程序此时默认只能进行动态链接。

二、理解动态库加载

         我们的动态库默认就是一个磁盘级别的文件。当我们的程序开始运行时,当程序运行到需要用到库中的实现方法时,库的代码和数据就会被加载到物理内存当中。库的实现方法一定是要跟程序运行起来所形成的进程产生关联的,动态库加载后,会被映射到该进程的地址空间中,准确来说,是先在页表中填写好对应虚拟地址和物理地址之间的映射关系,才被映射到进程地址空间中的共享区中

        如果此时另一个进程也要加载该动态库,只需要填写它的页表的映射关系即可,不需要再从磁盘中加载一份动态库代码和数据,如果所需库不在内存中才需要加载。这样就保证了一个动态库最多只在内存中存在一份,大大节省了内存开销。这里的本质就是说其实所有系统进程中公共的代码和数据,只需要存在一份

三、可执行程序的理解

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函数),可执行程序的表头会记录调用了这个动态库。 我们调用的动态库也是要被加载到内存中的,并被映射到进程地址空间的共享区中。当我们的程序执行到动态库调用处,就会根据动态库首地址加偏移量找到页表中在内存中的物理地址,进而就能调用动态库中的方法了。所以库中代码和数据的访问,都是可以通过库在地址空间上的起始地址加上我们程序内部的偏移量就可以访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python和pip中常见命令和方法

玩python的同学想必没有不用pip的吧,pip是python包管理工具,和Nodejs的npm、Java的maven类似,这些依靠开源力量建立起的庞大软件库极大提高了开发的效率,下面是整理和总结pip中的常见命令和方法。 pip更新版本 python -m pip inst…

【架构二】胖瘦客户端

瘦客户端和胖客户端是指在客户端-服务端架构中,客户端所承担的功能和责任不同。瘦客户端是指在客户端设备上,主要负责显示用户界面和处理用户输入,而大部分的应用逻辑和数据处理都在服务端完成。瘦客户端通常只需要较少的计算能力和存储资源&…

利用Spark将Kafka数据流写入HDFS

利用Spark将Kafka数据流写入HDFS 在当今的大数据时代,实时数据处理和分析变得越来越重要。Apache Kafka作为一个分布式流处理平台,已经成为处理实时数据的事实标准。而Apache Spark则是一个强大的大数据处理框架,它提供了对数据进行复杂处理…

Echarts 自适应宽高,或指定宽高进行自适应

文章目录 需求分析 需求 有一个按钮实现对Echarts的指定缩放与拉长&#xff0c;形成自适应效果 拉长后效果图 该块元素缩短后效果图 分析 因为我习惯使用 ref 来获取组件的 DOM 元素&#xff0c;然后进行挂载 <div ref"echartsRef" id"myDiv" :sty…

OCR常用识别算法综述

参考&#xff1a;https://aistudio.baidu.com/education/lessonvideo/3279888 语种&#xff1a;常用字符36与常用汉字6623&#xff0c;区别。 标注&#xff1a;文本型位置/单字符位置&#xff0c;后者标注成本大 挑战&#xff1a;场景文字识别&#xff1a;字符大小、颜色、字体…

力扣1379---找出克隆二叉树的相同节点(Java、DFS、简单题)

目录 题目描述&#xff1a; 思路描述&#xff1a; 代码&#xff1a; &#xff08;1&#xff09;&#xff1a; &#xff08;2&#xff09;&#xff1a; 题目描述&#xff1a; 给你两棵二叉树&#xff0c;原始树 original 和克隆树 cloned&#xff0c;以及一个位于原始树 ori…

蓝牙学习九(定向广播 ADV_DIRECT_IND)

一、简介 广播类型有如下&#xff1a; 非定向可连接广播&#xff08;ADV_IND&#xff09;。可连接的非定向广播&#xff0c;表示当前设备可以接受任何设备的连接请求。 定向可连接广播&#xff08;ADV_DIRECT_IND&#xff09;。可连接的定向广播&#xff0c;设备不能被主动扫描…

Kotlin:常用标准库函数(let、run、with、apply、also)

一、let 扩展函数 Kotlin标准库函数let可用于范围确定和空检查。当调用对象时&#xff0c;let执行给定的代码块并返回其最后一个表达式的结果。对象可以通过引用(默认情况下)或自定义名称在块中访问。 let扩展函数源码 let.kt文件代码 fun main() {println("isEmpty $is…

`std::ref`的作用是将一个对象包装成一个引用包装器

std::ref是C标准库中的一个函数模板&#xff0c;位于<functional>头文件中&#xff0c;通常与std::bind一起使用。std::ref的作用是将一个对象包装成一个引用包装器&#xff0c;使得在函数对象的传递中能够以引用的方式传递对象&#xff0c;而不是进行对象的拷贝。 具体…

求区间和

题源 记录一哈前缀和吧 题目描述 给定 n 个正整数组成的数列 a1​,a2​,⋯,an​ 和 m 个区间[li​,ri​]&#xff0c;分别求这 m 个区间的区间和。 对于所有测试数据&#xff0c;m≤10^5,ai​≤10^4 输入格式 第一行&#xff0c;为一个正整数 n 。 第二行&#xff0c;为 n 个正…

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导&#xff0c;需要参考这篇文章&#xff1a; Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…

C++求1到100相加,简单案例

简单案例 #include"iostream" /*如果是iostream.h就可以省略using namespace std*/ using namespace std; /* 指标识符的各种可见范围 */ void main() { int i1,sum0; while(i<100) { sumi; /*sumsum (i)*/ } cout<<"sum"&…

【Unity 实用工具篇】| Unity中 实现背景模糊效果,简单易用

前言【Unity 实用工具篇】| Unity 实现背景模糊效果,简单易用一、实现背景模糊效果1.1 介绍1.2 效果展示1.3 使用说明及下载二、插件资源简单介绍2.1 导入下载好的资源2.2 功能介绍2.2.1 捕获特效2.2.2 高级选项

【Vue】watch监听复杂数据,新值与旧值一样

问题 watch监听复杂数据&#xff0c;例如数组&#xff0c;旧值与新值一样 解决方案 监听回调里返回新数组&#xff0c;新、旧数组地址改变&#xff0c;得到的值也就不一样&#xff0c;例↓ ()>[...data] 码 test.js // 数据 const musicList ref([{ id: 540000200805…

00-JAVA基础-动态编译

动态编译 JAVA 6 引入了动态编译机制。Java 动态编译是指在运行时将Java源代码编译成可执行的字节码。这通常使用Java的内置编译器API javax.tools.JavaCompiler 来实现。 动态编译的应用场景 可以做一个浏览器编写java代码&#xff0c;上传服务器编译和运行的在线测评系统服…

继承.Java

目录 1&#xff0c;概述 1.1继承的含义 1.2什么时候用继承 1.3继承的好处 1.4继承的特点 2&#xff0c;继承的格式 3&#xff0c;可以继承哪些内容 4&#xff0c;成员方法和成员变量的访问特点 5&#xff0c;构造方法的访问特点 6&#xff0c;this&#xff0c;super…

前端三剑客 —— CSS (第一节)

目录 CSS 什么是CSS CSS的几种写法&#xff1a; 行内样式 内嵌样式 外链样式 import 加载顺序 CSS选择器*** 基本选择器 ID选择器 标签选择器 类选择器 通用选择器 包含选择器 上节内容中提到了 前端三剑客 —— HTML 超文本标记语言&#xff0c;这节内容 跟大家…

每日一题 --- 有效的括号[力扣][Go]

有效的括号 题目&#xff1a;20. 有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序…

大厂面试之【Redis持久化机制】 - RDB和AOF概述及应用配置

文章目录 Redis持久化1. RDB(Redis DataBase)1.1 概述1.2 配置应用 2. AOF(Append Only File)2.1 概述2.2 配置应用 Redis持久化 先上结论&#xff1a;Redis持久化操作分为rdb以及aof&#xff0c;但是前者已经够用 1. RDB(Redis DataBase) 1.1 概述 rdb保存的是dump.rdb文件在指…

WEB漏洞挖掘详细教程--用户输入合规性(sql注入测试)

前置教程&#xff1a;WEB漏洞挖掘&#xff08;SRC&#xff09;详细教程--信息收集篇-CSDN博客 WEB漏洞挖掘&#xff08;SRC&#xff09;详细教程--身份认证与业务一致性-CSDN博客 WEB漏洞挖掘&#xff08;SRC&#xff09;详细教程--业务数据篡改-CSDN博客 2.4 用户输入合规性…