Linux—使用readelf工具查看程序代码变量的内存空间布局情况

2023-11-13

1. 源程序与程序的映射

  1. BSS段:存放未初始化的全局变量或静态变量,Block Started by Symbol;
  2. DATA段:存放已初始化的变量;
  3. TEXT段:存放二进制代码。

2. 程序到进程的映射

  1. 程序代码区:存放函数体二进制代码;
  2. 常量区:存放常量、字符串等,只读;
  3. 全局数据区:存放全局变量、静态变量等,可读可写;
  4. 堆区:存放进程运行中被动态分配的内存段,可动态扩展或缩减;
  5. 动态链接库:用于在程序运行期间加载和卸载动态链接库;
  6. 栈区:存放函数的参数值局部变量的值等。

#include<stdio.h>
int s1;
int s2 = 0;
static int s3 = 0;
static int s4 = 4;
int main(void)
{
	int s5;
	return 0;
}
  • 其中s1、s2、s3都是未初始化的全局变量,所以在bss段;
  • s4为已初始化的全局变量,所以在data段;
  • s5位局部变量,存储在栈中。

3. 使用readelf指令

在Linux中,可以使用readelf指令来查看相应的信息。

ELF的英文全称是The Executable and Linking Format,是Linux的主要可执行文件格式,包含三种:

  • 可执行文件(.out)
  • 可重定位文件(.o文件)
  • 共享目标文件(.so)
gcc -g bss.c -o bss   //-g为编译   -o为指定目标名称,gcc默认编译出来的文件为a.out
readrlf -a bss

其中gcc和readelf都有很多的指令,以readelf为例:

  • readelf -h:elf header,头文件信息;
  • readelf -l:program headers,显示程序头 (段头) 信息;
  • readelf -S:section headers,显示节头信息;
  • readelf -s:symbols,显示符号表段中的项;
  • readelf -r:relocs,显示可重定位段的信息;
  • readelf -d:dynamic,显示动态段的信息;
  • readelf -V:version-info,显示版本段的信息;
  • readelf -A:arch-specific,显示CPU构架信息;
  • readelf -I:histogram,显示符号的时候,显示bucket list长度的柱状图;
  • readelf -a,all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I。

 头文件信息:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400400
  Start of program headers:          64 (bytes into file)
  Start of section headers:          5200 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         35                               
  Section header string table index: 32

可以看到Number of section headers为35,从文件地址5200开始,每个Section Header占64字节,文件开头第一个字节的地址是0x400400。

节头信息:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
       0000000000000048  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000400300  00000300
       0000000000000038  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           0000000000400338  00000338
       0000000000000006  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000400340  00000340
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000400360  00000360
       0000000000000018  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000400378  00000378
       0000000000000030  0000000000000018   A       5    12     8
  [11] .init             PROGBITS         00000000004003a8  000003a8
       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         00000000004003d0  000003d0
       0000000000000030  0000000000000010  AX       0     0     16
  [13] .text             PROGBITS         0000000000400400  00000400    // 代码区
       0000000000000172  0000000000000000  AX       0     0     16
  [14] .fini             PROGBITS         0000000000400574  00000574
       0000000000000009  0000000000000000  AX       0     0     4
  [15] .rodata           PROGBITS         0000000000400580  00000580    // 常量区
       0000000000000004  0000000000000004  AM       0     0     4
  [16] .eh_frame_hdr     PROGBITS         0000000000400584  00000584
       0000000000000034  0000000000000000   A       0     0     4
  [17] .eh_frame         PROGBITS         00000000004005b8  000005b8
       00000000000000f4  0000000000000000   A       0     0     8
  [18] .init_array       INIT_ARRAY       0000000000600e10  00000e10
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .jcr              PROGBITS         0000000000600e20  00000e20
       0000000000000008  0000000000000000  WA       0     0     8
  [21] .dynamic          DYNAMIC          0000000000600e28  00000e28
       00000000000001d0  0000000000000010  WA       6     0     8
  [22] .got              PROGBITS         0000000000600ff8  00000ff8
       0000000000000008  0000000000000008  WA       0     0     8
  [23] .got.plt          PROGBITS         0000000000601000  00001000
       0000000000000028  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         0000000000601028  00001028    // 已初始化变量
       0000000000000014  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           000000000060103c  0000103c    // 未初始化变量
       0000000000000014  0000000000000000  WA       0     0     4
  [26] .comment          PROGBITS         0000000000000000  0000103c
       0000000000000056  0000000000000001  MS       0     0     1
  [27] .debug_aranges    PROGBITS         0000000000000000  00001092
       0000000000000030  0000000000000000           0     0     1
  [28] .debug_info       PROGBITS         0000000000000000  000010c2
       00000000000000f0  0000000000000000           0     0     1
  [29] .debug_abbrev     PROGBITS         0000000000000000  000011b2
       0000000000000073  0000000000000000           0     0     1
  [30] .debug_line       PROGBITS         0000000000000000  00001225
       0000000000000039  0000000000000000           0     0     1
  [31] .debug_str        PROGBITS         0000000000000000  0000125e
       00000000000000a8  0000000000000001  MS       0     0     1
  [32] .shstrtab         STRTAB           0000000000000000  00001306
       0000000000000148  0000000000000000           0     0     1
  [33] .symtab           SYMTAB           0000000000000000  00001d10
       00000000000006d8  0000000000000018          34    52     8
  [34] .strtab           STRTAB           0000000000000000  000023e8
       000000000000022f  0000000000000000           0     0     1

 符号表段中的项:

Symbol table '.symtab' contains 73 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000400238     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000400254     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000400274     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000400298     0 SECTION LOCAL  DEFAULT    4 
     5: 00000000004002b8     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000400300     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000400338     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000400340     0 SECTION LOCAL  DEFAULT    8 
     9: 0000000000400360     0 SECTION LOCAL  DEFAULT    9 
    10: 0000000000400378     0 SECTION LOCAL  DEFAULT   10 
    11: 00000000004003a8     0 SECTION LOCAL  DEFAULT   11 
    12: 00000000004003d0     0 SECTION LOCAL  DEFAULT   12 
    13: 0000000000400400     0 SECTION LOCAL  DEFAULT   13 
    14: 0000000000400574     0 SECTION LOCAL  DEFAULT   14 
    15: 0000000000400580     0 SECTION LOCAL  DEFAULT   15 
    16: 0000000000400584     0 SECTION LOCAL  DEFAULT   16 
    17: 00000000004005b8     0 SECTION LOCAL  DEFAULT   17 
    18: 0000000000600e10     0 SECTION LOCAL  DEFAULT   18 
    19: 0000000000600e18     0 SECTION LOCAL  DEFAULT   19 
    20: 0000000000600e20     0 SECTION LOCAL  DEFAULT   20 
    21: 0000000000600e28     0 SECTION LOCAL  DEFAULT   21 
    22: 0000000000600ff8     0 SECTION LOCAL  DEFAULT   22 
    23: 0000000000601000     0 SECTION LOCAL  DEFAULT   23 
    24: 0000000000601028     0 SECTION LOCAL  DEFAULT   24 
    25: 000000000060103c     0 SECTION LOCAL  DEFAULT   25 
    26: 0000000000000000     0 SECTION LOCAL  DEFAULT   26 
    27: 0000000000000000     0 SECTION LOCAL  DEFAULT   27 
    28: 0000000000000000     0 SECTION LOCAL  DEFAULT   28 
    29: 0000000000000000     0 SECTION LOCAL  DEFAULT   29 
    30: 0000000000000000     0 SECTION LOCAL  DEFAULT   30 
    31: 0000000000000000     0 SECTION LOCAL  DEFAULT   31 
    32: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    33: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   20 __JCR_LIST__
    34: 0000000000400430     0 FUNC    LOCAL  DEFAULT   13 deregister_tm_clones
    35: 0000000000400460     0 FUNC    LOCAL  DEFAULT   13 register_tm_clones
    36: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
    37: 000000000060103c     1 OBJECT  LOCAL  DEFAULT   25 completed.6982
    38: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   19 __do_global_dtors_aux_fin
    39: 00000000004004c0     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
    40: 0000000000600e10     0 OBJECT  LOCAL  DEFAULT   18 __frame_dummy_init_array_
    41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS bss.c
    42: 0000000000601044     4 OBJECT  LOCAL  DEFAULT   25 s3
    43: 0000000000601038     4 OBJECT  LOCAL  DEFAULT   24 s4
    44: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    45: 00000000004006a8     0 OBJECT  LOCAL  DEFAULT   17 __FRAME_END__
    46: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   20 __JCR_END__
    47: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    48: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_end
    49: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
    50: 0000000000600e10     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_start
    51: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   23 _GLOBAL_OFFSET_TABLE_
    52: 0000000000400570     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    53: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
    54: 0000000000601028     0 NOTYPE  WEAK   DEFAULT   24 data_start
    55: 0000000000601040     4 OBJECT  GLOBAL DEFAULT   25 s2
    56: 000000000060103c     0 NOTYPE  GLOBAL DEFAULT   24 _edata
    57: 0000000000400574     0 FUNC    GLOBAL DEFAULT   14 _fini
    58: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    59: 0000000000601028     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
    60: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    61: 0000000000601030     0 OBJECT  GLOBAL HIDDEN    24 __dso_handle
    62: 0000000000400580     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used
    63: 0000000000400500   101 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    64: 0000000000601050     0 NOTYPE  GLOBAL DEFAULT   25 _end
    65: 0000000000400400     0 FUNC    GLOBAL DEFAULT   13 _start
    66: 0000000000601048     4 OBJECT  GLOBAL DEFAULT   25 s1
    67: 000000000060103c     0 NOTYPE  GLOBAL DEFAULT   25 __bss_start
    68: 00000000004004ed    11 FUNC    GLOBAL DEFAULT   13 main
    69: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    70: 0000000000601040     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__
    71: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
    72: 00000000004003a8     0 FUNC    GLOBAL DEFAULT   11 _init

