程序员的自我修养(2)

news2024/11/17 7:32:32

目标文件的学习

1.什么是目标文件以及格式
目标文件为编译器编译后生成的文件,就是window下的.obj,linux下的.o文件。与可执行文件格式几乎一样,因为只是缺少链接过程。所以可执行文件,动态链接库,静态链接库,目标文件广义上都可以算是一个格式,即可执行文件的格式
2.目标文件是怎么样的
目标文件很明显包含编译后的机器指令代码,数据,还包含了链接需要的符号表,调试信息,字符串等等。我们通常以段分隔。
代码段(.code .text):机器指令
数据段(.data):全局变量和局部静态变量
bss段(.bss):未初始化的全局变量和局部静态变量

还有一个部分,文件头
描述整个文件的文件属性,是否可以执行,是静态还是动态链接,目标硬件,目标操作系统等信息。还包括一个段表,描述各个段的数组,各个段在文件中的偏移地址以及段的属性。(这里的段就是指的是代码,数据,bss等段)
(目标文件通常是ELF结构)
3.为什么目标文件需要分段
1.将代码与数据分开,数据和代码被映射到不同的虚拟内存中,可以给其设置不同的权限,保护代码段指令不被修改。
2.缓存在现代计算机地位非常重要,分段能提高缓存的命中概率。
3.增加了存储空间利用率,共享数据。能将系统中运行多个同样的程序只用保存一份指令,数据能够共享。window系统中超过一半是共享部分。
4.以一个程序来讲解各段细节
程序
simply.c

#include<stdio.h>
int global_init_var = 84;
int global_uninit_var;

void func1(int i)
{
	printf("%d\n", i );
}
int main()
{
	static int static_var = 85;
	static int static_var2;
	int a = 1;
	int b;
	func1(static_var+static_var2+a+b);
	return a;
}

经过gcc -c simply.c 得到simply.o
通过objdump工具可以查看.o文件的内容结构

objdump -h simply.o

得到内容(参数-h是将elf文件各个段基本信息打印),很明显分成了.text,.data,.bss,.rodata,.comment,.note.GNU-stack等段,分别为代码,数据,bss,只读数据,注释信息,堆栈提示段。
size为大小,file off起始位置这两行最为重要的信息。,每个段底下的第二行表示段的属性,CONTENTS表示该段在文件中存在等等。
那么实际存在的段为.text,.data,.rodata,.comment(.note段存在但是大小为0)
请添加图片描述
size命令可以获取各个段的大小

size simply.o

其中dec3个段长度的十进制,hex16进制
请添加图片描述

5.代码段
以上面程序为例子
-s将所有段的内容以16进制打印。-d将所有包含指命的段反汇编

objdump -s -d 

结果可以很明显的看出反汇编的结构.text包含的正是funch1和main函数的指令
请添加图片描述
6.数据段与只读数据段
.data段保存的是那些已经初始化的全局变量和局部静态变量
根据程序可以知道为global_init_var与static_var。两个变量都为int类型,故共8个字节。
.rodata存放只读数据,例如printf函数中的%d\n是一种只读数据,就是const修饰的和字符串常量。
由下图.data区内容0x54与0x55刚好对应84与85,就是上面两个变量的值
.rodata区中的25640a00对应ascil表就是%d\n
(注意是16进制,然后我用的是ubunte系统为小端模式)
请添加图片描述
7.bss段
bss段放置的是位初始化的全局变量和静态局部变量
上面程序代码中static_var2与global_uninit_var就是
这里不做多解释,通常c语言有一个步骤叫bss段清零,所以放入bss段的变量初值都是0,如果定义全局变量或静态局部变量值=0,同样放入bss段。
8.其它的段
除了.text,.data,.rodata,.bss这些常见的段,还有一些比较特殊的段,还有被遗弃(不使用了)的段
.comment 编译器版本信息
.debug 调试信息
.dynamic 动态链接信息
.hash 符号哈希表
.line 调试的行号表O
.note 额外的编译器信息
.strtab 存储elf结构用到的各种字符串
.symtab 符号表
.shstrtab 段名表
.plt .got 动态链接的跳转表和全局入口表
.init.fini 程序初始化和终结代码段
这些段都是.开头的,我们也可以自定义段,例如定义music段存放音乐信息,但是不能以.开头
9.ELF文件结构描述
上面我们已经讲了各个段的作用,接下来讲述这些段在ELF怎么放置,还有ELF结构还有那些内容
1.整体结构
ELF Header
.text
.data
.bss

other sections
section header table (段表)
string tables
symbol tables
首先是文件头,描述了整个文件的基本属性,如elf文件版本号,目标机器型号,程序入口地址等。
然后接下来是各个段的内容,其中与段有关的重要结构体就是段表,该表描述了所有段的信息,例如段命,长度,文件偏移,读写权限等
10.段表
我们之前使用的命令只是打印重要的段,例如.text,.data等等
我们现在使用这个命令将会打印段表的信息,即打印所有段的信息

readelf -S   simply.c    

