bin、hex、exe、elf文件类型到底有何区别?如何解读hex文件和elf文件?...相关内容都在这里!

《嵌入式工程师自我修养/C语言》系列——bin、hex、exe、elf文件类型到底有何区别?readelf用法全面解读!

  • 一、常见文件类型之:bin、hex、elf、exe
    • 1.1 bin、hex、exe、elf文件类型到底有何区别?
    • 1.2 如何读懂一份hex文件?(hex文件格式详细解读)
      • 1.2.1 每行的结构
      • 1.2.2 记录类型(Record type)
      • 1.2.3 校验和的计算
      • 1.2.4 实例解析
    • 1.3 如何实现bin文件和hex文件的相互转换?
      • 1.3.1 linux环境下
      • 1.3.2 linux环境下bin转hex如何指定起始地址?
      • 1.3.2 Windows环境下
  • 二、readelf常见用法解读
    • 2.1 elf文件及其组成结构
    • 2.2 readelf常见用法详解

快速学习嵌入式开发其他基础知识?>>>>>>>>> 返回专栏总目录 《嵌入式工程师自我修养/C语言》<<<<<<<<<

Tip📌:鼠标悬停双虚线关键词/句,可获得更详细的描述

一、常见文件类型之:bin、hex、elf、exe

1.1 bin、hex、exe、elf文件类型到底有何区别?

  在嵌入式软件开发中,不同的文件格式承载着不同的信息和用途。了解这些文件格式的差异对于开发人员来说是非常重要的,特别是对于那些处理固件编写、调试和程序部署的开发者。以下是几种常见文件格式(bin、hex、elf、exe)的详细描述和它们之间的主要区别:

类型定义用途特点
BIN二进制格式文件,直接存储二进制数据,没有结构或头信息,仅包含裸数据。常用于嵌入式系统,用于存储固件镜像,直接烧录到闪存。大小较小,只包含代码和数据,但缺少调试信息,调试困难。
HEX十六进制格式文件,以文本形式表示的二进制数据文件,使用ASCII字符。用于嵌入式系统固件的存储和传输,易于阅读和编辑。通常比BIN文件大,因ASCII字符表示,可包含地址信息,方便定位烧录。
ELF可执行链接格式,通用的标准文件格式。用于嵌入式Linux和UNIX-like系统,适用于可执行程序和调试。灵活可扩展,包含代码和数据以及调试和配置信息,支持静态和动态链接。
EXEWindows系统中的可执行文件格式。存储Windows环境下的可执行程序代码。为Windows设计,包含运行程序所需的所有信息,不适用于嵌入式系统。

  综上,这几种文件有以下几方面的区别:
a. 适用环境不同:
  BIN和HEX文件通常用于嵌入式系统中固件的烧录;ELF文件广泛用于UNIX-like系统的可执行文件和调试;EXE文件是Windows环境下的可执行文件。
b. 内容和结构不同:
  BIN是裸二进制文件,HEX是文本形式的二进制数据,ELF文件具有高度的灵活性,支持复杂的程序结构和调试信息,而EXE是Windows可执行文件格式,包含了运行所需的全部信息。
c. 调试信息不同:
  BIN文件和HEX文件通常不包含调试信息;而EXE和ELF文件可以包含丰富的调试信息,有助于开发和调试过程。

1.2 如何读懂一份hex文件?(hex文件格式详细解读)

  十六进制(HEX)文件格式通常用于在编程过程中传输二进制信息。这种文件格式常见于微控制器和小型嵌入式系统的固件更新中。Intel HEX是其中最常见的一种HEX文件格式,我们将以此为例来解释。

Tip📌:Intel HEX文件格式是一种以文本形式存储二进制数据的文件格式,它的每一行代表了在特定内存地址上的数据记录。这种格式使得数据易于人类阅读和机器解析,并且可以被许多程序编程工具所接受。

  一个标准的Intel HEX文件由多行构成,每行代表一个数据记录(Record)。下面是一个例子:

:020000040000FA
:10010000214601360121470136007EFE09D2190140
:100110002146017E17C20001FF5F16002148011928
:0C012000FFFFFFFFFFFFFFFF0200000000FA
:00000001FF

