Linux:库

目录

静态库

动态库

目标文件

ELF文件 

ELF形成可执行

ELF可执行加载

 ELF加载

全局偏移量表GOT(global offset table) 


库是写好的,成熟的,可以复用的代码

现实中每个程序都要依赖很多的基础的底层库,不可能都是从零开始的

库有两种:

  • 静态库 .a[Linux]、.lib[windows]
  • 动态库 .so[Linux]、.dll[windows]

静态库

程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库

一个可执行程序可能用到多个库,这些库可能有的是静态库,有的是动态库,而我们编译默认链接为动态库,只有在该库下找不到动态.so的时候才会采用同名静态库。

若是想使用静态库我们可以使用gcc的 -static 强转设置链接静态库

 静态库的生成:

ar -rc libmylib.a mylib.o

 若我们有一个自己写的库叫mylib,那么我们该如何使用它呢?


若头文件和库文件都被我们安装到系统的路径下

/usr/lib、/usr/lib64、/usr/local/lib等等

gcc main.c -lmystdio

 头文件和库文件和我们自己的源文件在同一个路径下

gcc main.c -L. -lmylib

头文件和库文件都有自己独立的路径

gcc main.c -I头⽂件路径 -L库⽂件路径 -lmylib
  •  -L:指定库路径
  • -I:指定头文件搜索路径
  • -l:指定库名

动态库

程序在运行的时候才去链接动态库,多个程序可以共享使用库的代码

一个与动态库链接的可执行程序仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接

动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘的空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间

动态库的生成:

gcc -fPIC -c main.c -o mylib.o
gcc -o libmylib.so mylib.o -shared

动态库需要使用位置无关码PIC,因此需要加上 -fPIC选项

动态库的命名约定通常以lib开头,后缀为.so

  • shared:表示生成共享库格式
  • fPIC:产生位置无关码
  • 库名规则:libxxx.so

动态库使用:

若头文件和库文件都被我们安装到系统的路径下

gcc main.c -lmylib

头文件和库文件和我们自己的源文件在同一个路径下

gcc main.c -L. -lmylib

头文件和库文件都有自己独立的路径

gcc main.c -I头⽂件路径 -L库⽂件路径 -lmylib

我们可以使用ldd命令来查看库或者可执行程序的依赖

ldd libmylib.so

目标文件

在编译之后会产生扩展名为.o的文件,它们被称作目标文件 

若是我们有多个源文件,需要修改其中一个,那么我们只需要编译这一个为目标文件再一起链接,这样就不需要浪费时间重新编译整个工程

目标文件是一个二进制文件,文件的格式是ELF,是对二进制代码的一种封装 

ELF文件 

以下四种都是ELF文件

  • 可重定位文件:即xxx.o文件。包含适合于与其他⽬标⽂件链接来创建可执⾏⽂件或者共享⽬标⽂件的代码和数据
  • 可执行文件:即可执行程序
  • 共享目标文件:即 xxx.so⽂件
  • 内核转储:存放当前进程的执⾏上下⽂,⽤于dump信号触发

一个ELF文件由四个部分组成

  • ELF头(ELF header):描述⽂件的主要特性。其位于⽂件的开始位置,它的主要⽬的是定位⽂件的其他部分
  • 程序头表(Program header table):列举了所有有效的段(segments)和他们的属性。表⾥
    记着每个段的开始的位置和位移(offset)、⻓度,毕竟这些段,都是紧密的放在⼆进制⽂件中,需要段表的描述信息,才能把他们每个段分割开
  • 节头表(Section header table):包含对节(sections)的描述
  • 节(Section):ELF⽂件中的基本组成单位,包含了特定类型的数据。ELF⽂件的各种信息和数据都存储在不同的节中,如代码节存储了可执⾏代码,数据节存储了全局变量和静态数据等

常见的节有:

  • 代码节(.text):⽤于保存机器指令,是程序的主要执⾏部分
  • 数据节(.data):保存已初始化的全局变量和局部静态变量

