Linux环境下:程序的链接, 装载和库[可执行文件的装载]
现代操作系统如何装载可执行文件?
- 给进程分配独立的虚拟地址空间
- 建立虚拟地址空间和可执行文件的映射关系
- 把CPU指令寄存器设置成可执行文件的入口地址,启动执行
可执行文件在装载的过程中实际上是映射的虚拟地址空间,所以可执行文件通常被叫做映像文件(或者Image文件).
ELF文件的两种视角
- Section header table: 编译器、汇编器和链接器将这个文件看作是被区段(section)头部表描述的一系列逻辑区段的集合
- Program header table: 系统加载器将文件看成是由程序头部表描述的一系列段(segment)的集合。一个段(segment)通常会由多个区段(section)组成。例如,一个“可加载只读”段可以由可执行代码区段、只读数据区段和动态链接器需要的符号组成

readelf -a 可执行文件 可以看到section和segment的映射关系
readelf -a sta_loop

每个Segment包含的Section在下面的mapping种可以看到。图中Program Headers的Type的含义可以在 /usr/include/elf.h 中查看,Load即表示可装载的段

可以单独通过 readelf -l sta_loop查看可执行文件的程序头
-l --program-headers Display the program headers
ELF可执行文件和进程虚拟地址空间的映射关系
样例
#include <stdlib.h>
int main()
{
void* pm = NULL;
for(;;)
{
pm = malloc(100);
sleep(500);
if(pm)
{
free(pm);
}
}
}
编译成静态链接库 sta_loop
执行 ./sta_loop &
通过 proc 文件系统 /proc/<PID>/maps查看虚拟内存的映射情况, 该文件有6列, 各个列的含义
- 地址:虚拟内存区域的起始和终止地址
- 权限:虚拟内存的权限,r=读,w=写,x=执行,s=共享,p=私有
- 偏移量:虚拟内存区域在被映射文件中的偏移量
- 设备:映像文件的主设备号和次设备号
- 节点:映像文件的节点号
- 路径: 映像文件的路径

这里可以看到上面的两个段都对应到我们的静态链接库的elf文件,分别是只读+可执行的段以及可读可写的段。可以看到第二段的offset是映像文件中的偏移,000a6000和上面readelf -a sta_loop看到的偏移一致。
这个就是对应在操作系统中学到的,执行一个程序首先是要将可执行文件加载到可执行的代码段和数据段

具体linux内核是如何加载可执行程序并进行虚拟内存映射的可以查看这篇文章
https://blog.csdn.net/gatieme/article/details/51628257
Linux环境下:程序的链接, 装载和库[可执行文件的装载]的更多相关文章
- 如何查看Linux系统下程序运行时使用的库?
Linux系统下程序运行会实时的用到相关动态库,某些场景下,比如需要裁剪不必要的动态库时,就需要查看哪些动态库被用到了. 以运行VLC为例. VLC开始运行后,首先查看vlc的PID,比如这次查到的V ...
- 解决Linux系统下程序找不到动态库的方法
思路:一般来说,通过make命令已经将程序依赖的动态库编译出来了,通过make install命令已经将动态库安装到系统的某个路径下.找没找到动态库就看这个路径是否包含在系统默认搜索动态库的路径中,如 ...
- windows和linux环境下使用google的glog日志库
一.概述 glog是google推出的一款轻量级c++开源日志框架,源码在github上,目前最新release版本是v0.3.5. githut地址:https://github.com/googl ...
- Linux 环境下程序不间断运行
一.背景 在linux命令行中执行程序,程序通常会占用当前终端,如果不启动新的终端就没法执行其他操作.简单可以通过'&'将程序放到后台执行,但是这种方法有个问题就是,一旦连接远程服务器 ...
- C语言中Linux环境下编译与链接
编写一个简单的 hello.c 文件,以此为例. 1.编译并链接一个完全包含于一个源文件的C程序. gcc hello.c gcc -Wall hello.c gcc -o hello hello.c ...
- 编写第一个Linux环境下程序的编译,下载记录
跟着韦东山学习Linux: 今天系统系统性的学了代码的编译下载,条记录一下: 一,代码:001_led_on.S,就把下面代码编译后Bin文件下载进2440处理器. /* * 点亮LED1: gpf4 ...
- [Python学习] Linux环境下的Python配置,必备库的安装配置
1.默认Python安装情况 一般情况,Linux会预装Python的,版本较低,比如Ubuntu15的系统一般预装的是Python2.7.10. 使用命令:which python可以查看当前的py ...
- 【ARM-Linux开发】Linux环境下使用eclipse开发C++动态链接库程序
Linux环境下使用eclipse开发C++动态链接库程序 Linux中也有类似windows中DLL的变成方法,只不过名称不同而已.在Linux中,动态链接叫做Standard Object,生成的 ...
- Linux环境下部署完JDK后运行一个简单的Java程序
前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...
- 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案
基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...
随机推荐
- [Unity] 为什么文件名和类名需要相同
挂载脚本时文件名和类名的关联方式 写过Unity脚本的人应该都知道,挂载脚本的文件名和类名必须相同 今天写新功能的时候偶然发现了这个规则的底层逻辑 并且发现这个规则并非必须的,实际上Unity是根据脚 ...
- #凸包,闵可夫斯基和#CF87E Mogohu-Rea Idol
题目 按逆时针顺序给出三个凸包点集 \(\mathbb{A,B,C}\),每次查询给出点 \(D\), 问是否存在点 \(A\in\mathbb{A},B\in\mathbb{B},C\in\math ...
- #线段树,组合计数,二项式定理#CF266E More Queries to Array
洛谷传送门 CF266E传送门 分析 首先区间修改区间查询首选线段树 要找突破口,\((i-l+1)^k\)中\(i\)不是定值, 显然得拆开,而且\(k\)很小,根据二项式定理, \[\sum_{i ...
- 李东山:如何让 OpenHarmony 支持低功耗蓝牙芯片 GR551x
编者按:在 OpenHarmony 生态发展过程中,涌现了大批优秀的代码贡献者,本专题旨在表彰贡献.分享经验,文中内容来自嘉宾访谈,不代表 OpenHarmony 工作委员会观点. 李东山 深圳市汇顶 ...
- XML文档节点导航与选择指南
XPath(XML Path Language)是XSLT标准的主要组成部分.它用于在XML文档中浏览元素和属性,提供了一种强大的定位和选择节点的方式. XPath的基本特点 代表XML路径语言: X ...
- 20个Python 正则表达式应用与技巧
本文分享自华为云社区<Python 正则表达式大揭秘应用与技巧全解析>,作者:柠檬味拥抱. Python 中的 re 模块是用于处理正则表达式的强大工具.正则表达式是一种用来匹配字符串的模 ...
- Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件-Nacos 、Sentinel等
概述 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用服务的必需组件. 方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发 ...
- SpringBoot学习:文件上传和下载
maven导入依赖 首先创建一个maven项目,然后加入以下配置,就创建好了一个springboot项目 <parent> <groupId>org.springframewo ...
- FPGA技术助手,notepad++ 两个插件
DS的时间很珍贵的 ,尤其是过了32岁以后,一身的病,扛不住996的制度.为了增加速度,只能想办法怎么在fpga工作上面降低时间.你有心思点来点去的GUI的界面.还不如用一个脚本完全做完.notepa ...
- 力扣586(MySQL)-订单最多的客户(简单)
题目: 编写一个SQL查询,为下了 最多订单 的客户查找 customer_number . 测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单. 查询结果格式如下所示. 进阶: 如果有多 ...