1.2.1 每行的结构

每一行数据记录有以下顺序和结构:

字段说明
开始码
(Start code)
一个冒号(:),表明这是一行新的记录。
字节计数
(Byte count)
两个十六进制数字,表示这一行中数据字段的字节数,不包括本身这个字段和其他字段
(通常为10或者20,分别表示这行有16个字节或者32个字节的数据)。
地址
(Address)
接着是四个十六进制数字,表示数据将要被写入的起始地址。
记录类型
(Record type)
两个十六进制数字,00到05之间,定义了数据记录的类型。
00代表数据记录;01代表文件结束记录;02代表扩展段地址记录;04代表扩展线性地址记录;05代表开始线性地址记录。
数据
(Data)
数据本身,长度由字节计数字段确定,可以是任意数量的字节(最多255个)。
校验和
(Checksum)
两个十六进制数字,是前面所有字节的反码加1(即二进制求和后取反加1)。

1.2.2 记录类型(Record type)

Intel HEX文件中最常见的几种记录类型如下:

记录类型代码记录类型描述
00数据记录(Data Record):包含了在一个指定地址开始的二进制数据。
01文件结束记录(End Of File Record):文件的结尾,表明没有更多的记录。
02扩展段地址记录(Extended Segment Address Record):用来标识接下来的数据记录的段地址。
04扩展线性地址记录(Extended Linear Address Record):用来标识接下来的数据记录的高位地址。
05开始线性地址记录(Start Linear Address Record):定义了程序的起始执行地址。

1.2.3 校验和的计算

  校验和的计算是对一行中的所有字节进行二进制求和(不包括开始冒号和校验和自身),然后取反加1。简化这种计算逻辑后可以按照下面的方法计算校验和:

  1. 将字节计数、地址、记录类型、和数据字段的所有值相加。
  2. 取这个总和的最低字节。
  3. 用0xFF减去这个最低字节,再加1。

  这样得到的结果就是校验和。校验和的目的是为了确保数据的完整性,在接收端可以通过重新计算校验和来确认数据是否在传输过程中被篡改。例如,我们计算上面第一行数据:020000040000FA的校验和:

02 + 00 + 00 + 04 + 00 + 00 = 06
0xFF - 0x06 + 0x01 = 0xFA

1.2.4 实例解析

以上述示例中的第二行为例:

:10010000214601360121470136007EFE09D2190140
  • : 是开始码。
  • 10 说明接下来有16个数据字节。
  • 0100 是这一行数据的起始地址。
  • 00 是数据记录类型,表示这是一个数据记录。
  • 接下来的214601360121470136007EFE09D21901是数据本身,共16个字节。
  • 最后的40是校验和。

Tip📌:hex文件每行记录数字很多,还是很难阅读的,博主工作中使用vscode比较多,推荐个vscode中的插件,每行记录的结构有不同的色彩区分,阅读起来相对友好一些:

在这里插入图片描述

1.3 如何实现bin文件和hex文件的相互转换?

1.3.1 linux环境下

  在Linux环境下,可以使用一些工具和命令行程序来实现二进制文件(bin)和十六进制文件(hex)之间的相互转换。下面是使用objcopy工具来实现这两种文件格式之间转换的方法,objcopy是GNU二进制工具集(Binutils)的一部分,通常在大多数Linux发行版中可用。

Bin文件 ------> Hex文件

objcopy -I binary -O ihex input_file.bin output_file.hex
  • -I 指定输入文件的格式,这里是binary
  • -O 指定输出文件的格式,这里是ihex,即Intel Hex格式。
  • input_file.bin 是要转换的二进制文件。
  • output_file.hex 是转换后生成的十六进制文件。

Hex文件 ------> Bin文件

objcopy -I ihex -O binary input_file.hex output_file.bin
  • -I 指定输入文件的格式,这里是ihex
  • -O 指定输出文件的格式,这里是binary
  • input_file.hex 是要转换的十六进制文件。
  • output_file.bin 是转换后生成的二进制文件。