ELF形成可执行

1. 首先将多份C/C++源代码翻译称为目标.o文件

2. 将多份.o文件Section进行合并

ELF可执行加载

⼀个ELF会有多种不同的Section,在加载到内存的时候,也会进⾏Section合并,形成segment

合并原则:相同属性,⽐如:可读,可写,可执⾏,需要加载时申请空间等。这样,即便是不同的Section,在加载到内存中,可能会以segment的形式,加载到⼀起

很显然,这个合并⼯作也已经在形成ELF的时候,合并⽅式已经确定了,具体合并原则被记录在了
ELF的 程序头表 (Program header table) 中

 

Section合并的主要原因是为了减少⻚⾯碎⽚,提⾼内存使⽤效率 

 ELF加载

⼀个ELF程序,在没有被加载到内存的时候,本来就有地址,当代计算机⼯作的时候,都采⽤"平坦
模式"进⾏⼯作。

 

用来初始化的数据也是从ELF的各个segment来,每个segment有自己的起始地址和长度,用来初始化内核结构中[start, end]等范围的数据

 

程序调用库方法:只需要知道库的起始虚拟地址+方法偏移量即可定位库中的⽅法

我们的程序运⾏之前,先把所有库加载并映射,所有库的起始虚拟地址都应该提前知道 
对我们加载到内存中的程序的库函数调⽤进⾏地址修改,在内存中⼆次完成地址设置(这个叫做加载地址重定位)
但是代码区是可读的,怎么能修改呢?

全局偏移量表GOT(global offset table) 

动态链接采⽤的做法是在 .data (可执⾏程序或者库⾃⼰)中专⻔预留⼀⽚区域⽤来存放函数的跳转地址,它也被叫做全局偏移表GOT,表中每⼀项都是本运⾏模块要引⽤的⼀个全局变量或函数的地址

因为.data区域是可读写的,所以可以⽀持动态进⾏修改 

有了GOT表,代码便可以被所有进程共享。但在不同进程的地址空间中,各动态库的绝对地址、相对位置都不同。每个动态库都有独⽴的GOT表,所以进程间不能共享GOT表

 

 


完 

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

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

相关文章

心脏滴血漏洞复现(CVE-2014-0160)

漏洞范围: OpenSSL 1.0.1版本 漏洞成因: Heartbleed漏洞是由于未能在memcpy()调用受害用户输入内容作为长度参数之前正确进 行边界检查。攻击者可以追踪OpenSSL所分配的64KB缓存、将超出必要范围的字节信息复 制到缓存当中再返回缓存内容,…

一文学会:用DeepSeek R1/V3 + AnythingLLM + Ollama 打造本地化部署的个人/企业知识库,无须担心数据上传云端的泄露问题

文章目录 前言一、AnythingLLM 简介&基础应用1.主要特性2.下载与安装3.配置 LLM 提供商4.AnythingLLM 工作区&对话 二、AnythingLLM 进阶应用:知识增强使用三、AnythingLLM 的 API 访问四、小结1.聊天模式2.本地存储&向量数据库 前言 如果你不知道Olla…

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 0基础…

探秘AES加密算法:多种Transformation全解析

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

html文件怎么转换成pdf文件,2025最新教程

