Linux C目标文件

LinuxC目标文件


宗旨:技术的学习是有限的,分享的精神是无限的。


一、目标文件格式(ELF格式)

编译器编译源代码后生成的文件叫做目标文件。目标文件是已经编译后的可执行文件,只是还没有经过链接的过程。

PC平台流行的可执行文件格式:windows下的PE和Linux下的ELF。

动态链接库和静态链接库也是按照可执行文件存储的。

1ELF文件归于4类:

ELF文讲类型

说明

举例

可重定位文件

目标文件.o

Linux的.o, windows下的.obj

可执行文件

直接可执行的文件

/bin/bash   windows的.exe

共享目标文件

 

.so   DLL

核心转储文件

进程意外终止

core dump

Linux下的file命令查看相应的文件格式:



2、目标文件

编译后的机器指令代码、数据、符号表、调试信息、字符串等。

一般目标文件将这些文件信息按不同的属性,以“节”的形式存储。

机器指令放在代码段.text,已初始化全局变量和静态变量放在数据段里.data,未初始化全局变量和静态变量放在数据段里.bss。.bss只是为变量预留的位置而已,并没有内容,不占据空间。

  

二、剖析目标文件section.o

// section.c:
#include<stdio.h>int init_var = 84;
int uninit_var;void fun(int i)
{printf(" %d \n", i);
}int main(void)
{static int static_var = 85;static int static_var2;int a = 1;int b;fun(init_var + uninit_var + a + b);return 0;
}

gcc  -c  section.c生成section.o——只编译不链接 

objdump  -h  section.o// ELF文件的各个段的基本信息打印出来。


除了最基本的代码段、数据段、BSS段,还有三个段:只读数据段(.rodata)、注释信息段(.comment)和堆栈提示段(.note.GNU-stack)。

段的属性:最容易理解的就是段的长度Size和段所在的位置File off(偏移量)。每个段第二行的“CONTENTS”表示该段在文件中存在——BSS段没有“CONTENTS “,实际上在ELF中不存在;”note.GNU-stack“有“CONTENTS”但大小为0,奇怪。

 

size命令查看ELF文件中的代码段、数据段和BSS段长度。

root@colinux:~/mystudy# size section.o

   text    data    bss     dec     hex filename

   88      8       4     100     64 section.o

 

1、代码段

         objdump的“-s”十六进制方式打印,“-d”反汇编。提取出代码段的内容:

 

“Contents of section.text”就是.text的数据以十六进制方式打印出来的内容,0x58字节,与size命令的长度符合。对照反汇编结果,.text包含两个函数,fun()和main()。.text的第一个字节就是”0x55”就是fun()函数的第一条“push   %ebp”指令,而最后一个字节0xc3正是main()函数的最后一条指令“ret”。


2、数据段和只读数据段

         .data段保存的是初始化的全局变量和静态变量,section.c中有这样两个变量init_var和static_var,都是int型,刚好8字节。所以.data的大小是8字节。

Contents of section .data:

 0000 54000000 55000000                    T...U...       

Contents of section .rodata:

 0000 20256420 0a00                         %d ..  

.data前四个字节,0x54、0x00、0x00、0x00 —— 0x54 = 84;——大端机

 

3BSS

         .bss段保存的是未化的全局变量和静态变量,section.c中有这样两个变量uninit_var和static_var2。但是通过size命令看到.bss只有4字节。通过符号表(后面说)看到,只有static_var2被放入了.bss段,uninit_var没有。与不同的语言和不同的编译器有关。

 

4、其他段        

常用段名

说明

.rodata

只读数据,如字符串常量,const只读变量

.comment

编译器版本信息,

.debug

调试信息

.dynamic

动态链接信息

.hash

符号哈希表

.line

行号表

.note

额外的编译器信息:公司名,发布版本号等

.strtab

字符串表

.symtab

符号表

.shstrtab

段名表

.plt   .got

动态链接的跳转表和全局入口表

.init  .fini

程序初始化与终结代码段

 

三、ELF文件结构

         提取重要的结构:ELFHeaderELF文件头)、.text.data.bss、其他段、段表、字符串表、符号表等。

ELF文件头——描述了整个文件的文件属性:是否可执行、是静态还是动态连接及入口地址、目标硬件、目标操作系统等信息。

段表——所有段的信息:段名、段的长度、在文件中的偏移、读写权限及段的其他属性。

 

1、文件头(readelf命令) 


ELF文件头定义:ELF魔数、文件机器字节长度、文件存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口地址和长度、段表的位置和长度及段的数量等。

ELF文件头结构及相关常数被定义在”/usr/include/elf.h”,32位“ELF32_Ehdr