Tips📌:

  • 在使用这些命令之前,需要确保系统中已经安装了GNU二进制工具集(Binutils)。如果没有安装,可以使用sudo apt-get install binutils来安装。
  • 这些命令不需要特殊的运行权限,但是需要对输入文件有读取权限,同时对输出文件的目录有写入权限。
  • 使用objcopy命令将bin文件转换为hex文件时,直接通过objcopy命令参数指定起始地址的功能是不支持的。objcopy工具主要用于格式转换,而不直接提供在转换过程中设置起始地址的选项。

1.3.2 linux环境下bin转hex如何指定起始地址?

  如果想要bin文件转hex文件的时候指定hex文件的起始地址,可以通过其他方式间接实现。一种常见的方法是先将bin文件转换为其他格式(如ELF),在这个过程中指定起始地址,然后再从该中间格式转换为hex格式。下面是一个示例流程:

步骤1:Bin转ELF,指定起始地址

ld --oformat=elf32-littlearm -Ttext=起始地址(如0x08000000) -o output_file.elf input_file.bin
  • --oformat=elf32-littlearm 指定输出格式为ELF,具体的格式根据目标架构而定。
  • -Ttext=起始地址 指定section的起始地址。
  • output_file.elf 是转换后的ELF文件。
  • input_file.bin 是原始的二进制文件。

步骤2:ELF转Hex

objcopy -O ihex output_file.elf output_file.hex

output_file.elf是上一步生成的ELF文件,而output_file.hex则是最终的hex文件。

Tips📌:

  • 这个方法需要ldobjcopy工具,这两个工具都属于GNU Binutils工具集,通常在大多数Linux系统中都是预安装的。
  • 指定起始地址时,需要确保它适用于目标平台和应用场景。

1.3.2 Windows环境下

  windows环境下直接推荐给大家两个工具,我工作中用起来还是比较顺手的:第一个工具比较简洁,但功能有限,主要就是用来完成bin和hex文件的转换,hex和bin互转工具(点击获取)
在这里插入图片描述
  第二个工具极其强大并高端,它甚至能完成文件的签名校验等功能,格式转换就更不在话下了:一个强大的hex工具(点击获取)

二、readelf常见用法解读

2.1 elf文件及其组成结构

  为了更好的了解elf文件的组成结构,为后续readelf的学习做准备,首先我们来自己制作一个elf文件。需要你有一台可以运行Linux操作系统的计算机或虚拟机,并且在Linux环境下已经安装了GCC编译器和gcc-arm-linux-gnueabi交叉编译器,Ubuntu环境下交叉编译器可以用下面的指令安装:apt-get install gcc-arm-linux-gnueabi gcc

先编写一个很简单的c文件:

/********* File: sub.h *********/
int add(int a, int b);
int sub(int a, int b);

