可执行文件以及其加载过程

news/2024/7/25 20:28:01/文章来源:https://blog.csdn.net/qq_52010229/article/details/139280215

在计算机系统中,可执行文件是指包含机器代码的文件,计算机可以直接执行这些代码以运行特定的任务或程序。不同的操作系统对可执行文件有不同的定义和处理方式。本文将探讨常见操作系统中的可执行文件格式及其加载过程,特别是以ELF(Executable and Linkable Format)文件格式为例,深入了解其动态库加载过程。同时,我们还将介绍静态链接和动态链接的区别。

可执行文件简介

可执行文件是程序经过编译和链接后生成的文件,其中包含了机器指令、数据和必要的元信息,使得操作系统能够加载并执行该程序。不同操作系统使用不同的可执行文件格式:

  • Windows:使用PE(Portable Executable)格式,文件扩展名通常为.exe.dll
  • macOS:使用Mach-O(Mach Object)格式,文件扩展名通常为.app.dylib
  • Linux:使用ELF(Executable and Linkable Format)格式,文件扩展名通常为没有特定的要求,但共享库使用.so

ELF 文件格式

ELF文件格式是用于Linux和其他Unix-like操作系统的标准文件格式,适用于可执行文件、目标文件和共享库。ELF文件由多个部分组成,每个部分包含不同类型的数据,主要结构包括:

  1. ELF Header(ELF头)

    • 包含了文件类型、架构、入口点等基本信息。
    • 关键字段包括e_ident、e_type、e_machine、e_entry等。
  2. Program Header Table(程序头表)

    • 描述了文件中各个程序段的位置和属性。
    • 关键字段包括p_type、p_offset、p_vaddr、p_filesz等。
  3. Section Header Table(节头表)

    • 描述了文件中各个节的位置和属性。
    • 关键字段包括sh_name、sh_type、sh_flags、sh_addr等。
  4. Sections(节)

    • 各种类型的数据段,如代码段(.text)、数据段(.data)、只读数据段(.rodata)、未初始化数据段(.bss)。

ABI(Application Binary Interface)

ABI是定义应用程序在特定操作系统和硬件架构上运行的二进制接口的约定。它包括数据类型大小和对齐、函数调用约定、系统调用接口、二进制文件格式等。不同的操作系统和架构有各自的ABI规范,确保应用程序的二进制兼容性。

  • Windows ABI

    • 使用PE文件格式。
    • 定义了多种调用约定,如stdcall、cdecl、fastcall。
    • 使用WinAPI作为主要的系统调用接口。
    • 常用C标准库实现包括MSVCRT。
  • macOS ABI

    • 使用Mach-O文件格式。
    • 使用System V AMD64 ABI调用约定。
    • 使用POSIX标准系统调用接口,扩展了一些特有的系统调用。
    • 使用libSystem作为C标准库实现。

ELF 文件格式在 ABI 中的作用

ELF文件格式是ABI的重要组成部分,规定了二进制文件的结构,确保操作系统能够正确加载和执行应用程序。具体而言:

  • 标准文件格式:定义了可执行文件、目标文件和共享库的标准文件格式,确保二进制兼容性。
  • 程序头表和节头表:定义了二进制文件中各个段和节的布局。
  • 符号表和重定位信息:提供了符号解析和重定位的必要信息。
  • 动态链接:支持动态链接,通过动态库实现代码共享和内存节省。
  • 系统调用和C库接口:通过ELF文件描述库文件的结构,确保应用程序与操作系统接口一致。

静态链接与动态链接

在编译和链接过程中,静态链接和动态链接是两种不同的方法,用于将程序代码和库代码组合在一起。

静态链接
  • 定义:在编译时将所有使用到的库函数代码复制到最终的可执行文件中。
  • 优点
    • 运行时不需要外部库,所有代码都在一个可执行文件中。
    • 可以避免由于库版本变化导致的兼容性问题。
  • 缺点
    • 可执行文件体积较大,因为包含了所有依赖的库代码。
    • 无法在运行时更新或替换库,更新程序需要重新编译整个可执行文件。
动态链接
  • 定义:在运行时将库代码加载到内存中,并与可执行文件链接。
  • 优点
    • 可执行文件体积较小,因为库代码不包含在可执行文件中。
    • 可以在运行时更新或替换库,更新程序只需要替换库文件而不需要重新编译整个可执行文件。
    • 多个程序可以共享同一个库的实例,节省内存。
  • 缺点
    • 运行时依赖于外部库文件,缺少库文件或库版本不兼容可能导致程序无法运行。
    • 动态链接和符号解析会增加一些运行时开销。

ELF 动态库加载过程

