Memory layout and Linux layout of C Programs on linux
Before studying this issue carefully, I think the C program only consists of code segments, stacks, and stacks in the memory. Only when I was asked this question a few days ago did I find that my impression was incomplete.
In this article, we analyze the variables and function addresses in a C program to analyze the layout of the C program in memory.
First, we will briefly introduce the Memory Distribution of C Programs on Linux.
In general, from the low address to the high address distribution:
- Program code segment and read-only data segment
- Program code and string constants are stored here
- Readable and writable Data Segment
- Global variables. Static variables are stored here.
- Data heap
- The Dynamic Allocation in the program exists.
- Shared Library
- The shared library loaded by the program is loaded in this place.
- Data Stack
- Local variables, function parameters, and function return addresses are stored here.
- Kernel address
- Operating system kernel memory space
The C language code is as follows (var_memory.c)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include <sys/types.h> 5 #include <unistd.h> 6 #include <errno.h> 7 #include <argp.h> 8 9 int global = 123;10 static int static_global = 123;11 12 int main()13 {14 char *string_literal = "hello";15 static int static_local = 456;16 char local_array[100] = {'a', 'b', 'c'};17 int *malloced = (int *)malloc(10*sizeof(int));18 19 pid_t pid = getpid();20 printf("pid: %ld\n", (long)pid);21 22 // string_literaling literal and function in this module are loaded23 // into readonly and excutable segment24 printf("%.8p: addr of main\n", &main);25 printf("%.8p: addr of local string_literal literal\n", string_literal);26 puts("");27 28 // static and global variables are allocated in data segment29 printf("%.8p: addr of global int\n", &global);30 printf("%.8p: addr of global static int\n", &static_global);31 printf("%.8p: addr of local static int\n", &static_local);32 puts("");33 34 // allocated in heap35 printf("%.8p: addr of local malloc\n", malloced);36 puts("");37 38 // errno is from a library39 printf("%.8p: addr of errno\n", &errno);40 puts("");41 42 // printf is from a library43 printf("%.8p: addr of printf\n", &printf);44 puts("");45 46 printf("%.8p: addr of argp_program_verstatic_localon_hook\n", & argp_program_version_hook);47 puts("");48 49 // local variable in stack50 printf("%.8p: addr of local pid\n", &pid);51 printf("%.8p: addr of local array\n", local_array);52 puts("");53 54 scanf("%s", local_array);55 return 0;56 }
Linux Command Line
make var_memory.c
Generate the var_memory executable file and run
./var_memory
The output is as follows:
1 pid: 4760 2 0x004b26dd: addr of main 3 0x004b29d0: addr of local string_literal literal 4 5 0x004b4008: addr of global int 6 0x004b400c: addr of global static int 7 0x004b4010: addr of local static int 8 9 0x00d30160: addr of local malloc10 11 0xb7db86b4: addr of errno12 13 0xb7e0b1c0: addr of printf14 15 0xb7f8f798: addr of argp_program_verstatic_localon_hook16 17 0xbf85518c: addr of local pid18 0xbf855198: addr of local array
Open another terminal window and run the command according to the pid output above
Pmap 4760 # process id output above shall prevail
Output:
1 4760: ./var_memory 2 004b2000 4K r-x-- var_memory 3 004b3000 4K r---- var_memory 4 004b4000 4K rw--- var_memory 5 00d30000 136K rw--- [ anon ] 6 b7db8000 8K rw--- [ anon ] 7 b7dba000 1852K r-x-- libc-2.26.so 8 b7f89000 4K ----- libc-2.26.so 9 b7f8a000 8K r---- libc-2.26.so10 b7f8c000 4K rw--- libc-2.26.so11 b7f8d000 12K rw--- [ anon ]12 b7fbb000 8K rw--- [ anon ]13 b7fbd000 12K r---- [ anon ]14 b7fc0000 8K r-x-- [ anon ]15 b7fc2000 148K r-x-- ld-2.26.so16 b7fe7000 4K r---- ld-2.26.so17 b7fe8000 4K rw--- ld-2.26.so18 bf836000 132K rw--- [ stack ]19 total 2352K
We can see from the output of running the C language program and pmap.
- The main function (0x004b26dd) and String constant (0x004b29d0) are allocated in the memory area.
- 004b2000 4 K r-x -- var_memory. rx indicates read-only and executable.
- Global variable (0x004b4008), global static variable static_global (0x004b400c), local static variable (0x004b4010) is allocated in the Data Segment
- 004b4000 4 K rw --- var_memory, where rw indicates read and write.
- The space allocated using malloc (0x00d30160) is in heap
- 00d30000 136 K rw --- [anon]
- The global variable errno (0xb7db86b4) provided by the shared library is allocated to the Data Segment of the shared library.
- B7db8000 8 K rw --- [anon]
- The printf (0xb7e0b1c0) function provided by the shared library is allocated to the shared library code segment.
- B7dba000 1852 K r-x -- libc-2.26.so
- Local variables (0xbf85518c, 0xbf855198) are allocated to the stack.
- Bf836000132 K rw --- [stack]
I hope this article will help you with the layout of C Programs in the memory.