Linux应用程序地址布局

一、程序构成

在学习Linux应用程序开发时,经常会遇到如下概念:代码段、数据段、BSS段等。BSS(Block Started by Symbol,又名:未初始化数据段)、堆(heap)、栈(stack)而这些部分也是构成Linux应用程序的重要组成部分。

二、内存布局

当Linux应用程序在内存中运行的时候,以上组成部分在内存中以如下图的方式布局。

Linux应用程序地址布局_第1张图片
image.png

  1. 从低地址到高地址分别为:代码段、数据段、BSS段、堆、栈
  2. 堆向高内存地址生长
  3. 栈向低内存地址生长

三、编写代码查看程序各段地址

编辑如下代码:addr.c

#include 

#include 
#include 
char a[64] = "welcome";
char b[64];
void main()
{
        char *c = (char *)malloc(64);
        int  d = 76;
        strcpy(b,"value b");
        strcpy(c,"value c");
        printf("var a address: 0x%16x \n",a);
        printf("var b address: 0x%16x \n",b);
        printf("var c address: 0x%16x \n",c);
        printf("var d address: 0x%16x \n",&d);
        while(1){;}    }

编译、运行程序:

gcc -o addr -g addr.c
./addr
//输出如下:
var a address: 0x          601060 
var b address: 0x          6010c0 
var c address: 0x          6ab010 
var d address: 0x        4715986c 

另外打开一个shell 进行操作:

ps aux | grep ./addr
//这里输出如下
jet        4426  100  0.0   4356   640 pts/18   R+   20:47   0:21 ./addr
jet        4439  0.0  0.0  15964   980 pts/19   S+   20:47   0:00 grep --color=auto ./addr
//可以看出我们的进程PID 是 4426

抓取内存信息:

cat /proc/4426/maps 
// 输出如下:(我这里是x64机器有点不太一样)
00400000-00401000 r-xp 00000000 08:01 7870415                            /home/jet/study/lesson3_memory/addr
00600000-00601000 r--p 00000000 08:01 7870415                            /home/jet/study/lesson3_memory/addr
00601000-00602000 rw-p 00001000 08:01 7870415                            /home/jet/study/lesson3_memory/addr
006ab000-006cc000 rw-p 00000000 00:00 0                                  [heap]
7f73272bb000-7f732747b000 r-xp 00000000 08:01 12849622                   /lib/x86_64-linux-gnu/libc-2.23.so
7f732747b000-7f732767b000 ---p 001c0000 08:01 12849622                   /lib/x86_64-linux-gnu/libc-2.23.so
7f732767b000-7f732767f000 r--p 001c0000 08:01 12849622                   /lib/x86_64-linux-gnu/libc-2.23.so
7f732767f000-7f7327681000 rw-p 001c4000 08:01 12849622                   /lib/x86_64-linux-gnu/libc-2.23.so
7f7327681000-7f7327685000 rw-p 00000000 00:00 0 
7f7327685000-7f73276ab000 r-xp 00000000 08:01 12845073                   /lib/x86_64-linux-gnu/ld-2.23.so
7f732788b000-7f732788e000 rw-p 00000000 00:00 0 
7f73278a8000-7f73278aa000 rw-p 00000000 00:00 0 
7f73278aa000-7f73278ab000 r--p 00025000 08:01 12845073                   /lib/x86_64-linux-gnu/ld-2.23.so
7f73278ab000-7f73278ac000 rw-p 00026000 08:01 12845073                   /lib/x86_64-linux-gnu/ld-2.23.so
7f73278ac000-7f73278ad000 rw-p 00000000 00:00 0 
7ffc4713a000-7ffc4715b000 rw-p 00000000 00:00 0                          [stack]
7ffc471c6000-7ffc471c8000 r--p 00000000 00:00 0                          [vvar]
7ffc471c8000-7ffc471ca000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

这里我们结合进程map信息和程序输出信息可以得出:

  • 代码段位于 400000 - 401000
  • 数据段位于 600000 - 601000
  • BSS段位于 601000 - 602000
  • 堆空间位于 6ab000 - 6cc000
  • 栈空间地址非常高

四、变量存放段补充


.data段:

  • 全局、已初始化
  • 全局、静态、已初始化
  • 局部、静态、初始化

.BSS段:

  • 全局、未初始化
  • 全局、静态、未初始化
  • 局部、静态、未初始化

.code段:

  • 全局、常量(const)
  • 字符串常量