在Linux系统中,加载共享库(.so文件)的过程涉及多个步骤,包括解析、映射、符号解析和重定位。以下是详细的加载过程:

  1. 启动程序

    • 操作系统首先加载可执行文件到内存中,读取其ELF头部信息,找到动态段(.dynamic)。
  2. 加载器(Loader)

    • 加载器读取程序头表,找到动态段信息,指示需要加载哪些共享库。
  3. 查找共享库

    • 加载器根据动态段信息查找共享库,路径包括DT_RUNPATH、LD_LIBRARY_PATH和系统默认路径。
  4. 映射共享库

    • 使用mmap将共享库的各个段映射到进程的虚拟地址空间。
  5. 解析符号

    • 加载器解析共享库中的符号,确保所有符号都能在内存中找到。
  6. 重定位(Relocation)

    • 处理重定位条目,调整代码和数据指针,使其指向正确的内存地址。
  7. 调用初始化函数

    • 调用共享库的初始化函数,完成库的初始化。

动态链接器(Dynamic Linker)

动态链接器(如ld.sold-linux.so)是负责加载和链接共享库的程序。在程序启动时,操作系统会先加载动态链接器,然后由动态链接器负责加载所有需要的共享库并进行符号解析和重定位。

示例:动态库加载过程

假设有一个可执行文件app依赖于共享库libfoo.solibbar.so,加载过程如下:

  1. 启动app

    • 操作系统加载app的ELF文件,读取其程序头表,找到动态段。
    • 动态段指示需要加载libfoo.solibbar.so
  2. 查找libfoo.solibbar.so

    • 加载器按顺序查找LD_LIBRARY_PATHDT_RUNPATH和系统默认路径,找到共享库文件。
  3. 映射共享库

    • 使用mmap将共享库的各个段映射到进程的虚拟地址空间。
  4. 解析符号

    • 动态链接器解析共享库中的符号,确保所有符号都能在内存中找到。
  5. 重定位

    • 处理重定位条目,更新内存中的地址使其指向正确的目标。
  6. 调用初始化函数

    • 调用共享库的初始化函数,完成库的初始化。

总结

可执行文件是操作系统运行程序的核心文件类型,不同操作系统有不同的可执行文件格式和加载方式。ELF文件格式是Linux和其他Unix-like操作系统的标准文件格式,通过详细的结构和动态链接支持,实现了程序的高效加载和运行。静态链接和动态链接是两种不同的链接方法,各有优缺点。了解这些技术和过程,对于系统编程和跨平台开发至关重要。

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

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

相关文章

[C][动态内存分配][柔性数组]详细讲解

目录 1.动态内存函数的介绍1.malloc2.free2.calloc4.realloc 2.常见的动态内存错误3.C/C程序的内存开辟4.柔性数组1.是什么?2.柔性数组的特点3.柔性数组的使用4.柔性数组的优势 1.动态内存函数的介绍 1.malloc 函数原型:void* malloc(size_t size)功能…

流水账(CPU设计实战)——lab3