#define EI_NIDENT(16)typedef struct
{unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */Elf32_Half   e_type;                 /* Objectfile type */Elf32_Half   e_machine;              /*Architecture */Elf32_Word   e_version;              /* Object file version */Elf32_Addr   e_entry;                /* Entrypoint virtual address */Elf32_Off    e_phoff;                /* Programheader table file offset */Elf32_Off    e_shoff;                /* Sectionheader table file offset */Elf32_Word   e_flags;                /*Processor-specific flags */Elf32_Half   e_ehsize;               /* ELFheader size in bytes */Elf32_Half   e_phentsize;            /* Programheader table entry size */Elf32_Half   e_phnum;                /* Program header table entrycount */Elf32_Half   e_shentsize;            /* Sectionheader table entry size */Elf32_Half   e_shnum;                /* Sectionheader table entry count */Elf32_Half   e_shstrndx;             /* Sectionheader string table index */
} Elf32_Ehdr;

结构与readelf输出的ELF文件头信息相比:只有e_ident对应了readelf输出中的“Class  Data  Version OS/ABI  ABI Version”5个参数,剩下的参数一一对应。

ELF魔数:Magic:  7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00  

16字节对应了Elf32_Ehdr的e_ident这个16字节成员。这16字节被ELF标准规定来标识ELF文件的平台属性:如字长、字节序、版本等。16字节含义:

前4字节是所有ELF文件都必须相同的标识码:0x7F、0X45、0X4C、0X46(这四个字节就是ELF文件的魔数)。几乎所有的可执行文件的开始的几个字节都是魔数,如a.out最开始两个字节是0x01、0x07;PE最开始两个字节是0x4d、0x5a。这个魔数用来确认文件类型。第5个字节用来标识ELF文件类的,0x01表示是32位的,0x02表示64位的。第6字节是字节序,规定ELF文件是大端的还是小端的。第7字节规定ELF文件的主版本号,一般是1.后面的九个字节ELF标准没有定义,一般写0。

e_type文件类型:ET_REL—— 1 ——可重定位文件,一般是.o文件;ET_EXEC—— 2 —— 可执行文件; ET_DYN —— 2 ——共享目标文件,一般是.so文件。

e_machine机器类型:ELF文件的平台属性,EM_386 —— 3 —— x86

 

2、段表

ELF的段结构就是由段表决定的,编译器、连接器和装载器都是靠段表来定位和访问各个段的属性的。段表在ELF文件中的位置由ELF文件头Elf32_Ehdr结构中的” e_shoff” 成员决定。section.o中,段表位于偏移0x104(260字节)处。

前面用”objdump -h”查看ELF文件中的段,此命令只是把ELF文件中的关键段显示出来了,省略了其他辅助性的段:符号表、字符串表、重定位表等。

readelf -S命令


段表是以“Elf32_Shdr”结构体为元素的数组,数组元素的个数等于段的个数,每个“Elf32_Shdr”结构体对应一个段。section.o:11个元素的数组。/usr/include/elf.h:

typedef struct
{Elf32_Word    sh_name;                /* Section name (string tblindex) */Elf32_Word    sh_type;                /* Section type */Elf32_Word    sh_flags;               /* Section flags */Elf32_Addr     sh_addr;                /* Section virtual addr atexecution */Elf32_Off       sh_offset;              /* Section file offset */Elf32_Word    sh_size;                /* Section size in bytes */Elf32_Word    sh_link;                /* Link to another section */Elf32_Word    sh_info;                /* Additional sectioninformation */Elf32_Word    sh_addralign;           /* Section alignment */Elf32_Word    sh_entsize;             /* Entry size if section holdstable */
} Elf32_Shdr;

总结section.o段表的位置

 

起始地址

大小

ELF Header  e_shoff = 0x104

0

0x34

.text

0x34

0x52

.data

0x88

0x08

.rodata

0x90

0x06

.comment

0x96

0x1d

.shstrtab

0xB3

0x51

Section Table

0x104

0x1b8

.symtab

0x2bc

0xf0

.rel.text

0x3fc

0x28

长度为0x424 = 1060,这个长度正好是section.o文件的大小。

段的类型(sh_type):段的名字只有在编译和链接的过程中有意义。SHT_NULL – 0 – 无效段, SHT_PROGBITS– 1 – 程序段, SHT_SYMTAB – 2 – 表示该段的内容为符号表, SHT_STRTAB – 3 – 字符串表, SHT_RELA –4 – 重定位表, SHT_HASH – 5 – 符号表的哈希表,SHT_DYNAMIC – 6 – 动态链接信息, SHT_NOTE – 7 – 提示性信息, SHT_NOBITS– 8 –该段在文件中没内容, SHT_REL – 9 –该段包含了重定位信息,SHT_SHLIB – 10 – 保留,SHT_DNYSYM – 11 – 动态链接的符号表。

