【链接】深入理解PLT表和GOT表

news2024/12/28 3:47:50

系列综述:
💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。
🥰来源:材料主要源于多处理器编程的艺术进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验自证。
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!
🌈【C++】秋招&实习面经汇总篇


文章目录

    • 概述
      • 二级标签
      • 源代码从静态翻译到动态执行
    • 参考博客


😊点此到文末惊喜↩︎


概述

二级标签

  1. 共享库(shared library)
    • 作用:所有进程共享代码段而各自拥有数据段的私有副本
    • 优点:节省了内存资源,增加了灵活性
  2. 位置无关代码PIC(position-Independent Code)
    • 作用:将程序编译成不同的目标模块, 模块内部的指令和数据。其余指令部分保持不变,而数据部分则在每个进程拥有一个副本。
    • 原理
      • 目标模块内部的指令和数据相对位置是固定的,加载到内存中时可以不需要重定位,通过指令的相对自己的绝对地址进行跳转即可。
      • 目标模块外的指令和数据的引用与重定位到内存的地址有关,需要在运行时进行动态链接。
  3. 进程的加载
    • 综述:Linux系统中的每个进程都是硬盘中的静态程序加载到内存中的动态执行,其中加载的是进程的内存和寄存器映像。
    • 过程:
      • 操作系统的父进程已通过execve("/bin/sh", argc_rc, envp_rv);,将shell程序加载到内存并运行。
      • 当shell运行一个目标程序文件时,父shell进程会fork一个子进程(fork是对父进程状态的一个复制)
      • 子进程通过execve系统调用启动加载器,加载器使用目标程序文件重置子进程的寄存器和虚拟内存映像(Reset子进程的状态机)
      • 最后加载器跳转到_start,开始执行应用程序的main函数
      • 加载器只进行虚拟内存和寄存器映像的Reset,不进行磁盘到内存的数据复制。直到CPU引用一个被映射的虚拟页时才会通过页面调度机制自动从磁盘传送到内存
  4. elf是存储在磁盘中的静态文件,程序执行时所需要的指令和数据必需在内存中才能够正常运行
  5. 如果一个目标模块调用定义在共享库中的任何函数,它就有自己的GOT和PLT,GOT是数据段的一部分,而PLT是代码段的一部分
  6. 延迟绑定
    • 原因:因为一个程序模块通常只会用到共享库中极少量的函数,所以将解析外部模块中的函数内存地址留到实际调用时才进行。
    • 首次调用:跳转到函数对应的PLT项,再跳转到PLT对应的GOT项,GOT在首次调用指向PLT项的第二条指令,再跳回到PLT的第二条指令处开始执行,先将调用函数的ID压入栈中,再将GOT[1]压入栈中,最后通过GOT[2]间接跳转到动态链接器中。动态链接器通过栈中的函数ID和GOT[1]重写函数调用对应的GOT项
    • 再次调用:跳转函数对应的PLT项,再跳转到PLT项对应的GOT项,再通过GOT项跳转到对应的代码段函数
  7. 延迟绑定的实现
    • 全局偏移量表(Global Offset Table/GOT/符号表):
      • 位置:创建数据段开始处(运行中可修改)
      • 内容:前三项存放动态链接器解析相关地址,其他各项均存储本运行模块要引用的一个全局变量或函数的地址
      • GOT表的首地址作为一个基准,用相对于该基准的偏移量来引用静态变量、静态函数
    • 过程链接表(Procedure Linkage Table/PLT)
      • 位置:在代码段中(运行中不可修改)
      • 内容:PLT[0]会将GOT[1](传递给动态链接器的一个参数)压入栈中,再通过GOT[2]间接跳转到动态链接器中。PLT[2]会调用系统启动函数。其余项负责调用一个具体的函数。
  8. 如果一个模块调用其他共享模块中的函数,通常原模块中的函数调用会生成一条重定位记录,然后动态链接器在程序加载时再解析。
  9. 符号表GOT和PLT:统一静态与动态链接,静态链接时模块内部的相对地址,动态链接是通过延迟绑定的间接引用实现的
  10. C++20中的modules进行了模块隔离,不同模块间的函数调用,需要export具体的被调用函数即可,从而增加模块的独立性和编译速度。
  11. 如果系统开启了内存布局随机化ASLR,程序每次运行动态链接库的加载位置都是随机的,就很难通过调试工具直接确定函数的地址