.stack段:

  • 局部、初始化
  • 局部、未初始化
  • 局部、常量(const)

.heap段:

  • malloc分配局部变量

注意:

可以通过下面命令读取相关程序的内存分配:

readelf -s addr 
//输出如下:
Symbol table '.dynsym' contains 5 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND malloc@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 75 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: 0000000000400330     0 SECTION LOCAL  DEFAULT    6 
     7: 0000000000400376     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000400380     0 SECTION LOCAL  DEFAULT    8 
     9: 00000000004003a0     0 SECTION LOCAL  DEFAULT    9 
    10: 00000000004003b8     0 SECTION LOCAL  DEFAULT   10 
    11: 0000000000400400     0 SECTION LOCAL  DEFAULT   11 
    12: 0000000000400420     0 SECTION LOCAL  DEFAULT   12 
    13: 0000000000400460     0 SECTION LOCAL  DEFAULT   13 
    14: 0000000000400470     0 SECTION LOCAL  DEFAULT   14 
    15: 0000000000400684     0 SECTION LOCAL  DEFAULT   15 
    16: 0000000000400690     0 SECTION LOCAL  DEFAULT   16 
    17: 00000000004006f4     0 SECTION LOCAL  DEFAULT   17 
    18: 0000000000400728     0 SECTION LOCAL  DEFAULT   18 
    19: 0000000000600e10     0 SECTION LOCAL  DEFAULT   19 
    20: 0000000000600e18     0 SECTION LOCAL  DEFAULT   20 
    21: 0000000000600e20     0 SECTION LOCAL  DEFAULT   21 
    22: 0000000000600e28     0 SECTION LOCAL  DEFAULT   22 
    23: 0000000000600ff8     0 SECTION LOCAL  DEFAULT   23 
    24: 0000000000601000     0 SECTION LOCAL  DEFAULT   24 
    25: 0000000000601040     0 SECTION LOCAL  DEFAULT   25 
    26: 00000000006010a0     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 SECTION LOCAL  DEFAULT   32 
    33: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    34: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_LIST__
    35: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
    36: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
    37: 0000000000400520     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    38: 00000000006010a0     1 OBJECT  LOCAL  DEFAULT   26 completed.7585
    39: 0000000000600e18     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fin
    40: 0000000000400540     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
    41: 0000000000600e10     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_
    42: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS addr.c
    43: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    44: 0000000000400818     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    45: 0000000000600e20     0 OBJECT  LOCAL  DEFAULT   21 __JCR_END__
    46: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    47: 0000000000600e18     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end
    48: 0000000000600e28     0 OBJECT  LOCAL  DEFAULT   22 _DYNAMIC
    49: 0000000000600e10     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start
    50: 00000000004006f4     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
    51: 0000000000601000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_
    52: 0000000000400680     2 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
    53: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
    54: 0000000000601040     0 NOTYPE  WEAK   DEFAULT   25 data_start
    55: 00000000006010c0    64 OBJECT  GLOBAL DEFAULT   26 b
    56: 00000000006010a0     0 NOTYPE  GLOBAL DEFAULT   25 _edata
    57: 0000000000400684     0 FUNC    GLOBAL DEFAULT   15 _fini
    58: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@@GLIBC_2.2.5
    59: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    60: 0000000000601040     0 NOTYPE  GLOBAL DEFAULT   25 __data_start
    61: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    62: 0000000000601048     0 OBJECT  GLOBAL HIDDEN    25 __dso_handle
    63: 0000000000400690     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
    64: 0000000000400610   101 FUNC    GLOBAL DEFAULT   14 __libc_csu_init
    65: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND malloc@@GLIBC_2.2.5
    66: 0000000000601100     0 NOTYPE  GLOBAL DEFAULT   26 _end
    67: 0000000000400470    42 FUNC    GLOBAL DEFAULT   14 _start
    68: 0000000000601060    64 OBJECT  GLOBAL DEFAULT   25 a
    69: 00000000006010a0     0 NOTYPE  GLOBAL DEFAULT   26 __bss_start
    70: 0000000000400566   164 FUNC    GLOBAL DEFAULT   14 main
    71: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    72: 00000000006010a0     0 OBJECT  GLOBAL HIDDEN    25 __TMC_END__
    73: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
    74: 0000000000400400     0 FUNC    GLOBAL DEFAULT   11 _init

通过输出结果可以分析数据段的分配。

你可能感兴趣的:(Linux应用程序地址布局)