Analysis of Linux Program Memory Layout
I. Detailed Explanation of Complete Program Memory Layout (Linux x86-64)
High Address 0x7FFFFFFFFFFFFF
+----------------------+ <-- Kernel Space Boundary
| **Kernel Space** | (Operating System Kernel Code/Data)
+----------------------+ <-- 0x7FFF80000000
| **Stack** | ↓ Grows Downward
| - Function Stack Frame |
| - Local Variables |
| - Return Address | <-- RSP (Stack Pointer Register)
+----------------------+
| **Shared Library Mapping** | (Dynamic Link Library Load Location)
| - libc.so |
| - ld-linux-x86-64 |
+----------------------+
| **Memory Mapping Segment** | (mmap Allocated Area)
| - File Mapping |
| - Anonymous Mapping |
+----------------------+
| ↓ |
| **Heap** | ↑ Grows Upward
| - malloc/new Allocated Area | <-- brk/sbrk Boundary
+----------------------+ <-- Program Break (brk)
| **BSS Segment** | (Uninitialized Global Data)
| - Uninitialized Global Variables |
| - Variables Initialized to 0 |
+----------------------+
| **DATA Segment** | (Initialized Global Data)
| - Initialized Global Variables |
| - Static Variables |
| - Constant Strings |
+----------------------+
| **RODATA Segment** | (Read-Only Data)
| - String Constants |
| - const Global Constants |
+----------------------+
| **TEXT Segment** | (Code Segment)
| - Machine Instructions |
| - Function Code | <-- RIP (Instruction Pointer)
+----------------------+
| **Reserved Area** | (0x00000000-0x400000)
Low Address 0x00000000000000
II. In-Depth Analysis of Key Memory Areas
1. Code Segment (TEXT)
- Content: Compiled Machine Instructions
- Permissions:
<span>r-x</span>(Readable/Executable, Not Writable) - Characteristics:
- All processes share the same physical copy (Copy-On-Write)
- Contains function entry points (
<span>_start</span>,<span>main</span>) - Example:
$ readelf -S a.out |grep .text [13] .text PROGBITS 0000000000401040 001040...
2. Data Segment (DATA/BSS)
| Segment Name | Stored Content | ELF Section Name | Initialization Method |
|---|---|---|---|
| DATA | Explicitly Initialized Global/Static Variables | <span>.data</span> |
Read from file during program loading |
| BSS | Uninitialized Global/Static Variables | <span>.bss</span> |
Initialized to zero by the kernel |
| RODATA | Read-Only Constants | <span>.rodata</span> |
Initialized during program loading |
- Example Code:
int data_var =42;// DATA Segment const char* rodata ="ABC";// RODATA Segment (.rodata) static int bss_var;// BSS Segment
3. Heap
- Management Mechanism:
+-------------------+ | glibc's ptmalloc2 | ← User Space Memory Allocator +-------------------+ | brk() System Call | ← Adjusts program break position +-------------------+ | Kernel's vm_area_struct | ← Manages Virtual Memory Areas +-------------------+ - Allocation Process:
<span>malloc(128)</span><span> checks thread-local cache (tcache)</span>- Miss → checks fast bins/free lists
- Still Miss → extends heap via
<span>brk()</span><span> or </span><code><span>mmap()</span>
4. Stack
- Stack Frame Structure Details:
High Address +-------------------+ | Parameter n | | ... | | Parameter 1 | +-------------------+ | Return Address | ← Return Position After Call +-------------------+ | Saved EBP | ← Current Stack Frame Base +-------------------+ | Local Variable 1| | Local Variable 2| | ... | +-------------------+ | Alignment Padding| ← Stack Alignment Requirement (16 bytes) +-------------------+ ← Current Stack Top (RSP) Low Address - Registers:
- RSP: Stack Top Pointer Register
- RBP: Stack Base Pointer Register (Optional Use)
- RIP: Address of Next Instruction
III. Advanced Memory Areas
1. Memory Mapping Segment
- Allocation Method:
<span>mmap()</span><span> System Call</span> - Usage Scenario:
// File Mapping void* file_map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); // Anonymous Mapping (Large Memory Allocation) void* big_mem = mmap(NULL, 1<<30, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - Advantages: Independent of heap, directly managed by the kernel, suitable for large memory blocks
2. Thread Stack
- Characteristics:
+---------------------+ | Main Thread Stack (8MB) | +---------------------+ | Thread 1 Stack (2MB) | +---------------------+ | Thread 2 Stack (2MB) | +---------------------+ | ... | - Each thread has an independent stack (default 2-10MB)
- Created via
<span>pthread_create()</span> - Located in Memory Mapping Segment
3. Kernel Space
- Composition:
+---------------------+ | Direct Mapping Area | ← 1:1 Mapping of Physical Memory +---------------------+ | vmalloc Area | ← Non-contiguous Physical Page Mapping +---------------------+ | Persistent Kernel Mapping Area | ← High Memory Mapping +---------------------+ | Fixed Mapping Area | +---------------------+
IV. Example Analysis: Complete Memory Snapshot
C Program Example
#include<stdlib.h>
#include<stdio.h>
int global_init =10;// DATA Segment
char* str ="Hello";// RODATA Segment (Pointer in DATA)
int global_uninit;// BSS Segment
void func(int param){// TEXT Segment
int local =20;// Stack
static int static_local =30;// DATA Segment
int* heap_var = malloc(sizeof(int));// Heap
printf("%s\n", str);// Calls Library Function (Shared Library Mapping Area)
}
int main(){
func(42);
return 0;
}
Runtime Memory Layout Illustration
0x7ffff7ffb000 +----------------------+
| Main Thread Stack |
| - main Stack Frame |
| - func Stack Frame |
| param=42 |
| local=20 |
0x7ffff7de0000 +----------------------+ <-- Shared Library Mapping Area
| libc.so Code/Data |
| printf Implementation Code |
0x7ffff7a00000 +----------------------+ <-- Heap Top (brk)
| malloc Allocated heap_var |
+----------------------+
| ... (Heap Space) |
0x55555555a000 +----------------------+ <-- BSS Segment
| global_uninit (Initialized to 0) |
0x555555559000 +----------------------+ <-- DATA Segment
| global_init=10 |
| str (Points to RODATA Address) |
| static_local=30 |
0x555555558000 +----------------------+ <-- RODATA Segment
| "Hello" String Constant |
0x555555554000 +----------------------+ <-- TEXT Segment
| func Machine Code |
| main Machine Code |
0x400000 +----------------------+
V. Key Numbers in Memory Management
| Parameter | Typical Value | View Command |
|---|---|---|
| Default Stack Size | 8MB (Linux) | <span>ulimit -s</span> |
| Page Size | 4KB | <span>getconf PAGE_SIZE</span> |
| Heap Allocation Threshold | 128KB (glibc) | <span>mallopt(M_MMAP_THRESHOLD)</span> |
| Maximum Offset for TEXT/DATA | 2GB (32-bit System) | Controlled by Compile Link Parameters |
| ASLR Randomization Range | ±28 bits (Linux) | <span>/proc/sys/kernel/randomize_va_space</span> |
VI. Advanced Topic: Underlying Principles of Memory Mapping
Mapping Virtual Memory to Physical Memory
Virtual Address Space Page Table Physical Memory
+---------------+ +-----------+ +---------------+
| 0x400000 | → | PTE | → | Code Page 1 |
| (TEXT) | +-----------+ +---------------+
+---------------+ +-----------+ +---------------+
| 0x600000 | → | PTE | → | Data Page |
| (DATA) | +-----------+ +---------------+
+---------------+ +-----------+ +---------------+
| 0x7fff0000 | → | PTE | → | Stack Page |
| (Stack) | +-----------+ +---------------+
+---------------+ +-----------+ +---------------+
| 0x100000000 | → | PTE | → | Heap Page |
| (Heap) | +-----------+ +---------------+
Page Fault Handling Process
- CPU accesses unmapped virtual address
- Triggers Page Fault
- Kernel checks access validity
- Allocates physical page/loads file content
- Updates page table entry
- Returns to user mode to re-execute instruction
VII. Diagnostic Tools
-
Linux Process Mapping:
cat /proc/$PID/mapsOutput Example:
00400000-00401000 r-xp 00000000 08:01 /app # TEXT 00600000-00601000 r--p 00000000 08:01 /app # DATA 00601000-00602000 rw-p 00001000 08:01 /app # BSS 7ffff7a00000-7ffff7bc0000 rw-p 00000000 00:00 0 # Heap 7ffff7bd0000-7ffff7bd1000 rw-p 00000000 00:00 0 # Anonymous Mapping 7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 # Stack -
Windows Tools:
- VMMap (SysInternals)
- WinDbg
<span>!address</span>Command