结果
请添加图片描述
由图可以知道,该程序总共10个段,
段表描述了段的信息有10个重要信息
sh_name
段命
sh_type
段的类型
sh_flags
段的标志位
sh_addr
段虚拟地址
sh_offset
段偏移
sh_size
段大小
sh_link
段的链接信息
sh_info
段的链接信息
sh_addralign
段对齐长度
sh_entsize
项的长度
10.重定位表
就是目标程序中有哪些部位需要重定位,就是代码段和数据段内需要重定位的函数或变量
这些重定位信息都记录在.rel.text或.rel.data内
由于我们的程序变量都是存在该程序内,所以没有.rel.data段
但是我们使用了printf函数,是需要在链接的时候重定位的,故存在.rel.text段
(为什么需要重定位,因为一些函数或变量就不存在在主程序中,绝对地址无法调用,需要调用其它.h或.c文件内的变量和函数,我们就需要其定位到正确的位置,去调用,才能正常使用。
11.字符串表
为什么需要字符串表,因为ELF结构里面有太多的字符串变量了,段命,变量名等等,而且大小不定,难以定义,我们可以直接定义一块大的空间,只用给下标,遇到\0就放回字符串,将普通的字符串通通保存,只有给下标直接可以访问。
12.链接的接口-符号
链接的本质就是将多个目标文件之间互相粘到一起,合为一个整体,能够互相使用对方需要的函数与变量,功能模块等。
按正常思考,我们要用一个函数和变量,底层该如何去找到,肯定是要靠地址。无法使用,肯定就是地址不对或没有该函数的地址,故其实本质上就是目标文件之间地址的引用,我找不到,我就问你要,因为你有这个函数或变量的地址。
我们将函数和变量称为符号,函数名与变量名称为符号名。故为什么需要引用的函数和变量一定不能重名,否则报错,就是因为符号重名会导致链接混乱。(这里要注意C++有其特殊性,函数重载,函数可以重名,但参数不能相同)
最后我们每一个目标文件都有符号表,记录了目标文件中使用到的所有符号,每个符号有一个符号值,就是符号的地址,也就是函数或变量的地址。
(我们最关心的是全局符号,因为这些符号最有可能被其它目标文件使用)
13.符号重复的问题
由于C语音和C++语言非常的庞大,我们可能定义一个函数就会导致符号重复,故为了防止重定义,C语言规定了定义一个函数或变量后,都在其前面加‘_’,形成新的符号名,这样就可以简单而原始的解决用户与C库的符号冲突。但程序一但很大,仍然有很大可能重复,故C++考虑到了这个问题,增加名称空间的方法来解决。
上面讲到了函数重载,还有一个情况就是不同类可以有同名同参数函数。
处理其实很简单,函数和变量会根据所处的类和返回值,函数参数不同会先生成一个函数签名,很容易知道,不同的类,函数签名肯定不同,在经过修饰,那么修饰后的符号肯定是不同的,在符号表肯定不会冲突的。

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

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

相关文章

B070-项目实战-用户模块--手机注册

目录 用户模块需求分析静态网站部署与调试两种前端项目的部署两种前端项目的调试(热部署)创建静态web项目 注册分析与设计分析需求设计 界面设计&#xff08;ui&#xff09;设计表&#xff08;后台&#xff09; 流程设计&#xff08;后台&#xff09;三范式表设计流程设计 相关…

英语动词-分类及应用

文章目录 1.实义动词系动词情态动词 1.实义动词 实义动词是表示具体动词的词。 常见的分类&#xff1a;及物动词和不及物动词。 1.及物动词&#xff1a;transitive verb后面直接加宾语&#xff0c;并且必须加宾语。比如&#xff1a;I love you.I buy a book. 2.不及物动词&…

AI 智能对话 - ChatGLM2-6B 本地搭建入门

前情提要 这一个月来干了啥事情呢&#xff1f;AI 绘画搞了2周左右&#xff0c;SD 建筑绘图&#xff0c;训练 LORA &#xff0c;模型控制基本也上手了&#xff0c;可以按照预期生成自己想要的东西&#xff0c;那种控制感是挺开心的&#xff0c;不然你输入一句话生成 AI 图片完全…

Linux进程(三)---深入理解进程地址空间

目录 地址空间的划分及验证 所谓的地址空间是内存吗&#xff1f; 一种奇怪的现象(虚拟地址的引入) 什么是进程地址空间&#xff1f; 我们平常访问到的内存是物理内存吗&#xff1f; 深入理解区域划分 再谈奇怪的现象 fork()中为什么一个变量可以同时保存两个不同的值 …

网络安全—入职大厂经验之谈

大三想去实习&#xff0c;趁现在该干什么才能去大厂实习呢&#xff1f;想做一些事丰富一下自己的简历&#xff0c;只有打ctf&#xff1f;还是挖洞&#xff1f;非常迷茫。 或者入职转行网络安全行业应该怎么做&#xff1f;对于接下来的职业规划学习计划有什么打算&#xff1f; …

PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images

PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images 作者单位 旷视 目的 本文的目标是 通过扩展 PETR&#xff0c;使其有时序建模和多任务学习的能力 以此建立一个 强有力且统一的框架。 本文主要贡献&#xff1a; 将 位置 embedding 转换到 时序表…

漏洞复现 || Bitrix cms文件上传

免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&#xff0c;遵守公共秩序&#xff0c;尊重社会公德&#xff0c;不得利用网络从事危害国家安全、荣誉和利益&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此…

Go语言之流程控制语句,for循环

程序是由语句构成&#xff0c;而流程控制语句 是用来控制程序中每条语句执行顺序的语句。可以通过控制语句实现更丰富的逻辑以及更强大的功能。几乎所有编程语言都有流程控制语句&#xff0c;功能也都基本相似。 其流程控制方式有 顺序结构,分支结构,循环结构 1、switch比if el…

javaWeb之文件上传和下载

文件上传下载(场景): * 文件上传 * 客户端 * 文件上传页面(form) * 请求方式一定是POST. * 文件上传域(<input typefile>)必须具有name属性. * 表单的enctype属性值设置为"multipart/form-data". * 扩展:浏览器内核产品不同(不建…

剖析C语言字符串函数(超全)

目录 前言&#xff1a; 一、strlen函数 功能&#xff1a; 参数和返回值&#xff1a; 注意事项&#xff1a; 返回值是无符号的易错点&#xff1a; strlen函数的模拟实现 1、计数器算法 2、递归算法 3、指针减去指针 二、strcpy函数 功能&#xff1a; 参数和返回值 …

git使用代码

git init //生成一个.git的子目录&#xff0c;产生一个仓库。 git status //查看当前目录下所有文件的状态。 git aad . //将该目录下所有的文件提交到暂存区 git add文件名/将该目录下指定的文件提交到暂存区 git commit -m v1.0//将暂存区的文件提交到版本库 git log //…

网络协议与攻击模拟-21-HTTP协议

HTTP 协议 1、 HTTP 协议结构 2、在 Windows server 去搭建 web 服务器 3、分析 HTTP 协议流量 一、 HTTP 协议 1、概念 HTTP &#xff08;超文本传输协议&#xff09;是用于在万维网服务器上传输超文本&#xff08; HTML &#xff09;到本地浏览器的传输协议 属于 TCP / …

树与图的(深度 + 广度)优先遍历

目录 一、树与图的存储1.树的特性2.图的分类3.有向图的储存结构 二、树与图的深度优先遍历的运用树的重心题意分析代码实现 三、树与图的广度优先遍历的运用图中点的层次题意分析代码实现 一、树与图的存储 1.树的特性 树是一种特殊的图,具有以下两个重要特性: 无环 树是一个…

Redis数据类型 — Set

目录 Set内部实现 源码片段 Set 类型是一个无序并唯一的键值集合&#xff0c;它的存储顺序不会按照插入的先后顺序进行存储。一个集合最多可以存储 2^32-1 个元素。 Set 类型除了支持集合内的增删改查&#xff0c;同时还支持多个集合取交集、并集、差集。Set 的差集、并集和…

Bean 的作用域和生命周期

目录 一、 Bean 的作用域 1. 安装Lombok插件 1.1 Lombok 简介 1.2 Lombok 安装 2. 创建一个 User 对象&#xff0c;然后将 User 对象 存储到 Spring 容器中 2.1 创建User 对象 2.2 将User 对象存储到 Spring 中 2.3 修改 User 对象中的属性&#xff0c;然后看结果&#…

概率论的学习和整理--番外12:2个概率选择比较的题目

目录 1 题目 2 结论 3 算法 3.1 错误算法 3.2 算法1&#xff0c;用期望的方式解方式 3.3 算法2&#xff0c;直接解方程 3.4 算法3&#xff0c;用递归--等比数列求和来算 4 上述比较的意义-回到问题本身 1 题目 题目 3个A合成1个B 方案1&#xff1a;1/4 几率返还一个A…

【ONE·Linux || 地址空间与进程控制(二)】

总言 进程地址空间和进程控制相关介绍。 文章目录 总言2、进程控制续2.3、进程等待2.3.1、为什么需要进程等待2.3.2、阻塞式等待2.3.2.1、使用wait2.3.2.2、使用waitpid2.3.2.3、参数status基本介绍 2.3.3、一些细节与问题</font>2.3.3.1、进程独立性说明2.3.3.1、父进程…

【网络安全带你练爬虫-100练】第13练:文件的创建、写入

目录 目标&#xff1a;将数据写入到文件中 网络安全O 目标&#xff1a;将数据写入到文件中 开干 &#xff08;始于颜值&#xff09;打开一个&#xff0c;没有就会创建 with open(data.csv, modew, newline) as file: &#xff08;忠于才华&#xff09;开始写入数据 writer cs…

LinuxC/C++开发工具——make/makefile和gdb

linux开发工具 前言Linux项目自动化构建工具&#xff08;make/makefile&#xff09;makefile文件的组成如何使用make.PHONY关键字 项目清理 gdb调试器背景使用list&#xff08;l&#xff09;调试命令break&#xff08;b&#xff09;&#xff1a;设置断点info break&#xff1a;…