X86 assembly language learning Notes (3) Author: Badcoffee
Email: blog.oliver@gmail.com
December 2004
Original article: http://blog.9cbs.net/yayong
Copyright: Please be sure to indicate the original source, author information and this statement by hyperlink.
This is the author's study notes in the process of learning the X86 assembly, which is inevitable to have errors and omissions. Welcome to correct.
Strictly speaking, the content involved in this document is not limited to the X86 assembly area, with respect to the ELF file format, C language, compiler, and other related knowledge, also refer to the relevant documentation.
The author will update the feedback error and update in your own
BLOG site.
In X86 Assembly Language Learning Intention (1) (2), you can see the stack as a temporary storage area of data during the process execution, usually contains the following types of data:
Local variable
Return address of function call
Entry parameters of function call
SFP stack frame pointer (can be removed by compiler optimization option)
In this chapter, we will continue to pass experiments, understand how global variables and static variables are stored and assigned in the process.
Note: Different CALLING CONVENTIONs have a difference in the provisions of the entrance parameters, and the function call entry parameters may also pass the registers.
For example, IBM's Power PC and AMD's Opteron, all of the port parameters of the function are passed through registers.
1. Experiment of global variables and global constants
Before the continuation, a simple C procedure is given, which is divided into three types of global variables:
Initialized global variable
Unmelted global variable
Global constant
#vi test5.c
INT i = 1;
INT J = 2;
INT K = 3;
INT L, M;
Int n;
Const Int O = 7;
Const Int P = 8;
Const Int Q = 9;
int main ()
{
L = 4;
m = 5;
n = 6;
RETURN I J K L M N O P Q;
}
# GCC Test5.c -o test5
# MDB Test5
Loading Modules: [Libc.so.1]
> Main :: DIS
Main: pushl% EBP
Main to main 1, create a Stack Frame
Main 1: MOVL% ESP,% EBP
Main 3: SUBL $ 8,% ESP
Main 6: Andl $ 0xF0,% ESP
Main 9: MOVL $ 0,% EAX
Main 0xe: Subl% EAX,% ESP
Main 3 to main 0xe, reserve stack space for local variables, and ensure that the stack is 16 bytes aligned
Main 0x10: MOVL $ 4,0x8060948
; l = 4
Main 0x1a: MOVL $ 5,0x806094c
; = 5
Main 0x24: MOVL $ 6,0x8060950
; n = 6
Main 0x2e: MOVL 0x8060908,% EAX
Main 0x33: AddL 0x8060904,% EAX
Main 0x39: AddL 0x806090c,% EAX
Main 0x3f: AddL 0x8060948,% Eaxmain 0x45: AddL 0x806094c,% EAX
Main 0x4b: AddL 0x8060950,% EAX
Main 0x51: AddL 0x8050808,% EAX
Main 0x57: AddL 0x805080c,% EAX
Main 0x5d: addl 0x8050810,% EAX
Main 0x2e to Main 0x5D, I J K L M N O P Q
MAIN 0x63: LEAVE
Undo STACK FRAME
Main 0x64: RET
Main function returns
Now, let's set breakpoints after the global variable initialization, observe the value of these global variables:
> main 0x2e: B
Set breakpoints
>: r
Operating procedures
MDB: Stop at Main 0x2e
MDB: Target Stopped AT:
Main 0x2e: MOVL 0x8060908,% EAX
> 0x8060904, 03 / NAP
View the value of global variables I, J, K
Test5`i:
Test5`i:
TEST5`I: 1
TEST5`J: 2
TEST5`k: 3
> 0x8060948, 03 / NAP
View the value of global variables L, M, N
TEST5`L:
TEST5`L:
Test5`l: 4
TEST5`m: 5
TEST5`N: 6
> 0x8050808, 03 / NAP
View the value of global variables O, P, Q
o:
o:
o: 7
P: 8
Q: 9
>
Concept: Process Address Space
---------------------- ----> 0xffffffFFF (4GB)
| | |
| Kernel space |
| | |
---------------------- ----> _kernel_base (0xE0000000)
| | |
| Other Library |
::
::
| | |
--------------------
| Data Section |
| LIB C LIBRARY |
| Text Section |
::
::
-------------------- |
| | |
::
: Grow up:
::
| User HEAP |
| | |
--------------------
| BSS |
| | |
| User Data |
| | |
--------------------
| | |
| User Text |
| | |
| | |
-------------------- ----> 0x08050000
| | |
| User Stack |
| | |
: Grow Down:
::
::
| | |
| | |
-------------------- ----> 0
Figure 3-1 Process Address Space on Solaris on IA32
As shown in Figure 3-1, the process address space and Linux on the IA32 are similar, and within the 4GB address space of the user process:
KERNEL is always mapped to the highest end of the user address space, from the macro definition _kernel_base to 0xffffffffff
All shared libraries dependent on the user process are immediately behind the high end of the kernel mapping in the user address space.
Finally, the user process address space is low in address space.
The code segment of each shared library stores binary executable machine instructions, which is the code segment map of the library ELF file to the virtual space, the attribute is Read / Exec / Share
The data segment of each shared library stores the overall variable required to perform the program, which is the data segment map of the ELF file to the virtual space, attribute is Read / Write / Private
The user code segment, stores the executable machine instructions of binary forms, is the code segment map of the ELF file to the doubling space, the attribute is Read / Exec
The user code segment is the data segment, stores the global variable required by the program execution, is the data segment map of the ELF file to the virtual space, attribute is Read / Write / Private
Under the user code segment is a stack, as a temporary data area of the process, is the anonymous memory Map to the virtual space, the property is Read / Write / EXEC
The user data segment is a heap (HEAP), and only when Malloc is called, it is called anonymous memory map to the virtual space, the property is Read / Write / EXEC Note Stack and HEAP Differences and contact:
Same point:
1. Both come from the anonymous memory assigned by the Kernel, and the ELF file on the disk is independent.
2. The property is Read / Write / Exec
difference:
1. Allocation of the stack is generally caused by the declaration of local variables, and the assignment of the stack is caused by explicit calls (malloc).
2. The release of the stack is transparent to the user, and the user does not need to care. The corresponding instructions generated by the C compiler will be released; the heap needs explicit calls (free) to release
3. The growth direction of the stack space is from the high address to the low address; the growth direction of the heap space is from the low address to the high address.
4. The stack is in the address space of any process; the stack does not exist without calling malloc in the program.
The layout of the user address space With the difference in CPU and OS, the above is discussed based on the X86 CPU on the Solaris OS.
Using the PMAP command, you can observe the address space distribution of the specified process in the system, one is an example of using the PMAP to observe the Bash process:
# pmap 1030
1030: -bash
08045000 12k rw --- [stack]
; Bash's stack
08050000 444k R-X-- / USR / BIN / BASH
; Bash text section
080CE000 72K RWX - / USR / BIN / BASH
; BASH data segment
080e0000 156k rwx - [HEAP]
Bash's pile
DD8C0000 8K R-X - /USR/LIB/LOCALE/EN_CN.GB18030/Methods_zh_cn.gb18030.so.2
Shared library text segment
DD8D1000 4K rwx - /usr/lib/locale/en_cn.gb18030/methods_zh_cn.gb18030.so.2
Data segment of shared library
DD8E0000 324K R-X - /USR/LIB/LOCALE/EN_CN.GB18030/EN_CN.GB18030.SO.2
DD940000 8K rwx - /usr/lib/locale/en_cn.gb18030/en_cn.gb18030.so.2
DD950000 4K rwx - [Anon]
Anonymous memory, created by mapping / dev / zero devices
DD960000 12K R-X - /USR/LIB/LIBMP.SO.2
DD973000 4K rwx - /usr/lib/libmp.so.2
DD980000 628K R-X - /USR/LIB/LIBC.SO.1
DDA2D000 24K rwx - /usr/lib/libc.so.1
DDA33000 4K rwx - /usr/lib/libc.so.1
DDA50000 4K rwx - [Anon]
DDA60000 548K R-X - /USR/LIB/LIBNSL.SO.1
DDAF9000 20K rwx - /usr/lib/libnsl.so.1
DDAFE000 32K RWX - /usR/LIB/Libnsl.so.1
DDB10000 44K R-X - /USR/LIB/LIBSOCKET.SO.1
DDB2B000 4K rwx - /usr/lib/libsocket.so.1
DDB30000 152K R-X - /USR/LIB/LIBCURS.SO.1
DDB66000 28K rwx - /usr/lib/libcurses.so.1
DDB6D000 8K rwx - /usr/lib/libcurses.so.1
DDB80000 4K R-X - /USR/LIB/LIBDL.SO.1
DDB90000 292K R-X - /USR/LIB/ld.so.1
DDBE9000 16K rwx - /usr/lib/ld.so.1
DDBED000 8K rwx - /usr/lib/ld.so.1
Total 2864K
Question: Global variables and global constants in the process space location?
Obviously, according to the previous description, global variables are in the user's data segment, then the global constant is the data segment?
Similarly, you can use MDB to hang the Test5 process, then use the PMAP command to verify:
# MDB Test5
Loading Modules: [Libc.so.1]
> :: sysbp _exit
; Set breakpoints in system call _exit
>: r
Operating procedures
MDB: Stop on entry to _exit
MDB: Target Stopped AT:
Libc.so.1`exit 0x2b: Jae 0x15
>
At this point, after the program is running, you can use the PMAP to view the address space of the Test5 process in another terminal:
# ps -ef | GREP TEST5
Root 1387 1386 0 02:23:53 PTS / 1 0:00 Test5
Root 1399 1390 0 02:25:03 PTS / 3 0:00 GREP TEST5
Root 1386 1338 0 02:23:41 PTS / 1 0:00 MDB TEST5
# pmap -f 1387
Formed with PMAP
1387: TEST5
08044000 16K rwx - [stack]
Test5 stack
08050000 4K R-X-- / EXPORT / HOME / ASM / L3 / TEST5
The code section of TEST5, the start address is 0x08050000
08060000 4K RWX - / EXPORT / HOME / ASM / L3 / TEST5
; Test5 data segment, start address is 0x08060000
DDAC0000 628k R-X - /USR/LIB/LIBC.SO.1
DDB6D000 24K rwx - /usr/lib/libc.so.1
DDB73000 4K rwx - /usr/lib/libc.so.1
DDB80000 4K R-X - /USR/LIB/LIBDL.SO.1
DDB90000 292K R-X - /USR/LIB/ld.so.1
DDBE9000 16K rwx - /usr/lib/ld.so.1
DDBED000 8K rwx - /usr/lib/ld.so.1
Total 1000K
It can be seen that since the Test5 program does not use Malloc to apply for memory, there is no map of HEAP.
The initialization values of these global variables and constants were observed in front of MDB, and their addresss were:
Global variables I, J, K: 0x8060904 start 12 bytes
Global variable L, M, N:
0x8060948 start 12 bytes
Global constant O, P, Q:
0x8050808 start 12 bytes
Obviously, according to the address of these variables, we can initially determine which paragraph belongs to these variables:
Since the Test5 data segment start address is
0x08060000
We conclude that the global variables I, J, K, L, M, N belong to the data segment and the starting address of the TEST5 code segment is
0x08050000, we conclude: global constant O, P, Q belong to code segment
It is indeed an accident that this conclusion is indeed: the global constant is actually in the code segment.
But it seems that in the reason: the attribute after the data segment memory is R / W / X, and the constant requirement is read-only attribute, so it is reasonable in the code segment (R-X).
Question: Why is these global variable addresses not continuous?
It is easy to note that global variables I, J, K and L, M, N, and global constant O, P, Q are continuous declarations, but the address is actually discontinuous, but at 3 segments continuous 12-byte address on.
Of course, the global constant is a code segment, so the address and global variable are separated; then why global variables are not continuous?
The data segment is actually mapped from the ELF format to the process of address space, and then find the answer by analyzing the ELF file format:
# File Test5
TEST5: ELF 32-BIT LSB EXECUTABLE 80386 VERSION 1, DYNAMICALLY LINKED, NOT STRIPPED
# Elfdump Test5
Elf Header
; ELF header information Total 52 (0x34) bytes, specific meaning can be referred to ELF FORMAT related documentation
EI_Magic: {0x7F, E, L, F}
Elf's magic
EI_CLASS: Elfclass32 Ei_Data: Elfdata2lsb
; 32-bit ELF file, small end (LSB) encoding
E_MACHINE: EM_386 E_VERSION: EV_CURRENT
; Intel 80386, version 1
E_TYPE: ET_EXEC
; executable file
E_FLAGS: 0
E_ENTRY: 0x8050600 E_EHSIZE: 52 E_SHSTRNDX: 27
; Program entry point _Start's address 0x8050600
E_SHOFF: 0x1584 E_SHENTSIZE: 40 E_SHNUM: 29
The size of the section header Table is 29 * 40
E_PHOFF: 0x34 E_PHENTSIZE: 32 E_PHNUM: 5
Program header [0]:
;
description
Program Header Table itself How to map in memory
p_vaddr:
0x8050034 p_flags: [pf_x pf_r]
p_paddr: 0 p_type: [PT_phdr]
P_filesz: 0xA0 p_memsz: 0xA0
P_offset: 0x34 p_align: 0
Program header [1]:
Describe the path name of the program loader (.Interp Section) stores in the file
P_vaddr: 0 p_flags: [PF_R] p_paddr: 0 p_type: [PT_INTERP]
p_filesz: 0x11 p_memsz: 0
P_offset: 0xD4 P_ALIGN: 0
Program Header [2]:
;
description
How to map in the memory, start address 0x8050000, size is 0x814
p_vaddr:
0x8050000 p_flags: [pf_x pf_r]
p_paddr: 0 p_type: [Pt_Load]
P_filesz: 0x814 p_memsz: 0x814
P_offset: 0 p_align: 0x10000
Program Header [3]:
Describe how the data segment is mapped in memory, the start address 0x8060814, the size is 0x144
p_vaddr:
0x8060814 p_flags: [pf_x pf_w pf_r]
p_paddr: 0 p_type: [Pt_Load]
P_filesz: 0x118 p_memsz: 0x144
p_offset: 0x814 p_align: 0x10000
Program header [4]:
;
description
Dynamic link information (.dynamic section)
How to map in memory
p_vaddr:
0x8060848 p_flags: [pf_x pf_w pf_r]
p_paddr: 0 p_type: [pt_dynamic]
P_filesz: 0xB8 p_memsz: 0
P_offset: 0x848 P_ALIGN: 0
Section header [1]: SH_NAME: .INTERP
This section saves the path of the program's interpretator (Interpreter)
SH_ADDR:
0x80500d4 sh_flags: [shf_alloc]
SH_SIZE: 0x11 sh_type: [SHT_PROGBITS]]
SH_OFFSET: 0xD4 Sh_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [2]: sh_name: .hash
This section saves a sign of a symbol
SH_ADDR:
0x80500E8 sh_flags: [shf_alloc]
SH_SIZE: 0x104 sh_type: [sht_hash]
SH_OFFSET: 0xE8 Sh_ENTSIZE: 0X4
SH_LINK: 3 sh_info: 0
SH_ADDralign: 0x4
Section header [3]: sh_name: .dynsym
This section saves a dynamic symbol table
SH_ADDR:
0x80501ec sh_flags: [shf_alloc]
SH_SIZE: 0x200 sh_type: [sht_dynsym] sh_offset: 0x1ec sh_entsize: 0x10
SH_LINK: 4 sh_info: 1
SH_ADDralign: 0x4
Section header [4]: sh_name: .dynStr
The section saves the string required when dynamically connected
SH_ADDR:
0x80503ec sh_flags: [SHF_alloc SHF_STRINGS]
SH_SIZE: 0x11A SH_TYPE: [SHT_STRTAB]
SH_OFFSET: 0x3ec sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section Header [5]: sh_name: .sunw_version
This section is SUN extension, save version information
SH_ADDR:
0x8050508 sh_flags: [shf_alloc]
SH_SIZE: 0x20 sh_type: [sht_sunw_verneed]
SH_OFFSET: 0x508 sh_entsize: 0
SH_LINK: 4 sh_info: 1
SH_ADDralign: 0x4
Section header [6]: SH_NAME: .REL.GOT
This section saves the repositioning information of some symbols in .got Section
SH_ADDR:
0x8050528 sh_flags: [SHF_ALLOC SHF_INFO_LINK]
SH_SIZE: 0x18 sh_type: [SHT_REL]
SH_OFFSET: 0x528 sh_entsize: 0x8
SH_LINK: 3 sh_info: 14
SH_ADDralign: 0x4
Section Header [7]: sh_name: .rel.bss
This section saves. Relocation information of some symbols in the .BSS Section
SH_ADDR:
0x8050540 sh_flags: [SHF_ALLOC SHF_INFO_LINK]
SH_SIZE: 0x8 sh_type: [SHT_REL]
SH_OFFSET: 0x540 sh_entsize: 0x8
SH_LINK: 3 sh_info: 22
SH_ADDralign: 0x4
Section header [8]: SH_NAME: .REL.PLT
This section saves the reposition information of partial symbols in PLT Section.
SH_ADDR:
0x8050548 sh_flags: [SHF_alloc SHF_INFO_LINK]
SH_SIZE: 0x38 sh_type: [SHT_REL]
SH_OFSET: 0x548 sh_entsize: 0x8
SH_LINK: 3 sh_info: 9
SH_ADDralign: 0x4
Section header [9]: SH_NAME: .plt
This section saves the process connection table (Procedure Linkage Table) SH_ADDR:
0x8050580 sh_flags: [SHF_ALLOC SHF_EXECINSTR]
SH_SIZE: 0x80 sh_type: [sht_progbits]
SH_OFFSET: 0x580 sh_entsize: 0x10
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [10]: sh_name: .text
This section saves the text section of the program, that is, executable instructions
SH_ADDR:
0x8050600 sh_flags: [SHF_ALLOC SHF_EXECINSTR]
SH_SIZE: 0x1ec sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x600 Sh_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [11]: SH_NAME: .INIT
This section saves an executable instruction that constitutes the initialization code of the process.
SH_ADDR:
0x80507ec sh_flags: [SHF_ALLOC SHF_EXECINSTR]
SH_SIZE: 0XD SH_TYPE: [SHT_PROGBITS]
SH_OFFSET: 0x7ec sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [12]: SH_NAME: .fini
This section saves an executable instruction that constitutes the termination code of the process.
SH_ADDR:
0x80507f9 sh_flags: [SHF_ALLOC SHF_EXECINSTR]
Sh_size: 0x8 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x7f9 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [13]: SH_NAME: .RODATA
This section saves read-only data
SH_ADDR:
0x8050804 sh_flags: [shf_alloc]
SH_SIZE: 0x10 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x804 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [14]: SH_NAME: .GOT
This section saves the global offset table
SH_ADDR:
0x8060814 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x34 sh_type: [SHT_PROGBITS]]
SH_OFFSET: 0x814 sh_entsize: 0x4
SH_LINK: 0 sh_info: 0sh_addralign: 0x4
Section header [15]: SH_NAME: .Dynamic
This section saves a dynamic connection information
SH_ADDR:
0x8060848 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0xB8 sh_type: [sht_dynamic]
SH_OFFSET: 0x848 sh_entsize: 0x8
SH_LINK: 4 sh_info: 0
SH_ADDralign: 0x4
Section header [16]: SH_NAME: .DATA
The sections saves the initialized data
SH_ADDR:
0x8060900 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x10 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x900 Sh_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [17]: SH_NAME: .CTORS
SH_ADDR:
0x8060910 sh_flags: [SHF_WRITE SHF_ALLOC]
Sh_size: 0x8 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x910 SH_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [18]: SH_NAME: .dtors
SH_ADDR:
0x8060918 sh_flags: [SHF_WRITE SHF_ALLOC]
Sh_size: 0x8 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x918 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [19]: SH_NAME: .e_frame
SH_ADDR:
0x8060920 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x4 sh_type: [SHT_PROGBITS]
SH_OFSET: 0x920 SH_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [20]: sh_name: .jcr
SH_ADDR:
0x8060924 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x4 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x924 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [21]: sh_name: .data.rel.localsh_addr:
0x8060928 sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x4 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x928 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [22]: SH_NAME: .BSS
This SECTIOPN holds unmelted data
SH_ADDR:
0x806092c sh_flags: [SHF_WRITE SHF_ALLOC]
SH_SIZE: 0x2c sh_type: [SHT_NOBITS]
Indicates that do not occupy the ELF space SH_SIZE is the size of the memory
SH_OFSET: 0x92c sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [23]: SH_NAME: .ssymTab
This section saves a symbol table
SH_ADDR: 0 sh_flags: 0
SH_SIZE: 0x540 sh_type: [SHT_SYMTAB]
SH_OFFSET: 0x92c sh_entsize: 0x10
SH_LINK: 24 sh_info: 53
SH_ADDralign: 0x4
Section header [24]: SH_NAME: .STRTAB
This section saves a string table
SH_ADDR: 0 sh_flags: [shf_strings]
SH_SIZE: 0x20B sh_type: [SHT_STRTAB]
SH_OFFSET: 0xE6C SH_ENTSIZE: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [25]: sh_name: .comment
This section saves version control information
SH_ADDR: 0 sh_flags: 0
SH_SIZE: 0x24D sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x1077 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [26]: SH_NAME: .STAB.INDEX
SH_ADDR: 0 sh_flags: 0
SH_SIZE: 0x24 sh_type: [SHT_PROGBITS]
SH_OFFSET: 0x12c4 sh_entsize: 0xc
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x4
Section header [27]: SH_NAME: .SHSTRTAB
This section saves the section name
SH_ADDR: 0 sh_flags: [shf_strings]
SH_SIZE: 0xDC SH_TYPE: [SHT_STRTAB]
SH_OFFSET: 0x12E8 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Section header [28]: sh_name: .stab.indexstr
SH_ADDR: 0 sh_flags: 0
SH_SIZE: 0x1c0 sh_type: [SHT_STRTAB]
SH_OFFSET: 0x13c4 sh_entsize: 0
SH_LINK: 0 sh_info: 0
SH_ADDralign: 0x1
Interpreter:
/usr/lib/ld.so.1
Version needed section: .sunw_version
FILE VERSION
Libc.so.1 sysvabi_1.3
Symbol Table: .dynsym
; Dynamic parsing and link required
Index Value Size Type Bind Oth Ver Shndx Name
[0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF
[1] 0x080507ec 0x0000000D Func Glob D 0 .init _init
[2] 0x08050804 0x00000004 Objt Glob D 0.Rodata _lib_version
[3] 0x08050580 0x00000000 OBJT GLOB D 0 .plt _procedure_linkage_table_
[4] 0x08050600 0x00000075 Func Glob D 0 .Text _Start
[5] 0x08060900 0x00000000 Objt Glob D 0 .DATA __DSO_HANDLE
[6] 0x08060848 0x00000000 Objt Glob D 0 .dynamic _ Dynamic
[7] 0x00000000 0x00000000 NOTY Weak D 0 undef __deregister_frame_info_bases
[8] 0x08050814 0x00000000 Objt Glob D 0 .Rodata _text
[9] 0x08060958 0x00000000 Objt Glob D 0 .BSS _END
[10] 0x08050590 0x00000000 FUNC Weak D 0 undef _cleanup
[11] 0x08050675 0x00000001 FUNC Weak D 0 .Text _mcount
[12] 0x08060904 0x00000004 Objt Glob D 0 .data i
[13] 0x08060908 0x00000004 Objt Glob D 0 .data J
[14] 0x0806090c 0x00000004 Objt Glob D 0 .data K [15] 0x08060948 0x00000004 Objt Glob D 0 .bss L
[16] 0x08060954 0x00000004 Objt Glob D 0 .bss _ENVIRON
[17] 0x08060814 0x00000000 Objt Glob D 0 .got _Global_offset_table_
[18] 0x0806094c 0x00000004 Objt Glob D 0 .bss M
[19] 0x0806092c 0x00000000 Objt Glob D 0 .data.rel.l_edata
[20] 0x08060954 0x00000004 Objt Weak d 0 .bss environ
[21] 0x080507f9 0x00000008 FUNC GLOB D 0 .fini _fini
[22] 0x080505a0 0x00000000 FUNC GLOB D 0 undef atexit
[23] 0x08060950 0x00000004 Objt Glob D 0 .BSS N
[24] 0x08050808 0x00000004 Objt Glob D 0.Rodata O
[25] 0x0805080c 0x00000004 Objt Glob D 0.Rodata P
[26] 0x00000000 0x00000000 NOTY Weak D 0 Undef _JV_REGISTERCLASSES
[27] 0x08050810 0x00000004 Objt Glob D 0.Rodata Q
[28] 0x080505B0 0x00000000 FUNC GLOB D 0 UNDEF __FPSTART
[29] 0x08050753 0x00000065 Func Glob D 0 .Text main
[30] 0x00000000 0x00000000 NOTY Weak D 0 undef __register_frame_info_bases
[31] 0x080505c0 0x00000000 FUNC GLOB D 0 UNDEF EXIT
Symbol Table: .symtab
The symbol table required for program links
Index Value Size Type Bind Oth Ver Shndx Name
[0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF
[1] 0x00000000 0x00000000 File LoCl D 0 ABS TEST5
[2] 0x080500d4 0x00000000 SECT LOCL D 0 .INTERP
[3] 0x080500E8 0x00000000 SECT LOCL D 0 .hash
[4] 0x080501ec 0x00000000 SECT LOCL D 0 .dynsym
[5] 0x080503ec 0x00000000 SECT LOCL D 0 .dynstr
[6] 0x08050508 0x00000000 SECT LOCL D 0 .SUNW_VERSI
[7] 0x08050528 0x00000000 SECT LOCL D 0 .rel.got [8] 0x08050540 0x00000000 SECT LOCL D 0 .rel.bss
[9] 0x08050548 0x00000000 SECT LOCL D 0 .REL.PLT
[10] 0x08050580 0x00000000 SECT LOCL D 0 .plt
[11] 0x08050600 0x00000000 SECT LOCL D 0 .Text
[12] 0x080507ec 0x00000000 SECT LOCL D 0 .init
[13] 0x080507f9 0x00000000 SECT LOCL D 0 .fini
[14] 0x08050804 0x00000000 SECT LOCL D 0 .RODATA
[15] 0x08060814 0x00000000 SECT LOCL D 0 .got
[16] 0x08060848 0x00000000 SECT LOCL D 0. Dynamic
[17] 0x08060900 0x00000000 SECT LOCL D 0 .DATA
[18] 0x08060910 0x00000000 SECT LOCL D 0 .ctors
[19] 0x08060918 0x00000000 SECT LOCL D 0 .dtors
[20] 0x08060920 0x00000000 SECT LOCL D 0 .EH_FRAME
[21] 0x08060924 0x00000000 SECT LOCL D 0 .JCR
[22] 0x08060928 0x00000000 SECT LOCL D 0 .DATA.REL.L
[23] 0x0806092c 0x00000000 SECT LOCL D 0 .BSS
[24] 0x00000000 0x00000000 SECT LOCL D 0 .SYMTAB
[25] 0x00000000 0x00000000 SECT LOCL D 0 .STRTAB
[26] 0x00000000 0x00000000 SECT LOCL D 0 .comment
[27] 0x00000000 0x00000000 SECT LOCL D 0 .STAB.Index
[28] 0x00000000 0x00000000 SECT LOCL D 0 .SHSTRTAB
[29] 0x00000000 0x00000000 SECT LOCL D 0 .STAB.Index
[30] 0x08050000 0x00000000 Objt LoCl D 0 .Interp_Start_
[31] 0x08060958 0x00000000 Objt LOCL D 0 .BSS _END_
[32] 0x00000000 0x00000000 File LoCl D 0 ABS CRT1.S
[33] 0x00000000 0x00000000 File LoCl D 0 ABS CRTI.s
[34] 0x00000000 0x00000000 File LoCl D 0 ABS VALUES-XA.C
[35] 0x00000000 0x00000000 File LoCl D 0 ABS CRTSTUFF.C
[36] 0x08060910 0x00000000 Objt LOCL D 0 .ctors __ctor_list __ [37] 0x08060918 0x00000000 Objt LOCL D 0 .dttors __dtor_list__
[38] 0x08060920 0x00000000 OBJT LOCL D 0 .EH_FRAME __EH_FRAME_BEGIN__
[39] 0x08060924 0x00000000 Objt LOCL D 0 .JCR __JCR_LIST__
[40] 0x08060928 0x00000000 Objt LoCl D 0 .data.rel.l P.0
[41] 0x0806092c 0x00000001 Objt LOCL D 0 .BSS Completed.1
[42] 0x08050678 0x00000000 FUNC LOCL D 0 .TEXT __DO_GLOBAL_DTORS_AUX
[43] 0x08060930 0x00000018 Objt LOCL D 0 .BSS Object.2
[44] 0x080506e4 0x00000000 FUNC LOCL D 0 .TEXT FRAME_DUMMY
[45] 0x00000000 0x00000000 File LoCl D 0 ABS Test5.c
[46] 0x00000000 0x00000000 File LoCl D 0 ABS CRTSTUFF.C
[47] 0x08060914 0x00000000 Objt LOCL D 0 .ctors __ctor_end__
[48] 0x0806091c 0x00000000 Objt LOCL D 0 .dttors __dtor_end__
[49] 0x08060920 0x00000000 OBJT LOCL D 0 .EH_FRAME __FRAME_END__
[50] 0x08060924 0x00000000 OBJT LOCL D 0 .JCR __JCR_END___
[51] 0x080507B8 0x00000000 FUNC LOCL D 0 .TEXT __DO_GLOBAL_CTORS_AUX
[52] 0x00000000 0x00000000 File LoCl D 0 ABS CRTN.O
[53] 0x080507ec 0x0000000D Func Glob D 0 .init _init
[54] 0x08050804 0x00000004 Objt Glob D 0.RODATA _LIB_VERSION
[55] 0x08050580 0x00000000 OBJT GLOB D 0 .plt _procedure_linkage_table_
[56] 0x08050600 0x00000075 Func Glob D 0 .Text _Start
[57] 0x08060900 0x00000000 OBJT GLOB D 0 .DATA __DSO_HANDLE
[58] 0x08060848 0x00000000 Objt Glob D 0 .dynamic_Dynamic
[59] 0x00000000 0x00000000 NOTY Weak D 0 undef __deregister_frame_info_bases [60] 0x08050814 0x00000000 Objt Glob D 0.Rodata_text
[61] 0x08060958 0x00000000 OBJT GLOB D 0 .BSS _END
[62] 0x08050590 0x00000000 FUNC Weak D 0 undef _cleanup
[63] 0x08050675 0x00000001 Func Weak D 0 .Text _mcount
[64] 0x08060904 0x00000004 Objt Glob D 0 .data i
[65] 0x08060908 0x00000004 Objt Glob D 0 .DATA J
[66] 0x0806090c 0x00000004 Objt Glob D 0 .data K
[67] 0x08060948 0x00000004 Objt Glob D 0 .bss L
[68] 0x08060954 0x00000004 Objt Glob D 0 .BSS _ENVIRON
[69] 0x08060814 0x00000000 Objt Glob D 0 .got _Global_offset_table_
[70] 0x0806094c 0x00000004 Objt Glob D 0 .BSS M
[71] 0x0806092C 0x00000000 Objt Glob D 0 .data.rel.l _edata
[72] 0x08060954 0x00000004 Objt Weak D 0 .bss Environ
[73] 0x080507f9 0x00000008 Func Glob D 0 .fini _fini
[74] 0x080505a0 0x00000000 Func Glob D 0 Undef Atexit
[75] 0x08060950 0x00000004 Objt Glob D 0 .BSS N
[76] 0x08050808 0x00000004 Objt Glob D 0 .Rodata O
[77] 0x0805080c 0x00000004 Objt Glob D 0.Rodata P
[78] 0x00000000 0x00000000 NOTY Weak D 0 Undef _JV_REGISTERCLASSES
[79] 0x08050810 0x00000004 Objt Glob D 0.Rodata Q
[80] 0x080505B0 0x00000000 FUNC GLOB D 0 UNDEF __FPSTART
[81] 0x08050753 0x00000065 Func Glob D 0 .Text main
[82] 0x00000000 0x00000000 NOTY Weak D 0 undef __register_frame_info_bases
[83] 0x080505c0 0x00000000 FUNC GLOB D 0 UNDEF EXIT
Hash section: .hash
Bucket SymnDx Name
0 [1] _INIT
1 [2] _LIB_VERSION
[3] _Procedure_linkage_table_
2 [4] _Start
[5] __DSO_HANDLE
4 [6] _Dynamic
9 [7] __deregister_frame_INFO_BASES
[8] _Text
10 [9] _end
12 [10] _CLEANUP
[11] _MCOUNT
[12] i
13 [13] J
14 [14] K
15 [15] L
16 [16] _ENVIRON
[17] _GLOBAL_OFFSET_TABLE_
[18] M
[19] _eData
[20] environ
17 [21] _fini
[22] atexit
[23] n
18 [24] O
19 [25] P
20 [26] _JV_REGISTERCLASSES
[27] Q
25 [28] __FPStart
26 [29] main
29 [30] __register_frame_info_bases
[31] EXIT
13 Buckets Contain 0 Symbols
10 Buckets Contain 1 Symbols
5 Buckets Contain 2 Symbols
2 Buckets Contain 3 Symbols
1 BUCKETS Contain 5 Symbols
31 Buckets 31 Symbols (Globals)
Global Offset Table: 13 Entries
NDX Addr Value Reloc Addend Symbol
[00000] 08060814 08060848 r_386_none 00000000
[00001] 08060818 00000000 r_386_none 00000000
[00002] 0806081c 00000000 r_386_none 00000000
[00003] 08060820 08050596 r_386_jmp_slot 00000000_CLEANUP
[00004] 08060824 080505A6 R_386_JMP_slot 00000000 Atexit
[00005] 08060828 080505B6 r_386_jmp_slot @000000__fpstart
[00006] 0806082c 080505c6 r_386_jmp_slot @000000 EXIT
[00007] 08060830 00000000 r_386_glob_dat 00000000 __deregister_frame_INFO_BASES
[00008] 08060834 080505d6 r_386_jmp_slot 00000000 __deregister_frame_info_bases
[00009] 08060838 00000000 r_386_glob_dat 00000000 __register_frame_info_bases [00010] 0806083c 00000000 r_386_glob_dat 00000000_JV_RegisterClasses
[00011] 08060840 080505E6 r_386_jmp_slot 00000000 _JV_REGISTERCLASESSESSESSESSES
[00012] 08060844 080505f6 r_386_jmp_slot 00000000 __register_frame_INFO_BASES
Relocation: .rel.got
Type Offset Section with Respect to
R_386_glob_dat 0x8060830 .rel.got __deregister_frame_info_bases
R_386_glob_dat 0x8060838 .rel.got __register_frame_info_bases
R_386_glob_dat 0x806083c .rel.got _JV_REGISTERCLASSES
RELOCATION: .rel.bss
Type Offset Section with Respect to
R_386_copy 0x8060954 .rel.bss_ENVIRON
RELOCATION: .rel.plt
Type Offset Section with Respect to
R_386_jmp_slot 0x8060820 .rel.plt_cleanup
R_386_jmp_slot 0x8060824 .rel.plt atexit
R_386_jmp_slot 0x8060828 .rel.plt __fpstart
R_386_jmp_slot 0x806082c .rel.plt exit
R_386_jmp_slot 0x8060834 .rel.plt __deregister_frame_INFO_BASES
R_386_jmp_slot 0x8060840 .rel.plt _jv_registerclasses
R_386_jmp_slot 0x8060844 .rel.plt __register_frame_info_bases
Dynamic Section: .dynamic
Index Tag Value
[0] Needed 0x104 libc.so.1
[1] init 0x80507ec
[2] Fini 0x80507F9
[3] Hash 0x80500E8
[4] strtab 0x80503ec [5] strsz 0x11a
[6] SYMTAB 0x80501EC
[7] SYMENT 0x10
[8] Checksum 0x6a10
[9] Verneed 0x8050508
[10] VerneedNum 0x1
[11] PLTRELSZ 0x38
[12] PLTREL 0x11
[13] jmprel 0x8050548
[14] rel 0x8050528
[15] relsz 0x58
[16] rent 0x8
[17] Debug 0
[18] Feature_1 0x1 [Parinit]
[19] Flags 0 0
[20] Flags_1 0 0
[21] Pltgot 0x8060814
With ELFDUMP, you can view the details of the ELF file format, you can find global variables and global constants defined in the program in the symbol table. Dynsym and .SymTab:
I, J, K in .data Section
l, m, n in .bss section
O, p, q in. rodata section
Concept: ELF (Executable and Linking Format) Executable Connection Format
The ELF format is developed and published as an application binary interface (USL) as an application binary interface (ABI).
At present, the ELF format is one of the most widely used binary industrial standards on UNIX / Linux platform.
The following image gives the general format of the ELF file from different perspectives:
LINKING Perspective Execution Perspective
============ ==============
Elf Header Elf Header
Program Header Table (Optional) Program Header Table
Section 1 segment 1
... segment 2
Section n ...
Section Header Table Section Header Table (Optional)
Figure 3-2 ELF file format Excerpted from Executable and Linkable Format (ELF)
The contents of the TEST5 are depicted in the information offset in the Program Header Table and Section Header Table of the Test5 ELF file:
ENTRY NAME start file offset actual size = next entry start offset
-------------------------------------------------- -----
Elf header 0x0 0x34 = 0x34program header 0x34 0xA0 = 0xD4
Section 1 .Interp 0xD4 0x11 = 0xE5
000 0xe5 0x3 = 0xE8
Section 2 .hash 0xe8 0x104 = 0x1ec
Section 3 .dynsym 0x1ec 0x200 = 0x3ec
Section 4 .dynstr 0x3ec 0x11a = 0x506
00 0x506 0x2 = 0x508
Section 5.SUNW_VERSION 0X508 0x20 = 0x528
Section 6 .rel.got 0x528 0x18 = 0x540
Section 7.rel.bss 0x540 0x8 = 0x548
Section 8.rel.plt 0x548 0x38 = 0x580
Section 9.plt 0x580 0x80 = 0x600
Section 10.text 0x600 0x1ec = 0x7ec
Section 11 .init 0x7ec 0xD = 0x7f9
Section 12 .fini 0x7f9 0x8 = 0x801
000 0x801 0x3 = 0x804
Section 13.RODATA 0x804 0x10 = 0x814
Section 14 .got 0x814 0x34 = 0x848
Section 15.dynamic 0x848 0xB8 = 900
Section 16.data 0x900 0x10 = 0x910
Section 17.ctors 0x910 0x8 = 0x918
Section 18.dtors 0x918 0x8 = 0x920
Section 19.eh_frame 0x920 0x4 = 0x924
Section 20.JCR 0x924 0x4 = 0x928
Section 21 .DATA.REL.LOCAL 0X928 0X4 = 0x92c
Section 22.BSS 0x92C 0x0 = 0x958
Section 23.SYMTAB 0x92C 0x540 = 0xE6C
Section 24 .strtab 0xE6C 0X20B = 1077
Section 25 .comment 0x1077 0x24d = 0x12c4
Section 26 .stab.index 0x12c4 0x24 = 0x12e8
Section 27.shstrtab 0x12e8 0xDC = 0x13c4
Section 28.indexstr 0x13c4 0x1c0 = 0x1584section header Table 0x1584 0x488 = 0x1a0c
; 29x40 = 1160 = 0x488 This is based on Elf Header information calculation
-------------------------------------------------- ----
Figure 3-3 ELF file format of TEST5
# ls -al test5
-rwxr-xr-x 1 root other 6668 2004-12-19 06:56 TEST5
You can see that the size of Test5 is 0x1A0C byte, namely 6688 bytes.
It can be seen that .bss section is used to save uninitialized global variables, so it does not occupy the ELF file space;
When the ELF file is loaded, the corresponding size memory space is mapped according to the related properties of the .BSS in Section Header Table 22, and initializes 0
The Program Header Table of the ELF file describes how to put ELF into memory:
Program HEADER 2 describes the starting address and size of the user code segment: 0x8050000 0x814 = 0x8050814
Program HEADER 3 describes the starting address and size of the user data segment: 0x8060814 0x144 = 0x8060958
Question: Why is the result of the previous PMAP is that the data segment begins with 0x8060000, while the ELF file starts starting from 0x8060814?
If you check the format specification of the ELF file, you can find the answer:
Program Header [2]:
p_vaddr:
0x8050000 p_flags: [pf_x pf_r]
p_paddr: 0 p_type: [Pt_Load]
P_filesz: 0x814 p_memsz: 0x814
P_offset: 0 p_align: 0x10000
Designated 64K page
Program Header [3]:
p_vaddr:
0x8060814 p_flags: [pf_x pf_w pf_r]
p_paddr: 0 p_type: [Pt_Load]
P_filesz: 0x118 p_memsz: 0x144
p_offset: 0x814 p_align: 0x10000
Designated 64K page
P_align specifies the mapping code segment and data segment, must be aligned in the 64K page alignment, that is, the start mapping address must end with 0000.
The start address of the code segment is just satisfying the condition. If the data segment does not consider the page alignment, you should start with the next byte of the code segment, that is, 0x8050814.
However, it is only starting from the 64K page alignment, only the 64K page closest to 0x8050814 is started with the address 0x8060000.
In fact, when mapping the ELF is mapping, the size of TEST5 is 0x1a0c, less than 1 page size, code segment and data segment are on page 1.
When the mapping occurs, first map the code segment of this page 1 to 0x8050000, attribute READ / EXEC; reproduce this page to 0x8060000, attribute READ / WRITE / EXEC.
In this way, the actual data segment start address is 0x8060000 0x814 = 0x8060814
Question: Why do you want a page to match Page Align?
First, memory mapping is the smallest unit of page, because Solaris's memory management is page-style memory management (this is currently the current most modern OS);
Second, the code segment and data segment are required for different permission requirements (the code segment requires only read only), so 2 mapping must be performed;
Finally, it is the efficiency requirements;
Although the mapping of the ELF file is completed in the Solaris kernel, you can still call MMAP (2) through the system to learn basic memory mapping common sense.
For other systems, such as Linux situations are similar.
Then why is this example request 64k page? The answer is: This is also the page of Solaris on the SPARC.
Concept: ELF file loading
It is easy to describe the internal conditions of the TEST5 code segment and data segments according to Program Header Table and Section Header Table:
Entry Name start address actual size = next entry start address
================= User text =============================
0x8050000
ELF Header 0x8050000 0x34 = 0x8050034
Program header 0x8050034 0xa0 = 0x80500d4
Section 1 .Interp 0x80500d4 0x11 = 0x80500E5
0 0x80500E5 0x3 = 0x80500E8; 3 bytes 0 fill
Section 2 .hash 0x80500E8 0x104 = 0x80501ec
Section 3 .dynsym 0x80501ec 0x200 = 0x80503ec
Section 4 .dynstr 0x80503ec 0x11a = 0x8050506
0 0x8050506 0x2 = 0x8050508
2 bytes 0 fill
Section 5.SUNW_VERSION 0x8050508 0x20 = 0x8050528
Section 6.rel.got 0x8050528 0x18 = 0x8050540
Section 7.rel.bss 0x8050540 0x8 = 0x8050548
Section 8.Rel.plt 0x8050548 0x38 = 0x8050580
Section 9.plt 0x8050580 0x80 = 0x8050600
Section 10.text 0x8050600 0x1ec = 0x80507ec
Section 11 .init 0x80507ec 0xD = 0x80507f9section 12.fini 0x80507f9 0x8 = 0x8050801
0 0x8050801 0x3 = 0x8050804
; 3 bytes 0 fill
Section 13.RODATA 0X8050804 0X10 = 0x8050814;
O, P, Q is in the code segment. Rodata Section
-------------------------------------------------- ---
Section 14.got 0x805050814 0x34 = 0x8050848
This is the first page of the code segment is also the last page.
Section 15.Dynamic 0x8050848 0xB8 = 8050900
Therefore, the content of the data segment will be appended to the last page of the code segment.
Section 16.Data 0x8050900 0x10 = 0x8050910
Section 17.ctors 0x8050910 0x8 = 0x8050918
Section 18.dttors 0x8050918 0x8 = 0x8050920
Section 19.eh_frame 0x8050920 0x4 = 0x8050924
Section 20.jcr 0x8050924 0x4 = 0x8050928
Section 21 .DATA.REL.LOCAL 0X8050928 0X4 = 0x805092c
Section 22.BSS 0x805092C 0x2c = 0x8050958
Pending Data 0x8050958 0x6a8 = 8051000
The page is 0x6A8 byte padding
============================================================================================================================================================================================================= ====
NO mapping
================= User data =============================
0x8060000
ELF Header 0x8060000 0x34 = 0x8060034
This is the last page of the data segment is also the first page.
Program header 0x8060034 0xA0 = 0x80600d4
Therefore, the content of the code segment will be added to the first page of the data segment.
Section 1 .Interp 0x80600d4 0x11 = 0x80600E50 0x80600E5 0x3 = 0x80600E8
; 3 bytes 0 fill
Section 2 .hash 0x80600e8 0x104 = 0x80601ec
Section 3 .dynsym 0x80601ec 0x200 = 0x80603ec
Section 4 .dynstr 0x80603ec 0x11a = 0x8060506
0 0x8060506 0x2 = 0x8060508
2 bytes 0 fill
Section 5.SUNW_VERSION 0x8060508 0x20 = 0x8060528
Section 6.rel.got 0x8060528 0x18 = 0x8060540
Section 7.rel.bss 0x8060540 0x8 = 0x8060548
Section 8.rel.plt 0x8060548 0x38 = 0x8060580
Section 9.plt 0x8060580 0x80 = 0x8060600
Section 10.text 0x8060600 0x1ec = 0x80607ec
Section 11 .init 0x80607ec 0xd = 0x80607f9
Section 12.fini 0x80607f9 0x8 = 0x8060801
0 0x8060801 0x3 = 0x8060804
; 3 bytes 0 fill
Section 13.RODATA 0x8060804 0x10 = 0x8060814
-------------------------------------------------- ---
Section 14.got 0x8060814 0x34 = 0x8060848
Section 15. Dynamic 0x8060848 0xB8 = 8060900
Section 16.data 0x8060900 0x10 = 0x8060910
;
I, J, K in the data segment. Data Section
Section 17.ctors 0x8060910 0x8 = 0x8060918
Section 18.dttors 0x8060918 0x8 = 0x8060920
Section 19.e_frame 0x8060920 0x4 = 0x8060924
Section 20.JCR 0x8060924 0x4 = 0x8060928
Section 21 .DATA.REL.LOCAL 0X8060928 0X4 = 0x806092c
Section 22.BSS 0x806092C 0x2c = 0x8060958
; L
, M, N in the data segment. BSS Section
0 0x8060958 0x6a8 = 8061000
At the end of the page, 0x6A8 byte 0 fill ======================================== ==============
Figure 3-4 Interior Structure of the code segment and data segment of TEST5
The following sections does not contain SHF_alloc in the section header Table, so it is not mapped to memory:
Section 23.SYMTAB
Symbol table, not mapped to memory, Strip command can remove
Section 24 .stab
String table, mainly saved and. SymTab's name string, other strings, not mapped to memory, Strip commands can be removed
Section 25 .comment
The information related to the binary program is saved, and the format content is determined in the binary itself, not mapped to memory, the strip command retains the section
Section 26 .stab.index
The information related to the binary program is saved, the format content is determined in the binary itself, not mapped to memory, the strip command can remove
Section 27 .shstrtab
String table, only saving section name, not mapped to memory, Strip command keeps this section
Section 28 .stab.indexStr
String table, not mapped to memory, Strip command can remove
With Figure 3-4, you can clearly find global variables and global constants in the accurate position of the data segment and code segment, and you can answer the previous question:
The global constant O, P, Q belongs to the code segment. Rodata section, this section has read-only attributes because it belongs to the code segment, used to save read-only data
Global variables I, J, K belong to the data segment .Data section, used to save the global variables with initial values, this section also occupies space in ELF files and memory
Global variables L, M, N belong to the code segment. BSS section, used to save uninitialized global variables, this section occupies memory space without occupying the ELF file space
Due to several different sections, the address space must not continuous.
The load of the ELF file is summarized below:
* The first code segment page contains Elf Header, Program Header Table, and other information
* The last code segment page apart a copy of the copy
* The first data segment page has a copy of the code section
* The last data segment page may contain file information that is not related to the running process
2. Verification of ELF file loading
The ELF file itself can be used to observe binary files directly. The following command can observe the related content of the .comment section:
BASH-2.05 # od -a x -c -j 0x1077 -n 0x24d TEST5
0000000 g n U C C R t 1. S / 0 a S:
0000010 F O R T E D E V E L o P e r
0000020 7 C O m p i l E R C O M M0000030 O N 7. 0 I a 3 2 - I TE E A
0000040 M 2 0 0 1/1 2/1 2/0 g n u
0000050 C C R T I. S / 0 a S: f O
0000060 R T E D E V E L o P e r 7
0000070 C O m p i l E R C O m M o n
0000080 7. 0 I a 3 2 - I TE E A M 2
0000090 0 0 1/1 2/1 2/0/0 @ (#) s
00000A0 u N o s 5. 9 g e n e r i c
00000B0_ 1 1 2 2 3 4 - 0 3 N o V e m
00000c0 B E R 2 0 0 2/0 g C C: (g
00000d0 n u) 3. 3. 2/0 a s: f o
00000E0 R t e d e v E L o P e r 7
00000F0 C O m P i l E R C O m M o n
0000100 7. 0 I A 3 2 - I T E A M 2
0000110 0 0 1/1 2/1 2/0 g c C: (
0000120 g n u) 3. 3. 2/0 a s: f
0000130 O R T E D E V E L o P e r 7
0000140 C O m P i l E R C O m M o n
0000150 7. 0 I a 3 2 - I T E a M
0000160 2 0 0 1/1 2/1 2/0 g C C:
0000170 (g n u) 3. 3. 2/0 a s:
0000180 F O R T E D E V E L o P e r
0000190 7 C O m P i l E R C O m M o
00001A0 N 7. 0 I a 3 2 - I T E A M00001B0 2 0 0 1/1 2/1 2/0 g N
00001c0 C C R t n. O / 0 A S: F O r
00001D0 T E D e v E L o P e r 7 c
00001E0 o m P i l E R C O m M o N 7
00001F0. 0 I a 3 2 - I T E A M 2 0
0000200 0 1/1 2/1 2/0 L D: s o f
0000210 T W a R E g E N e r a t i o n
0000220 U T i L i T i E S - S O L
0000230 A R I S L i N k E D i T O r
0000240 S: 5. 9 - 1. 2 7 6/0
000024D
Obviously, the contents of the .comment section are the version information of the compiler and the linker.
Observing that the ELF is loaded after memory, the process of the ELF program is required to hang in the system to read the relevant content.
With MDB, you can check the code segment and data segment values loaded in the memory, and verify it below.
Figure 3-4:
# MDB Test5
Loading Modules: [Libc.so.1]
> Main :: DIS
Main: pushl% EBP
Main 1: MOVL% ESP,% EBP
Main 3: SUBL $ 8,% ESP
Main 6: Andl $ 0xF0,% ESP
Main 9: MOVL $ 0,% EAX
Main 0xe: Subl% EAX,% ESP
Main 0x10: MOVL $ 4,0x8060948
Main 0x1a: MOVL $ 5,0x806094c
Main 0x24: MOVL $ 6,0x8060950
Main 0x2e: MOVL 0x8060908,% EAX
Main 0x33: AddL 0x8060904,% EAX
Main 0x39: AddL 0x806090c,% EAX
Main 0x3f: addl 0x8060948,% EAX
Main 0x45: AddL 0x806094c,% EaxMain 0x4b: addl 0x8060950,% EAX
Main 0x51: AddL 0x8050808,% EAX
Main 0x57: AddL 0x805080c,% EAX
Main 0x5d: addl 0x8050810,% EAX
MAIN 0x63: LEAVE
Main 0x64: RET
> main 0x2e: B
Set breakpoints
>: r
Operation
MDB: Stop at Main 0x2e
MDB: Target Stopped AT:
Main 0x2e: MOVL 0x8060908,% EAX
> 0x8050000, 0x4 / NAB
View the Elf Header head 4 bytes
0x8050000:
0x8050000: 7F
0x8050001: 45
0x8050002: 4C
0x8050003: 46
> 0x8050000, 0x4 / NAC
View Elf HEADER
Head 4 bytes
0x8050000:
0x8050000:
0x8050001: E
0x8050002: L
0x8050003: f
> 0x80500d4, 11 / c
View .Interp Section
0x80500d4: /usr/lib/ld.so.1
> 0x8050600 :: DIS
View the first process of .Text Section, is also the entry point of ELF
_Start: Pushl $ 0
_Start 2: Pushl $ 0
_START 4: MOVL% ESP,% EBP
_Start 6: Pushl% EDX
_Start 7: MOVL $ 0x8050590,% EAX
_Start 0xc: Testl% Eax,% EAX
_Start 0xe: JE 0xF <_Start 0x1D>
_Start 0x10: Pushl $ 0x8050590
_Start 0x15: Call -0x75
_Start 0x1a: Add1 $ 4,% ESP
_Start 0x1D: MOVL $ 0x8060848,% EAX
_Start 0x22: Testl% EAX,% EAX
_Start 0x24: JE 7 <_Start 0x2B>
_Start 0x26: Call -0x86
_Start 0x30: Call -0x90
_Start 0x35: MOVL 8 (% EBP),% EAX
_Start 0x38: LEAL 0X10 (% EBP,% EAX, 4),% EDX
_Start 0x3c: MOVL% EDX, 0x8060954
_Start 0x42: Andl $ 0xF0,% ESP
_Start 0x45: SUBL $ 4,% ESP
_Start 0x48: Pushl% EDX
_Start 0x49: LEAL 0xC (% EBP),% EDX
_Start 0x4c: Pushl% EDX
_Start 0x4D: Pushl% EAX
_Start 0x4e: Call 0x19e <_init>
_Start 0x53: Call -0xa3
_Start 0x58: Call 0xfb
_Start 0x5D: AddL $ 0xc,% ESP
_Start 0x60: Pushl% EAX
_Start 0x61: Call -0xa1
_Start 0x66: Pushl $ 0
_Start 0x68: MOVL $ 1,% EAX
_Start 0x6D: LCALL $ 7, $ 0
_Start 0x74: HLT
> 0x8050804, 0x4 / NAP
View. Rodata section, including real O, P, Q several global constants
_LIB_Version:
_LIB_Version:
_LIB_Version: 1
o: 7
P: 8
Q: 9
> 0x8050900, 0x4 / NAP
View. Data section filling in the code segment, this is actually invalid data
0x8050900:
0x8050900: 0
0x8050904: 1
Global variable I
0x8050908: 2
Global variable J
0x805090c: 3; global variable K
> 0x8060000, 0x4 / NAB
View the Elf Header header 4 bytes before the filled data segment, this part is actually invalid
0x8060000:
0x8060000: 7F
0x8060001: 45
0x8060002: 4C
0x8060003: 46
> 0x8060000, 0x4 / NAC
View the Elf Header header 4 bytes before the filled data segment, this part is actually invalid
0x8060000:
0x8060000:
0x8060001: E
0x8060002: L
0x8060003: f
> 0x8060804, 0x4 / NAP
View
Fill before the data segment
.RODATA Section,
This part is actually invalid
0x8060804:
0x8060804: 1
0x8060808: 7
Global constant O
0x806080c: 8
Global constant P
0x8060810: 9
Global constant Q
> 0x8060900, 0x4 / NAP
View .date section, including a few global variables of true I, J, K
0x8060900:
0x8060900: 0
TEST5`I: 1
TEST5`J: 2
TEST5`k: 3
> 0x806092c, 0xB / NAP
View .bss section, including several global variables of true L, M, N
TEST5`completed.1:
TEST5`completed.1:
TEST5`completed.1: 0
TEST5`Object.2: 0
TEST5`Object.2 4: 0
TEST5`Object.2 8: 0
TEST5`Object.2 0xc: 0
TEST5`Object.2 0x10: 0
TEST5`Object.2 0x14: 0
Test5`l: 4
TEST5`m: 5
TEST5`N: 6
TEST5`Environ: 0x8047e00
> 0x8060958, 0x6A8 / NAB
; View 0x6A8 byte data added at the end of the data segment, all 0
0x8060958:
0x8060958: 0
0x8060959: 0
0x806095a: 0
.................
.................
0x8060ffe: 0
0x8060FFF: 0
> 0x8060FFF, 2 / NAB
; Verify that the page boundary data is mapped
0x8060FFF:
0x8060FFF: 0
MDB: Failed to Read Data from target: no mapping for address
0x8061000:
> 0x8050FFF, 2 / NAB
; Verify that the page boundary data is mapped
0x8050FFF:
0x8050FFF: 0151
MDB: Failed to Read Data from target: no mapping for address
0x8051000:
3. Small knot
This experiment analyzes and verifies the global variables and global constants in the process of the process address and the relationship between the ELF file, and involves the following concepts: Process Address Space Processing Address Space
ELF EXECUTABLE AND LINKLE FORMAT Execution link format
Page align page
And, using the MDB, PMAP, Elfdump, OD tools provided by Solaris, directly observe the loading and format of the ELF file.
.
Related documents:
X86 assembly language learning incoming (1)
X86 assembly language learning notes (2)
Executable and Linkable Format (ELF)
Development Environment Installation and Settings on Solaris
Linux AT & T Asficient Language Development Guide
ELF Dynamic Resolution Symbol Process (Revised)
Concerned: 10 new changes in Solaris 10
Solaris Internals Core Kernel Architecture Jim Mauro, Richard McDougall