源代码从静态翻译到动态执行

  1. 预处理阶段(Preprocessing)
    • 处理所有预编译指令(以#开头)
      • 删除#inlucde和#define并展开
      • 处理条件预编译指令,比如#if、#ifdef、#elif、#else、#endif等
    • 删除所有注释
    • 添加行号和文件标识
    • 预处理命令:gcc -E hello.c -o hello.i
  2. 编译(Compilation)
    • 词法分析:输入组成源程序的字符流,通过处理输出分解后成为词法单元组成的符号流
    • 语法分析:利用词法单元流构建一颗语法树
    • 语义分析:使用语法树和符号表中的数据,进行类型检查和运算符匹配检查
    • 中间代码生成:生成易于翻译到各种不同平台的机器无关语言
    • 机器无关代码优化:期望使用更长的编译时间换取更高效的目标程序运行
    • 代码生成:使用中间代码生成目标语言
    • 机器相关代码优化:生成更高效的目标机器语言(通常是汇编语言)
  3. 汇编(Assembly)
    • 将汇编语言文件生成可重定位的二进制目标程序
  4. 链接方式
    • 静态链接:将要链接的目标文件生成副本拷贝到可执行文件中,就算把静态库删除也不会影响可执行程序的执行。
      • 优点:运行速度快,删除静态库不影响代码执行。
      • 缺点:库函数修改需要重新链接,同一个链接文件可能在多个可执行程序中都由副本,浪费空间
    • 动态链接:将程序分成独立模块,在执行时再链接形成可执行文件
      • 优点:所有程序共享一个库文件,减少空间浪费。单个文件修改不影响整体执行
      • 缺点:每次执行时进行链接会产生性能损耗
  5. 静态链接器(ld)
    • 原因:现代操作系统通常以动态链接共享库(DLL)的形式进行程序加载,4可以忽略
      • 可重定位的目标文件.o共享库.so进行部分链接生成运行时再完全链接的可执行目标文件
      • 将模块内的位置无关代码进行静态链接,将模块间的符号引用
  6. 加载器(通过execve调用)
    • 部分链接的可执行目标文件共享库重定位到相应内存段,即Reset进程的初始状态
  7. 动态链接器(dynamic linking)
    • 对于模块外部引用的全局变量和全局函数,用 GOT 表的表项内容作为地址来间接寻址 ;对于本模块内的静态变量和静态函数,用GOT 表的首地址作为一个基准,用相对于该基准的偏移量来引用, 因为不论程序被加载到何种地址空间,模块内的静态变量和静态函数与 GOT 的距离是固定的,并且在链接阶段就可知晓其距离的大小。


少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
不如点赞·收藏·关注一波


🚩点此跳转到首行↩︎

参考博客

  1. 动态链接库中与地址无关代码(PIC)对于地址引用的处理
  2. 深入理解计算机系统
  3. 待定引用
  4. 待定引用
  5. 待定引用
  6. 待定引用
  7. 待定引用
  8. 待定引用

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

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

相关文章

nest日志包pino、winston配置-懒人的折腾

nest日志 三种node服务端日志选型 winstonpinolog4js 2023年5月23日 看star数:winston > pino > log4js 使用体验: pino 格式简洁,速度快,支持输入日志到任意数据库,日志暂无自动清理(可能是我…

AI是怎么帮我写代码,写SQL的?(本文不卖课)

近期,ChatGPT风起云涌,“再不入局,就要被时代淘汰”的言论甚嚣尘上,借着这一波创业的朋友都不止3-4个,如果没记错,前几次抛出该言论的风口似乎是区块链,元宇宙,WEB3.0。 画外音&…

动态规划问题实验:数塔问题

目录 前言实验内容实验流程实验过程实验分析伪代码代码实现分析算法复杂度用例测试 总结 前言 动态规划是一种解决复杂问题的方法,它将一个问题分解为若干个子问题,然后从最简单的子问题开始求解,逐步推导出更复杂的子问题的解,最…

绝世内功秘籍《调试技巧》

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 内容专栏:这里是《C知识系统分享》专栏,笔者用重金(时间和精力)打造,基础知识一网打尽,希望可以帮到读者们哦。 内…

CloudQuery v2.0.0 发布 新增数据保护、数据变更、连接管理等功能

哈喽社区的小伙伴们,经过一个月的努力,CloudQuery 社区版发布了全新 v2.0.0系列! 对比 v1.5.0,v2.0.0 在整体 UI 界面上就做了很大调整,功能排布我们做了重新梳理,可以说,社区版 v2.0.0 带领 C…

Linux——makefile自动化构建工具

一. 前言 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能…

数据结构的定义

主要的定义 数据 描述客观事物的数和字符的集合,比如文字,数字和特殊符号 基本单元:数据元素 一个数据单元由若干个数据项构成 数据项:具有独立含义的数据最小单元,也称字段或域 数据元素&…

Spring Boot 中的 Starter 是什么?如何创建自定义 Starter?

Spring Boot 中的 Starter 是什么?如何创建自定义 Starter? Spring Boot 是一个快速构建应用程序的框架,它提供了一种简单的方式来快速启动和配置 Spring 应用程序。Spring Boot Starter 是 Spring Boot 的一个重要概念,它可以帮…

计算机网络详细笔记(四)网际控制报文协议ICMP

文章目录 4.网际控制报文协议ICMP4.1.ICMP报文的种类4.2.ICMP应用举例 4.网际控制报文协议ICMP 网际控制报文协议概述:: 作用:更有效地转发IP数据报和提高交付成功的机会。原理:允许主机或路由器报告差错情况和提供有关异常情况…

maven_SSM项目如何实现验证码功能

验证码的作用 防止恶意注册,自动化程序批量注册。防止暴力破解。 1、这里我们使用goole的验证码生成器 由于直接在maven中引入依赖,没有找到。所以只能直接去下载jar包了。 链接:https://pan.baidu.com/s/1KANhJKI4sQCfkiroTVr0WA?pwd29iv …

Oracle数据库环境变量配置修改数据库密码

1.设置环境变量: 必须设置环境变量才可以用CMD命令访问Oracle数据库 1.1.首先找到你Oracle安装位置路径 C:\app\Administrator\product\11.2.0\dbhome_1 1.2.设置环境变量 1.2.1 设置Adimistrator变量 变量名: ORACLE_HOME 变量值:C:\app…

嵌入式学习之Linux驱动(第九期_设备模型_教程更新了)_基于RK3568

驱动视频全新升级,并持续更新~更全,思路更科学,入门更简单。 迅为基于iTOP-RK3568开发板进行讲解,本次更新内容为第九期,主要讲解设备模型,共计29讲。视频选集 0.课程规划 06:35 1.抛砖引玉-设备模型…

K8s in Action 阅读笔记——【3】Pods: running containers in Kubernetes

K8s in Action 阅读笔记——【3】Pods: running containers in Kubernetes 3.1 Introducing pods 在Kubernetes中,Pod是基本构建块之一,由容器集合组成。与独立部署容器不同,你总是要部署和操作一个Pod。Pod并不总是包含多个容器&#xff0…

Python数据分析案例28——西雅图交通事故预测(不平衡样本处理)

本次案例适合机器学习数据科学方向的同学。 引言(废话集) 交通事故是一个严重的公共安全问题,在全球范围内每年都有成千上万的人死于交通事故。随着交通运输的发展和城市化进程的加速,交通事故已成为制约城市发展和人民幸福的主要因素之一。因此&#x…

【蓝桥杯选拔赛真题57】Scratch计数游戏 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解

目录 scratch计数游戏 一、题目要求 编程实现 二、案例分析 1、角色分析

Java版本企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标…

设计模式之【解释器模式】,用语言定义一门语言

文章目录 一、什么是解释器模式1、常见文法(语法)规则2、抽象语法树3、解释器模式的使用场景4、解释器模式的四大角色5、解释器模式优缺点 二、实例1、解释器模式的一般写法2、数学表达式案例 三、源码中的解释器模式1、Pattern正则2、Spring的Expressio…

jupyter notebook零散操作整理

1 修改Jupyter Notebook打开路径 1.1 永久修改 jupyter notebook --generate-config 打开相应的.py文件,修改c.NotebookApp.notebook_dir 1.2 临时修改 .切换到需要的临时目录,打开jupyter notebook 2 使用Matplotlib绘图时输出矢量图 %config Inli…

MT4期货软件怎么使用?有哪些MT4期货软件使用知识?

现在MT4软件在投资市场上应用广泛,当然也包括期货交易市场,但有不少投资者不知道为什么一定要选择MT4期货软件,其实选择MT4期货软件的理由有很多,MT4作为一款交易软件,不仅能够为投资者提供准确的市场信息,…

PyQt5实现父窗口内点击按钮显示子窗口(窗口嵌套功能)

摘要:在软件中,常会有点击某个按钮,显示一个新的子界面的需求,本文介绍如何在PyQt5中实现这一功能,主要涉及知识点是“信号与槽函数的自动绑定”。 程序说明: 1.开发环境:win10系统&#xff0c…