段的标志位(sh_flag):表示该段在进程虚拟地址空间中的属性,可写可执行等。SHF_WRITE – 1 – 该段在进程空间中可写; SHF_ALLOC– 2 – 在进程空间中要分配空间; SHF_EXECINSTR– 4 –该段在进程空间中可以被执行,一般指代码段。

         段的链接信息(sh_link、sh_info):

sh_type

sh_link

sh_info

SHT_DYNAMIC

字符串表在段表的下标

0

SHT_HASH

符号表在段表中的下标

0

SHT_REL

相应符号表在段表中的下标

该重定位表所作用的段在段表中的下标

SHT_RELA

SHT_SYMTAB

操作系统相关

操作系统相关

SHTDYNSYM

other

SHN_UNDEF

0

 

3、重定位表

         section.o中有一个“rel.text”的段,类型是“SHT_REL”——重定位表。

代码段和数据段中那些对绝对地址的引用的位置——相应的重定位表。section.o中的“rel.text”就是对“.text”段的重定位表——printf函数的调用;而“.data”段没有对绝对地址的引用,只包含了几个常量,故没有“.rel.data”。

 

4、字符串表——段名,变量名等

 

四、链接的接口——符号

         可以使用很多工具查看ELF文件的符号表,readelfobjdumpnm等;

1ELF符号表结构

         ELF符号表是文件中的一个段“.symtab”

/* Symbol table entry.  */
typedef struct
{Elf32_Word    st_name;                /* Symbol name (string tblindex) */Elf32_Addr    st_value;               /* Symbol value */Elf32_Word    st_size;                /* Symbol size */unsigned char st_info;                /* Symbol type and binding */unsigned char st_other;               /* Symbol visibility */Elf32_Section st_shndx;               /* Section index */
} Elf32_Sym;


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

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

相关文章

Win2003下Exchange2003部署图解之七

Exchange 2003 基本配置在邮件服务器SERVERVM下打开“第一个存储组”&#xff0c;&#xff08;这里我们只看到一个缺省的存储组&#xff0c;在Exchange2003标准版中我们只能建立一个存储组&#xff0c;而企业版中我们可以建立4个存储组&#xff09;选择“邮箱存储”&#xff0c…

嵌入式Linux操作UART实例

1引言串口是我们实际工作中经常使用的一个接口&#xff0c;比如我们在Linux下使用的debug串口&#xff0c;它用来登录Linux系统&#xff0c;输出log。另外我们也会使用串口和外部的一些模块通信&#xff0c;比如GPS模块、RS485等。这里对Linux下串口使用做个总结&#xff0c;希…

Datawhale组队-Pandas(下)文本数据(打卡)

一、string类型的性质 1.string和object的区别 string类型和object不同之处有三&#xff1a; 字符存取方法&#xff08;string accessor methods&#xff0c;如str.count&#xff09;会返回相应数据的Nullable类型&#xff0c;而object会随缺失值的存在而改变返回类型某些Se…

sql语句遇到的问题

分别统计所有男同学的平均分&#xff0c;所有女同学的平均分及总平均分 //SELECT AVG(score),name,(SELECT AVG(score) FROM student) as 总平均分 from student GROUP BY sex; 按照分数从小到大的顺序打印分数大于总平均分的学员信息(id-name-sex-score),并将分数大于总平均分…

新唐单片机代码评审总结

昨晚上&#xff0c;我们一个同事组织了一个小会议&#xff0c;大家一起讨论了一个项目的单片机代码&#xff0c;这个单片机用的是新唐单片机&#xff0c;期间大家也讨论了一些问题&#xff0c;总结一下&#xff0c;希望对写单片机的同学们有帮助。我这个同事写的代码非常优秀&a…

Datawhale组队-Pandas(下)分类数据(打卡)

Categoricals是pandas的一种数据类型&#xff0c;对应于统计学中的Categorical variables&#xff08;分类变量&#xff09;&#xff0c;分类变量是有限且固定的可能值&#xff0c;例如&#xff1a;gender&#xff08;性别&#xff09;、血型、国籍等&#xff0c;与统计学的Cat…

【分享】一个集成tracert和ping的网络监测工具

最近接到一个需求&#xff0c;需求背景是这样的&#xff1a;目前Windows平台下本身都有tracert和ping的实现&#xff0c;而且可以直接在cmd下使用。 需求中有两个要求&#xff1a; 1. Windows平台中的tracert执行速度太慢&#xff0c;一次tracert可能要花十几分钟。所以&#x…

秀操作 | 函数宏的三种封装方式

作者&#xff1a;☆星轨★ 链接&#xff1a;https://blog.csdn.net/qq_35692077/article/details/1029949591. 函数宏介绍函数宏&#xff0c;即包含多条语句的宏定义&#xff0c;其通常为某一被频繁调用的功能的语句封装&#xff0c;且不想通过函数方式封装来降低额外的弹栈压…