/********* File: sub.c *********/
int add(int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

/********* File: main.c *********/
#include <stdio.h>
#include "sub.h"

int global_val = 1;
int uninit_val;

int main(void)
{
    int a, b;
    static int local_val = 2;
    static int uninit_local_val;
    a = add(2, 3);
    b = sub(5, 4);
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    return 0;
}

  如果我们想让上面的程序在ARM平台上运行,则要使用ARM交叉编译器将C源程序编译生成ARM格式的二进制可执行文件,执行编译指令arm-linux-gnueabi-gcc -o a.out main.c sub.c。将生成的二进制文件a.out复制到ARM平台上就可以直接运行了。不考虑这个编译生成的过程,先来研究下在这个可执行文件。

——section header、ELF header以及节头表的概念

  一个可执行文件通常由不同的段(section)构成:代码段、数据段、BSS段、只读数据段等。每个section会有一个section header来描述这个段的段名、段的类型、段的起始地址、段的偏移和段的大小等信息,将这些section headers集中放到一起,就是节头表(section header table)。

  此外,可执行文件还会有一个文件头ELF header,用来描述文件类型、要运行的处理器平台、入口地址等信息。当程序运行时,加载器会根据此文件头来获取可执行文件的一些信息。

Tips📌:section header table自身也是以一个section的形式存储在可执行文件中的。

——温故常说的代码段、数据段、BSS段

  C程序中定义的函数、变量、未初始化的全局变量经过编译后会放置在不同的段中:

  • 函数翻译成二进制指令放在代码段中;
  • 初始化的全局变量和静态局部变量放在数据段中;
  • 未初始化的全局变量和静态变量放在BSS段中,但是因为它们未初始化,默认值全部是0,其实没有必要再单独开辟空间存储,为了节省存储空间,所以在可执行文件中BSS段是不占用空间的。但是BSS段的大小、起始地址和各个变量的地址信息会分别保存在节头表和符号表.symtab里,当程序运行时,加载器会根据这些信息在内存中紧挨着数据段的后面为BSS段开辟一片存储空间,为各个变量分配存储单元。

  程序编译的过程实际上就是将程序代码中定义的函数、变量等加以分类,分别放置在可执行文件的代码段、数据段和BSS段中。程序中定义的一些字符串、printf函数打印的字符串常量则放置在只读数据段.rodata中。如果程序在编译时设置为debug模式,则可执行文件中还会有一个专门的.debug section,用来保存可执行文件中每一条二进制指令对应的源码位置信息。根据这些信息,GDB调试器就可以支持源码级的单步调试,否则你单步执行的都是二进制指令,可读性不高,不方便调试。在最后环节,编译器还会在可执行文件中添加一些其他section,如.init section,这些代码来自C语言运行库的一些汇编代码,用来初始化C程序运行所依赖的环境,如内存堆栈的初始化等。

2.2 readelf常见用法详解

  readelf是GNU Binutils包中的一个工具(通常各个linux发行版中都会默认包含这个工具包),用于展示ELF文件的结构信息,包括段头表、节头表、符号表等。实际上,不必大费周章的搜它的用法,readelf -H指令将详细展示各个选项参数的作用。

Tips📌:除了-v和-H之外,其它的选项必须有一个指定参数(即选项后面要加一个待读取信息的文件),-v用来显示readelf的版本信息。

我们这里将列举最常用的几个参数,如下所示:
  如果对程序的编译链接过程不是很清楚的,这里可以先简单认识下前两个选项-h-S即可,阅读《程序的编译、链接过程分析(简洁浓缩版)!》后,再回过头来看其他选项的作用会容易理解一些,不然可能还是不清楚每个选项罗列出来的信息具体有什么用。

在这里插入图片描述

  1. 选项 -h(elf header)
      主要用来获取可执行文件的头部信息,主要包括可执行文件运行的平台、软件版本、程序入口地址, 以及programheaders、section header等信息。通过文件的头部信息,我们可以知道在a.out可执行文件里一共有多少个section headers。
    在这里插入图片描述

  2. 选项 -S(section headers)大写的S
      通过上面-h选项我们看到a.out中总共有29个section header,将这些section header集中放到一起,就是section header table-节头表。可以使用readelf-S命令来查看一个可执行文件的节头表。section header table里的各个section header用来描述各个section的名称、类型、起始地址、大小等信息。
    在这里插入图片描述

  3. 选项 -l(program headers)
      用于显示ELF文件中的程序段(segments)信息。这些信息包括每个段的类型(如LOAD, DYNAMIC等)、地址、偏移、大小等,这对于理解程序如何被操作系统加载到内存中非常有用。建议先阅读《编译链接(待更新)》
    在这里插入图片描述

  4. 选项 -s(symbols)
      可以列出ELF文件中的所有符号,包括函数、变量等。这些符号信息包括它们的名称、位置、大小、类型(如函数、对象等),对于调试程序和理解程序结构非常重要。

westen@westen-ubuntu:/mnt/hgfs/code/build$ readelf -s a.out 

Symbol table '.dynsym' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.4 (2)
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort@GLIBC_2.4 (2)
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.4 (2)

Symbol table '.symtab' contains 112 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00010154     0 SECTION LOCAL  DEFAULT    1 
     2: 00010168     0 SECTION LOCAL  DEFAULT    2 
     3: 00010188     0 SECTION LOCAL  DEFAULT    3 
     4: 000101ac     0 SECTION LOCAL  DEFAULT    4 
     5: 000101d8     0 SECTION LOCAL  DEFAULT    5 
     6: 00010228     0 SECTION LOCAL  DEFAULT    6 
     7: 0001026c     0 SECTION LOCAL  DEFAULT    7 
     8: 00010278     0 SECTION LOCAL  DEFAULT    8 
     9: 00010298     0 SECTION LOCAL  DEFAULT    9 
    10: 000102a0     0 SECTION LOCAL  DEFAULT   10 
    11: 000102c0     0 SECTION LOCAL  DEFAULT   11 
    12: 000102cc     0 SECTION LOCAL  DEFAULT   12 
    13: 00010310     0 SECTION LOCAL  DEFAULT   13 
    14: 00010520     0 SECTION LOCAL  DEFAULT   14 
    15: 00010528     0 SECTION LOCAL  DEFAULT   15 
    16: 0001053c     0 SECTION LOCAL  DEFAULT   16 
    17: 00010544     0 SECTION LOCAL  DEFAULT   17 
    18: 00020f10     0 SECTION LOCAL  DEFAULT   18 
    19: 00020f14     0 SECTION LOCAL  DEFAULT   19 
    20: 00020f18     0 SECTION LOCAL  DEFAULT   20 
    21: 00021000     0 SECTION LOCAL  DEFAULT   21 
    22: 00021020     0 SECTION LOCAL  DEFAULT   22 
    23: 00021030     0 SECTION LOCAL  DEFAULT   23 
    24: 00000000     0 SECTION LOCAL  DEFAULT   24 
    25: 00000000     0 SECTION LOCAL  DEFAULT   25 
    26: 00000000     0 FILE    LOCAL  DEFAULT  ABS /usr/lib/gcc-cross/arm-li
    27: 00010168     0 NOTYPE  LOCAL  DEFAULT    2 $d
    28: 00010310     0 NOTYPE  LOCAL  DEFAULT   13 $a
    29: 0001053c     0 NOTYPE  LOCAL  DEFAULT   16 $d
    30: 00010340     0 NOTYPE  LOCAL  DEFAULT   13 $d
    31: 00010528     0 NOTYPE  LOCAL  DEFAULT   15 $d
    32: 00021020     0 NOTYPE  LOCAL  DEFAULT   22 $d
    33: 00000000     0 FILE    LOCAL  DEFAULT  ABS /usr/lib/gcc-cross/arm-li
    34: 0001034c     0 NOTYPE  LOCAL  DEFAULT   13 $a
    35: 0001034c     0 FUNC    LOCAL  DEFAULT   13 call_weak_fn
    36: 00010368     0 NOTYPE  LOCAL  DEFAULT   13 $d
    37: 000102c0     0 NOTYPE  LOCAL  DEFAULT   11 $a
    38: 00010520     0 NOTYPE  LOCAL  DEFAULT   14 $a
    39: 00000000     0 FILE    LOCAL  DEFAULT  ABS /usr/lib/gcc-cross/arm-li
    40: 000102c8     0 NOTYPE  LOCAL  DEFAULT   11 $a
    41: 00010524     0 NOTYPE  LOCAL  DEFAULT   14 $a
    42: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    43: 00010370     0 NOTYPE  LOCAL  DEFAULT   13 $a
    44: 00010370     0 FUNC    LOCAL  DEFAULT   13 deregister_tm_clones
    45: 00010390     0 NOTYPE  LOCAL  DEFAULT   13 $d
    46: 0001039c     0 NOTYPE  LOCAL  DEFAULT   13 $a
    47: 0001039c     0 FUNC    LOCAL  DEFAULT   13 register_tm_clones
    48: 000103c8     0 NOTYPE  LOCAL  DEFAULT   13 $d
    49: 00021024     0 NOTYPE  LOCAL  DEFAULT   22 $d
    50: 000103d4     0 NOTYPE  LOCAL  DEFAULT   13 $a
    51: 000103d4     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
    52: 000103f8     0 NOTYPE  LOCAL  DEFAULT   13 $d
    53: 00021030     1 OBJECT  LOCAL  DEFAULT   23 completed.9929
    54: 00020f14     0 NOTYPE  LOCAL  DEFAULT   19 $d
    55: 00020f14     0 OBJECT  LOCAL  DEFAULT   19 __do_global_dtors_aux_fin
    56: 000103fc     0 NOTYPE  LOCAL  DEFAULT   13 $a
    57: 000103fc     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
    58: 00020f10     0 NOTYPE  LOCAL  DEFAULT   18 $d
    59: 00020f10     0 OBJECT  LOCAL  DEFAULT   18 __frame_dummy_init_array_
    60: 00021030     0 NOTYPE  LOCAL  DEFAULT   23 $d
    61: 00000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    62: 00021028     0 NOTYPE  LOCAL  DEFAULT   22 $d
    63: 0001052c     0 NOTYPE  LOCAL  DEFAULT   15 $d
    64: 00010400     0 NOTYPE  LOCAL  DEFAULT   13 $a
    65: 00010454     0 NOTYPE  LOCAL  DEFAULT   13 $d
    66: 00021034     4 OBJECT  LOCAL  DEFAULT   23 uninit_local_val.4621
    67: 00021034     0 NOTYPE  LOCAL  DEFAULT   23 $d
    68: 0002102c     4 OBJECT  LOCAL  DEFAULT   22 local_val.4620
    69: 00000000     0 FILE    LOCAL  DEFAULT  ABS sub.c
    70: 0001045c     0 NOTYPE  LOCAL  DEFAULT   13 $a
    71: 00000000     0 FILE    LOCAL  DEFAULT  ABS elf-init.oS
    72: 000104bc     0 NOTYPE  LOCAL  DEFAULT   13 $a
    73: 00010514     0 NOTYPE  LOCAL  DEFAULT   13 $d
    74: 0001051c     0 NOTYPE  LOCAL  DEFAULT   13 $a
    75: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    76: 00010544     0 NOTYPE  LOCAL  DEFAULT   17 $d
    77: 00010544     0 OBJECT  LOCAL  DEFAULT   17 __FRAME_END__
    78: 00000000     0 FILE    LOCAL  DEFAULT  ABS 
    79: 00020f14     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_end
    80: 00020f18     0 OBJECT  LOCAL  DEFAULT   20 _DYNAMIC
    81: 00020f10     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_start
    82: 00021000     0 OBJECT  LOCAL  DEFAULT   21 _GLOBAL_OFFSET_TABLE_
    83: 000102cc     0 NOTYPE  LOCAL  DEFAULT   12 $a
    84: 000102dc     0 NOTYPE  LOCAL  DEFAULT   12 $d
    85: 000102e0     0 NOTYPE  LOCAL  DEFAULT   12 $a
    86: 0001051c     4 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    87: 00021038     4 OBJECT  GLOBAL DEFAULT   23 uninit_val
    88: 00021020     0 NOTYPE  WEAK   DEFAULT   22 data_start
    89: 0001045c    48 FUNC    GLOBAL DEFAULT   13 add
    90: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@@GLIBC_2.4
    91: 00021030     0 NOTYPE  GLOBAL DEFAULT   23 __bss_start__
    92: 0002103c     0 NOTYPE  GLOBAL DEFAULT   23 _bss_end__
    93: 00021030     0 NOTYPE  GLOBAL DEFAULT   22 _edata
    94: 00010520     0 FUNC    GLOBAL DEFAULT   14 _fini
    95: 0002103c     0 NOTYPE  GLOBAL DEFAULT   23 __bss_end__
    96: 00021028     4 OBJECT  GLOBAL DEFAULT   22 global_val
    97: 00021020     0 NOTYPE  GLOBAL DEFAULT   22 __data_start
    98: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    99: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
   100: 00021024     0 OBJECT  GLOBAL HIDDEN    22 __dso_handle
   101: 00010528     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used
   102: 000104bc    96 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
   103: 0002103c     0 NOTYPE  GLOBAL DEFAULT   23 _end
   104: 00010310     0 FUNC    GLOBAL DEFAULT   13 _start
   105: 0002103c     0 NOTYPE  GLOBAL DEFAULT   23 __end__
   106: 00021030     0 NOTYPE  GLOBAL DEFAULT   23 __bss_start
   107: 00010400    92 FUNC    GLOBAL DEFAULT   13 main
   108: 00021030     0 OBJECT  GLOBAL HIDDEN    22 __TMC_END__
   109: 0001048c    48 FUNC    GLOBAL DEFAULT   13 sub
   110: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort@@GLIBC_2.4
   111: 000102c0     0 FUNC    GLOBAL DEFAULT   11 _init
  1. 选项 -r(relocs)
      用于显示ELF文件中的重定位表信息。重定位表包含了程序在运行时需要修改的地址信息,这对于理解动态链接和地址修正过程至关重要。
    在这里插入图片描述

  2. 选项 -d(dynamic)
      可以查看ELF文件的动态段信息,这对于动态链接的ELF文件(如共享库)特别有用。它显示了动态链接器需要的信息,如所需的共享库、动态符号表等。
    在这里插入图片描述

  3. 选项 -A(arch-specific)
      显示CPU构架信息,这个其实也是不常用的,偶尔用来看一下enum类型。
    在这里插入图片描述

  4. 选项-x, hex-dump=<number or name>
      以16进制方式显示指定段内内容,通过-x选项后跟节(section)名称或者索引号,可以将指定节的内容以十六进制形式转储出来。这对于直接查看节中的原始数据非常有用,特别是在分析程序行为或调试时。
    在这里插入图片描述

  再次提醒,如果对程序的编译链接过程不是很清楚的,建议阅读《程序的编译、链接过程分析(简洁浓缩版)!》后,再回过头来看这些选项的作用,不然可能还是不清楚每个选项罗列出来的信息具体有什么用。

>>>>>>>>> 返回专栏总目录 《嵌入式工程师自我修养/C语言》<<<<<<<<<

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

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

相关文章

数字人解决方案——Wav2lip本地部署

1、安装anaconda anaconda自行下载安装 2、下载wav2lip 在github中搜索wav2lip ​ git clone https://github.com/Rudrabha/Wav2Lip.git ​ 源码到本地 准备脸部检测预训练模型 下载地址&#xff1a;https://www.adrianbulat.com/downloads/python-fan/s3fd-619a316812…

安卓远离手机app

软件介绍 远离手机是专门为防止年轻人上瘾而打造的生活管理类的软件,适度用手机&#xff0c;保护眼睛&#xff0c;节约时间。 下载 安卓远离手机app

C++ 一种简单的软件验证码 程序授权使用 收费付费使用 无需注册 用机器码得到一个加密值 再对比加密值是否一致 只需加密

简单软件授权方案 1、获取机器码&#xff0c;发给软件开发者 2、开发者用机器码加密得到一个密文 发给使用者 3、使用者 用这个密文 与本地计算密文比较密文是否一致&#xff0c;一致就把密文写入到注册表&#xff0c;下次登录从注册表读密文对比。 &#xff08;最重要的是密…

【C++】STL学习之string的使用

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 前言一、basic_string二、编码理解三、构造函数相关3.1 无参(默认)构造函数3.2 …

力扣爆刷第114天之CodeTop100五连刷56-60

力扣爆刷第114天之CodeTop100五连刷56-60 文章目录 力扣爆刷第114天之CodeTop100五连刷56-60一、78. 子集二、105. 从前序与中序遍历序列构造二叉树三、43. 字符串相乘四、155. 最小栈五、151. 反转字符串中的单词 一、78. 子集 题目链接&#xff1a;https://leetcode.cn/prob…

一文了解RAID技术基本概念

RAID是数据存储技术&#xff0c;旨在提高磁盘的IO吞吐以及提供更为可靠的数据安全。在实际工作中经常听到RAID相关名称&#xff0c;那么RAID技术的基本概念是什么、不同RAID级别有什么特性&#xff0c;本文将简单介绍&#xff0c;以了解。 1、RAID技术基本概念 1.1 RAID基本概…

uniapp中uni.navigateTo传递变量

效果展示&#xff1a; 核心代码&#xff1a; uniapp中uni.navigateTo传递变量 methods: {changePages(item) {setDatas("maintenanceFunName", JSON.stringify(item)).then((res) > {uni.navigateTo({url: /pages/PMS/maintenance/maintenanceTypes/maintenanceT…

python开发poc2,爆破脚本

#本课知识点和目的&#xff1a; ---协议模块使用&#xff0c;Request 爬虫技术&#xff0c;简易多线程技术&#xff0c;编码技术&#xff0c;Bypass 后门技术 下载ftp服务器模拟器 https://lcba.lanzouy.com/iAMePxl378h 随便创建一个账户&#xff0c;然后登录进去把ip改成…

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍

文章目录 前提嵌入式开发交叉编译GDB调试&#xff0c;QEMU&#xff0c;MAKEFILE练习 目标&#xff1a;通过这一个系列课程的学习&#xff0c;开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提 这个系列的大部分文章和知识来自于&#xff1a;[完结] 循序渐进&#x…

五一假期来临,各地景区云旅游、慢直播方案设计与平台搭建

一、行业背景 经文化和旅游部数据中心测算&#xff0c;今年清明节假期3天全国国内旅游出游1.19亿人次&#xff0c;按可比口径较2019年同期增长11.5%&#xff1b;国内游客出游花费539.5亿元&#xff0c;较2019年同期增长12.7%。踏青赏花和户外徒步成为假期的热门出游主题。随着…

Matlab 修改图例顺序

对于使用 .m 文件绘制的图片&#xff0c;可以修改程序中图例的顺序来改变图片的图例。如果图片所对应的 .fig 文件已经存在&#xff0c;而且不便修改源程序&#xff0c;则可以通过如下方式来修改图例&#xff1a; step 1: 打开fig文件&#xff0c;然后点击绘图浏览器 step 2&…

STC89C51学习笔记(五)

STC89C51学习笔记&#xff08;五&#xff09; 综述&#xff1a;文本讲述了代码中速写模板的创建、如何将矩阵键盘的按键与数字一一对应以及如何创建一个矩阵键盘密码锁。 一、速写模板 点击“templates”&#xff0c;再鼠标右键选择配置&#xff0c;按照以下方式即可修改一些…

【WEEK6】 【DAY7】MD5 Encryption Transactions【English Version】

2024.4.7 Sunday Following the previous article 【WEEK6】 【DAY3】MySQL Functions【English Version】 Contents 5.3. MD5 Encryption5.3.1. Introduction5.3.2. Testing MD5 Encryption5.3.2.1. Plain Text Passwords5.3.2.2. Implementing Data Encryption5.3.2.3. Encry…

位域与联合体巧妙使用

在编写dbc报文的协议解析时&#xff0c;使用位域运算和联合体的组合&#xff0c;能够巧妙解决字段解析问题&#xff0c;代码看起来整洁又健壮。 #include <algorithm> #include <iostream> #include <vector>using namespace std;typedef union tagCoreCalib…

Python爬虫:为什么你爬取不到网页数据

目录 前言 一、网络请求被拒绝 二、数据是通过JavaScript加载的 三、需要进行登录 四、网站反爬虫策略 五、网站结构变更 总结 前言 作为一名开发者&#xff0c;使用Python编写爬虫程序是一项常见的任务。爬虫程序的目的是收集互联网上的数据&#xff0c;并将其保存或使…

【漏洞复现】用友畅捷通TPlus GetStoreWarehouseByStore .net反序列化漏洞

0x01 阅读须知 “如棠安全的技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供…

【Lavavel框架】——各目录作用的介绍

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

C++ 之 【类与对象】从入门到精通一条龙服务 入门篇

不要觉的自己很没用&#xff0c;其实你还可以给家人带来温暖&#xff0c;比如爸妈看到你就来火 目录&#xff1a; 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 四、类的访问限定符及封装 1.访问限定符 2.封装 五、类的作用域 六、类的实例化 七、类的…

亚马逊云配置深度学习环境

开发环境 对于MacOS来说没无法cuda&#xff0c;所以用的是mps后端计算&#xff0c;所以也无法打印GPU数量和型号。 torch.backends.mps.is_available()如果使用PopOS的话&#xff0c;可以选择自带英伟达驱动的镜像&#xff0c;这样就可以免去复杂的驱动安装流程。 EC2 (自己…

RabbitMQ的交换机与队列

一、流程 首先先介绍一个简单的一个消息推送到接收的流程&#xff0c;提供一个简单的图 黄色的圈圈就是我们的消息推送服务&#xff0c;将消息推送到 中间方框里面也就是 rabbitMq的服务器&#xff0c;然后经过服务器里面的交换机、队列等各种关系&#xff08;后面会详细讲&am…