将HTML文件转换成PDF文件,可以采取以下几种方法: 一、使用浏览器内置功能 打开HTML文件:在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框:按下CtrlP(Windows)或CommandP(M…

DFS+回溯+剪枝(深度优先搜索)——搜索算法

DFS也就是深度优先搜索,比如二叉树的前,中,后序遍历都属于DFS。其本质是递归,要学好DFS首先需要掌握递归。接下来咱们就一起来学习DFS涉及的算法。 一、递归 1.什么是递归? 递归可以这样理解把它拆分出来&#xff0…

DeepSeek从入门到精通教程PDF清华大学出版

DeepSeek爆火以来,各种应用方式层出不穷,对于很多人来说,还是特别模糊,有种雾里看花水中望月的感觉。 最近,清华大学新闻与传播学院新媒体研究中心,推出了一篇DeepSeek的使用教程,从最基础的是…

idea Ai工具通义灵码,Copilot我的使用方法以及比较

我用过多个idea Ai 编程工具,大约用了1年时间,来体会他们那个好用,以下只是针对我个人的一点分享,不一定对你适用 仅作参考。 介于篇幅原因我觉得能说上好用的 目前只有两个 一个是阿里的通义灵码和Copilot,我用它来干…

C++ Primer sizeof运算符

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…

【C++】命名空间

🌟 Hello,我是egoist2023! 🌍 种一棵树最好是十年前,其次是现在! 目录 背景知识 命名空间(namespace) 为何引入namespace namespace的定义 namespace的使用 背景知识 C的起源要追溯到1979年&#xff0…

(2024|Nature Medicine,生物医学 AI,BiomedGPT)面向多种生物医学任务的通用视觉-语言基础模型

BiomedGPT: A generalist vision–language foundation model for diverse biomedical tasks 目录 1. 摘要 2. 引言 3. 相关研究 3.1 基础模型与通用生物医学 AI 3.2 生物医学 AI 的局限性 3.3 BiomedGPT 的创新点 4. 方法 4.1 架构及表示 4.1.1 模型架构选择 4.1.2 …

使用PyCharm进行Django项目开发环境搭建

如果在PyCharm中创建Django项目 1. 打开PyCharm,选择新建项目 2.左侧选择Django,并设置项目名称 3.查看项目解释器初始配置 4.新建应用程序 执行以下操作之一: 转到工具| 运行manage.py任务或按CtrlAltR 在打开的manage.pystartapp控制台…

AD域控粗略了解

一、前提 转眼大四,目前已入职上饶一公司从事运维工程师,这与我之前干的开发有着很大的差异,也学习到了许多新的知识。今天就写下我对于运维工作中常用的功能——域控的理解。 二、为什么要有域控,即域控的作用 首先我们必须要…

Linux(21)——系统日志

目录 一、系统日志架构: 1、系统日志: 2、日志文件类型: 二、查看 syslog 文件: 1、将事件记录到系统: (1)syslog 设备: (2)syslog 优先级&#xff1a…

学习数据结构(6)单链表OJ上

1.移除链表元素 解法一:(我的做法)在遍历的同时移除,代码写法比较复杂 解法二:创建新的链表,遍历原链表,将非val的节点尾插到新链表,注意,如果原链表结尾是val节点需要将…

第433场周赛:变长子数组求和、最多 K 个元素的子序列的最值之和、粉刷房子 Ⅳ、最多 K 个元素的子数组的最值之和

Q1、变长子数组求和 1、题目描述 给你一个长度为 n 的整数数组 nums 。对于 每个 下标 i&#xff08;0 < i < n&#xff09;&#xff0c;定义对应的子数组 nums[start ... i]&#xff08;start max(0, i - nums[i])&#xff09;。 返回为数组中每个下标定义的子数组中…

CSS 伪类(Pseudo-classes)的详细介绍

CSS 伪类详解与示例 在日常的前端开发中&#xff0c;CSS 伪类可以帮助我们非常精准地选择元素或其特定状态&#xff0c;从而达到丰富页面表现的目的。本文将详细介绍以下伪类的使用&#xff1a; 表单相关伪类 :checked、:disabled、:enabled、:in-range、:invalid、:optional、…

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…

大模型推理——MLA实现方案

1.整体流程 先上一张图来整体理解下MLA的计算过程 2.实现代码 import math import torch import torch.nn as nn# rms归一化 class RMSNorm(nn.Module):""""""def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Pa…

Python截图轻量化工具

一、兼容局限性 这是用Python做的截图工具&#xff0c;不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境&#xff1b; 如果要提升其跨平台性的话&#xff0c;需要考虑替换cty…