Datawhale组队-Pandas(下)时序数据(打卡)

Pandas可以处理任何领域的时序数据&#xff08;time series&#xff09;&#xff0c;使用Numpy的datetime64 和timedelta64 类型&#xff0c;Pandas整合了来自其他Python库的大量功能&#xff0c;如Scikits.TimeSeries&#xff0c;并为处理时间序列数据创建了大量新功能。 一、…

解析一个C语言俄罗斯方块游戏,包你看了就会

最近在看俄罗斯方块的游戏&#xff0c;看到一个大神写的俄罗斯方块代码&#xff0c;非常非常优秀&#xff0c;拿出来解析给大家看看&#xff0c;也希望大家自己尝试运行试试&#xff0c;从中能得到一些启发。#先了解下俄罗斯方块的几个形状一共分成 7 形状&#xff0c;有的形状…

认识星座、八大行星的观察

1. 北斗七星 北斗七星属于大熊座&#xff0c;春夏可见&#xff1b;2. 八大行星 太阳系的八大行星基本位于同一轨道面&#xff0c;如以地球轨道面为基准&#xff0c;相互间轨道倾角的差距甚至不到5度&#xff08;不包括水星&#xff09;。太阳系各大行星公转平面与地球黄道平面的…

Datawha组队——Pandas(下)综合练习(打卡)

import pandas as pd import numpy as np import missingno as msno import matplotlib.pyplot as plt plt.rcParams[font.sans-serif][SimHei] #用来正常显示中文标签 plt.rcParams[axes.unicode_minus]False #用来正常显示负号#读取数据 df pd.read_csv(端午粽子数据.csv) d…

测试内存对齐对运行速度的影响

我们知道内存对齐是为了方便CPU工作&#xff0c;但是对齐和不对齐差异有多大呢&#xff1f;我自己也没有实际测试过&#xff0c;今天就运行个代码测试看看。1、1字节对齐的时候#include "stdio.h"#pragma pack(1) struct test { char x1; short x2; float x3; …

Datawhale-零基础入门NLP-新闻文本分类Task01

参考&#xff1a; https://www.jianshu.com/p/56061b8f463a 统计自然语言处理 宗成庆&#xff08;第二版&#xff09; 文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题.传统的文本分类是基于文本内容的,研究如何将文本自动划分为…

华为海选开发者状元?还送14件豪礼?

华为云全年最大 最大 最大开发者庆典活动来啦&#xff01;这次庆典没别的&#xff0c;就是&#xff1a;好玩&#xff01;刺激&#xff01;让你拿奖拿到怀疑人生&#xff01;贺岁就要有贺岁的样子~赶紧来看看华为云为开发者们准备了怎样的新年惊喜好玩的在这里&#xff01;上学的…

Datawhale-零基础入门NLP-新闻文本分类Task02

Task01里边对赛题进行了分析,接下来进行数据读取与数据分析&#xff0c;通过使用Pandas库完成数据读取和分析操作。 1 数据读取 由赛题数据格式可知&#xff0c;可通过read_csv读取train_set.csv数据&#xff1a; import pandas as pd import numpy as np import matplotlib…

一步步分析-C语言如何面向对象编程

这是道哥的第009篇原创一、前言在嵌入式开发中&#xff0c;C/C语言是使用最普及的&#xff0c;在C11版本之前&#xff0c;它们的语法是比较相似的&#xff0c;只不过C提供了面向对象的编程方式。虽然C语言是从C语言发展而来的&#xff0c;但是今天的C已经不是当年的C语言的扩展…

Datawhale-零基础入门NLP-新闻文本分类Task03

文本是不定长度的&#xff0c;文本表示成计算的能够运算的数字或向量的方法称为词嵌入&#xff08;Word Embedding&#xff09;。词嵌入是将不定长的文本转换成定长的空间中。为了解决将原始文本转成固定长度的特征向量问题&#xff0c;scikit-learn提供了以下方法&#xff1a;…

Linus 在圣诞节想提前放假做了这些解释,哈哈哈

最近在 lkml.org 上看到Linus发布的一个信息&#xff0c;挺有意思的&#xff0c;我看了内容&#xff0c;然后根据自己的理解展示给大家看看&#xff0c;如果有不对的地方欢迎指正。好的&#xff0c;5.10内核发布了我真希望在圣诞节来的最后一个星期没有那么多破事&#xff0c;现…

eleemnt-ui修改主题颜色

饿了吗的element-ui使用的是淡蓝色的主题&#xff0c;有时候我们可以自定义主题&#xff0c;官方的文档给我们提供了如何修改主题&#xff0c;介绍的很详细&#xff0c;自己试验过后&#xff0c;觉得很不错&#xff0c;一方面怕忘记&#xff0c;一方面写一写。 方法一是在线生成…