Lab3 Rewrite V1.0 版本控制 版本描述V0V1.0相对V0变化: 修改了文件名,各阶段以_stage结尾(因为if是关键词,所以module名不能叫if,遂改为if_stage,为了统一命名,将所有module后缀加上_stage&a…

Java | Leetcode Java题解之第118题杨辉三角

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret new ArrayList<List<Integer>>();for (int i 0; i < numRows; i) {List<Integer> row new…

《探索Stable Diffusion:AI绘画的创意之路与实战秘籍》

《Stable Diffusion AI 绘画从提示词到模型出图》介绍了 Stable Diffusion AI 绘画工具及其使用技巧。书中内容分为两部分&#xff1a;“基础操作篇”&#xff0c;讲解了 SD 文生图、图生图、提示词、模型、ControlNet 插件等核心技术的应用&#xff0c;帮助读者快速从新手成长…

基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善

前言 紧接上篇->基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善-CSDN博客 本篇将完善主界面的管理员入库和出库功能&#xff0c;同样的&#xff0c;管理员入库和出库的设计套路适用于动态表的录入和编辑 首先还是介绍一下本项目将要实现的功能 &#xf…

【Oracle】PL SQL 怎么重新编译无效的对象

1.打开PL SQL &#xff0c;点击图中有红色的 2.点击齿轮按钮即可 from&#xff1a;【Oracle】PL SQL 怎么重新编译无效的对象_plsql编译无效对象的按钮在哪里-CSDN博客

openresty(Nginx) 隐藏 软包名称及版本号 升级版本

1 访问错误或者异常的URL 2 修改配置&#xff0c;重新编译&#xff0c;升级 #修改版本等 vim ./bundle/nginx-1.13.6/src/core/nginx.h #define nginx_version 1013006 #define NGINX_VERSION "1.13.6" #define NGINX_VER "openresty/&q…

C++线程任务队列模型

功能描述 实现一个任务队列&#xff0c;用于任务的执行 任务队列 任务队列可以添加、删除任务&#xff0c;实现对任务的管理添加任务后&#xff0c;任务队列可以开始执行任务队列执行任务方式为串行执行 任务 任务执行需要持续一段10s内随机的时间&#xff0c;执行过程通过…

如何批量提取pdf文件名?批量提取文件夹里的文件名,只要用对方法!

在数字化时代&#xff0c;PDF文件已经成为我们日常工作中不可或缺的一部分。然而&#xff0c;随着PDF文件数量的不断增加&#xff0c;如何高效地管理这些文件成为了一个挑战。批量提取PDF文件名&#xff0c;就是解决这一问题的关键所在。本文将为你介绍几种实用的方法&#xff…

【小呆的力学笔记】连续介质力学的知识点回顾二:应变度量

文章目录 3. 格林应变与阿尔曼西应变 3. 格林应变与阿尔曼西应变 变形体在变形前的线元 O A → \overrightarrow{OA} OA &#xff0c;在变形后变成 o a → \overrightarrow{oa} oa &#xff0c;那么应变应该度量这种线元变形前后的差别。 ∣ o a → ∣ 2 − ∣ O A → ∣ 2 …

【Qt秘籍】[004]-Qt中的重要工具-介绍

QtCreator概览 当我们打开系统的菜单翻到刚刚下载的Qt文件&#xff0c;里面的内容却让我们眼花缭乱。 不过别急&#xff0c;下面我们将一一解析。 1.Assistant Qt自带的离线版本官方文档 2.Designer Qt图形化设计界面的工具&#xff0c;通过拖拽控件快速生成界面&#xff0c…

SpirngMVC框架学习笔记(一):SpringMVC基本介绍

1 SpringMVC 特点&概述 SpringMVC 从易用性&#xff0c;效率上 比曾经流行的 Struts2 更好 SpringMVC 是 WEB 层框架&#xff0c;接管了 Web 层组件, 比如控制器, 视图, 视图解析, 返回给用户的数据格式, 同时支持 MVC 的开发模式/开发架构SpringMVC 通过注解&#xff0c;…

【DrissionPage爬虫库 1】两种模式分别爬取Gitee开源项目

文章目录 DrissionPage爬虫库简介1. 浏览器操控模式&#xff08;类似于游戏中的后台模拟鼠标键盘&#xff09;2. 数据包收发模式&#xff08;类似于游戏中的协议封包&#xff09; 实战中学习需求&#xff1a;爬取Gitee开源项目的标题与描述解决方案1&#xff1a;用数据包方式获…

[机缘参悟-191] - 《道家-水木然人间清醒1》读书笔记 -14- 关系界限 - 经济和人格上的独立,走向成熟的必经之路,才能更好的谈其他情感(IT)

目录 前言&#xff1a; 1、“友善的孤独者” 2、“外向的孤独者” 3、道不同不相为谋 4、警惕依赖 5、完整独立的个体 6、不必纠正他人的错误&#xff0c;除非他影响了你 7、不再期待别人能理解自己&#xff0c;只有高维向下兼容你的人才能理解你 8、只有高维和同频的…

基于语音识别的智能电子病历(三)之 Soniox

Soniox成立于2020年&#xff0c;目前总部位于美国加州福斯特城&#xff0c;该公司开发了市场上最好的语音识别引擎之一。该公司目前提供市面上领先的云转录引擎之一——这也是audioXpress成功用于采访和一般语音转文本转换的引擎。 专注于语音AI的Soniox在2021年推出了世界上第…

据库管理-第196期 实战RDMA(20240528)

数据库管理196期 2024-05-28 数据库管理-第196期 实战RDMA&#xff08;20240528&#xff09;1 环境2 操作系统配置3 配置NVMe over RDMA4 挂载磁盘处理并挂载磁盘&#xff1a; 5 RDMA性能测试6 iSCSI部署7 iSCSI性能测试8 性能对比总结 数据库管理-第196期 实战RDMA&#xff08…

Petalinux 制作ZYNQ镜像文件流程

1概述 在Zynq-7000 SoC中搭建运行Linux&#xff0c;嵌入式软件栈。 处理器系统引导是一个分两个阶段的过程。第一个阶段是一个内部 BootROM&#xff0c;它存储 stage-0 的引导代码。BootROM 在 CPU 0 上执行&#xff0c;CPU 1 执行等待事件&#xff08;WFE&#xff09;指令。…

【全开源】宇鹿家政系统(FastAdmin+ThinkPHP+原生微信小程序)

&#xff1a;助力家政行业数字化升级 一、引言&#xff1a;家政服务的新篇章 随着移动互联网的普及和人们生活水平的提高&#xff0c;家政服务的需求日益增长。为了满足这一市场需求&#xff0c;并推动家政行业的数字化升级&#xff0c;我们特别推出了家政小程序系统源码。这…

这款信创FTP软件,可实现安全稳定的文件传输

信创&#xff0c;即信息技术应用创新&#xff0c;2018年以来&#xff0c;受“华为、中兴事件”影响&#xff0c;国家将信创产业纳入国家战略&#xff0c;并提出了“28n”发展体系。“8”具体指金融、石油、电力、电信、交通、航空航天、医院、教育等主要行业。目前企业使用比较…

代码随想录——左叶子之和(Leetcode404)

题目链接 BFS 队列 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right)…