截取我们需要的四条信息:

  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
......

  [13] .text             PROGBITS         0000000000400400  00000400
       0000000000000172  0000000000000000  AX       0     0     16
......

  [15] .rodata           PROGBITS         0000000000400580  00000580
       0000000000000004  0000000000000004  AM       0     0     4
......

  [24] .data             PROGBITS         0000000000601028  00001028
       0000000000000014  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           000000000060103c  0000103c
       0000000000000014  0000000000000000  WA       0     0     4
......
   Num:    Value          Size Type    Bind   Vis      Ndx Name
......
    42: 0000000000601044     4 OBJECT  LOCAL  DEFAULT   25 s3
    43: 0000000000601038     4 OBJECT  LOCAL  DEFAULT   24 s4
......
    55: 0000000000601040     4 OBJECT  GLOBAL DEFAULT   25 s2
......
    66: 0000000000601048     4 OBJECT  GLOBAL DEFAULT   25 s1
#include<stdio.h>
int s1;
int s2 = 0;
static int s3 = 0;
static int s4 = 4;
int main(void)
{
	int s5;
	return 0;
}
  • s1:未初始化变量,是一个GLOBAL符号,地址为0000000000601048,从Section Headers可以看到这个地址位于bss段;
  • s2:未初始化变量,是一个GLOBAL符号,地址为0000000000601040,从Section Headers可以看到这个地址位于bss段;
  • s3:未初始化变量,但是被static修饰,所以为LOCAL,地址为0000000000601044,从Section Headers可以看到这个地址位于bss段;
  • s4:初始化变量,但是被static修饰,所以为LOCAL,地址为0000000000601038,从Section Headers可以看到这个地址位于data段。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux—使用readelf工具查看程序代码变量的内存空间布局情况 的相关文章

  • 限制 Imagemagick 使用的空间和内存

    我在 Rails 应用程序上使用 Imagemagick 使用 rmagick 但我的服务器 Ubuntu 不是很大 当我启动转换进程时 Imagemagick 占据了我的服务器 30GB HDD 的所有位置 内存 我想限制内存和 tmp
  • 如何从 PROC 获取有关子进程的信息

    我正在尝试编写一个以几个进程作为参数的程序 然后父进程执行每个子进程并打印出一些相关的统计信息 示例 generate ls l 将生成一个程序 打印出有关 ls l 的一些统计信息 特别是其系统时间 用户时间和上下文切换次数 我不想使用
  • vagrant ssh -c 并在连接关闭后保持后台进程运行

    我正在编写一个脚本来启动和后台流浪机器内的进程 似乎每次脚本结束和 ssh 会话结束时 后台进程也会结束 这是我正在运行的命令 vagrant ssh c cd vagrant src nohup python hello py gt he
  • 在 Ubuntu 中找不到 X11/Xlib.h

    我试图在 Linux 上使用 open gl 编写一个相当简单的程序 但在编译时它说 编译拇指 egl 我对 GL 完全陌生 不知道出了什么问题 快速搜索使用 apt search Xlib h 打开 libx11 dev 包 但纯 Ope
  • Linux中使用管道进行进程间通信

    我已经编写了在 linux 中写入数字以进行管道传输的代码 如下所示 但显示错误 任何人都可以帮助我解决这个问题 基本上该程序的问题陈述如下 一个程序将打开一个管道 向管道写入一个数字 其他程序将打开同一管道 读取数字并打印它们 关闭两个管
  • 捕获数据包后会发生什么?

    我一直在阅读关于网卡捕获数据包后会发生什么的内容 我读得越多 我就越困惑 首先 我读过传统上 在网卡捕获数据包后 它会被复制到内核空间中的一个内存块 然后复制到用户空间 供随后处理数据包数据的任何应用程序使用 然后我读到了 DMA 其中 N
  • Web 应用程序的带宽和流量模拟器?

    您能否建议如何创建一个测试环境来模拟 Web 应用程序中的各种类型的带宽和流量 或者也许是一个针对本地主机执行此操作的开源程序 我认为在编写网络应用程序时这是一个非常重要的主题 但这不是一个常见的主题 我能想象创建这种环境的唯一方法是在本地
  • C:如果文件描述符被删除,阻塞读取应该返回

    我正在以阻塞的方式从设备 文件描述符中读取 可能会发生这样的情况 在不同的线程中 设备被关闭并且文件描述符被删除 不幸的是 读取没有返回或注意到并且一直阻塞 作为一种解决方法 我可以使用 select 作为超时来执行 while 循环 如果
  • 无法在 64 位 Linux 上从汇编 (yasm) 代码调用 C 标准库函数

    我有一个函数foo以汇编语言编写 并在 Linux Ubuntu 64 位上使用 yasm 和 GCC 编译 它只是使用以下命令将消息打印到标准输出puts 如下所示 bits 64 extern puts global foo secti
  • PyPI 上的轮子平台约束有什么限制吗?

    是否有任何地方 PEP 或其他地方 声明关于 Linux 轮子上传范围的限制 PyPI http pypi io 应该有 具体来说 上传是否被认为是可接受的做法linux x86 64轮子到 PyPI 而不是manylinux1 x86 6
  • 在 Linux 上访问 main 之外的主要参数

    是否可以访问参数main在外面main 即在共享库构造函数中 在 Linux 上除了通过解析之外 proc self cmdline 您可以通过将构造函数放入 init array部分 功能在 init array 不像 init 使用相同
  • dlopen 或 dlclose 未调用信号处理程序

    我在随机时间内收到分段错误 我注册了信号 但发生分段错误时未调用信号处理程序 include
  • 码头无故停止

    我需要经验丰富的码头用户的建议 我在负载均衡器 亚马逊云 后面维护着 2 台 Linux 机器 使用 Jetty 9 0 3 有时我的 Jetty 容器会被 Thread 2 无故关闭 同时地 显示以下日志并且容器无故停止 没有错误 没有例
  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 在 Docker 容器中以主机用户身份运行

    在我的团队中 我们在进行开发时使用 Docker 容器在本地运行我们的网站应用程序 假设我正在开发 Flask 应用程序app py具有依赖关系requirements txt 工作流程大致如下 I am robin and I am in
  • 运行此处编译的 C 程序会导致在另一台服务器上找不到 GLIBC 库错误 - 是我的错还是他们的错?

    此处编译的 C 程序在我们的 Ubuntu 服务器上运行良好 但是当其他人尝试在他们的特定 Linux 服务器上运行它时 他们会收到以下错误 myprog install lib tls libc so 6 version GLIBC 2
  • 在 debian wheezy amd64 上安装 ia32-libs

    我正在使用 Debian 7 喘息 amd64 uname a Linux tzwm debian 3 2 0 4 amd64 1 SMP Debian 3 2 51 1 x86 64 GNU Linux 我想安装ia32 libs在我的
  • 使用 ProcessBuilder 运行 shell 脚本

    我正在尝试使用 Java 和 ProcessBuilder 运行脚本 当我尝试运行时 我收到以下消息 error 2 没有这样的文件或目录 我不知道我做错了什么 但这是我的代码 ps 我尝试只执行不带参数的脚本 错误是相同的 String
  • 使用c在linux上分块读写

    我有一个 ASCII 文件 其中每一行都包含一个可变长度的记录 例如 Record 1 15 characters Record 2 200 characters Record 3 500 characters Record n X cha
  • 可以作为命令行参数传递多少数据?

    在 Linux 下生成进程时可以发送多少字节作为命令行参数 gahooa 推荐了一篇好文章http www in ulm de mascheck various argmax http www in ulm de mascheck vari

随机推荐