We know that C/C ++ code compilation requires four steps: preprocessing, compilation, assembly, and connection.
Generally, when compiling a program, we complete these four steps through one-step operations of the compiler. Instead, we do not pay much attention to the specific compilation process.
Let's take a closer look at what happened in every compilation step.
Write a simple helloworld. c
Helloworld. c ------------------------
# Include <stdio. h>
Int main (INT argc, char * argv [])
{
Printf ("Hello World/N ");
Return 0;
}
-----------------------------------------
If GCC is used for compilation, the compilation and execution results are generally as simple as this.
$ GCC helloworld. C-o helloworld
$./Helloworld
Hello World
Now we can add the-V parameter after GCC during compilation to see the detailed compilation process:
$ Gcc-V helloworld. C-o helloworld
----------------------------------------------------
Using built-in specs.
Target: i486-linux-gnu
Configured :.. /src/configure-V -- With-pkgversion = 'ubuntu 4.4.3-4ubuntu5' -- With-bugurl = file: // usr/share/doc/gcc-4.4/readme. bugs -- enable-languages ages = C, C ++, Fortran, objc, OBJ-C ++ -- prefix =/usr -- enable-shared -- enable-multiarch -- enable-linker-Build-id -- With-system-zlib -- libexecdir =/usr/lib -- without-included-gettext -- enable-threads = POSIX -- With-gxx-include-Dir =/usr/include/C ++/4.4 -- Program-suffix =-4.4 -- enable- NLS -- enable-clocale = GNU -- enable-libstdcxx-Debug -- enable-plugin -- enable-objc-GC -- enable-targets = all -- disable-werror -- With-arch-32 = iworkflow -- With-tune = generic -- enable-checking = release -- Build = i486-linux-gnu -- Host = i486-linux-gnu -- target = i486-linux-gnu
Thread model: POSIX
GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
Collect_gcc_options = '-v''-O '''helloworld'-mtune = generic ''-March = iyun'
/Usr/lib/GCC/i486-linux-gnu/4.4.3/PC3-quiet-V helloworld. c-d_fortify_source = 2-quiet-dumpbase helloworld. c-mtune = generic-March = isung-auxbase helloworld-version-fstack-protector-o/tmp/ccte4jk2. s
Gnu c (Ubuntu 4.4.3-4ubuntu5) version 4.4.3 (i486-linux-gnu)
Compiled by gnu c version 4.4.3, GMP version 4.3.2, mpfr version 2.4.2-P1.
GGC Heuristics: -- Param GGC-Min-expand = 97 -- Param GGC-Min-heapsize = 126998
Ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
Ignoring nonexistent directory "/usr/lib/GCC/i486-linux-gnu/4.4.3/.../i486-linux-gnu/include"
Ignoring nonexistent directory "/usr/include/i486-linux-gnu"
# Include "..." search starts here:
# Include <...> search starts here:
/Usr/local/include
/Usr/lib/GCC/i486-linux-gnu/4.4.3/include
/Usr/lib/GCC/i486-linux-gnu/4.4.3/include-fixed
/Usr/include
End of search list.
Gnu c (Ubuntu 4.4.3-4ubuntu5) version 4.4.3 (i486-linux-gnu)
Compiled by gnu c version 4.4.3, GMP version 4.3.2, mpfr version 2.4.2-P1.
GGC Heuristics: -- Param GGC-Min-expand = 97 -- Param GGC-Min-heapsize = 126998
Compiler executable checksum: 5998ce5f1765e99eea5269f4c1e38d44
Collect_gcc_options = '-v''-O '''helloworld'-mtune = generic ''-March = iyun'
As-v-QY-O/tmp/ccc02j4q. O/tmp/ccte4jk2. s
GNU Debugger er version 2.20.1 (i486-linux-gnu) using BFD version (GNU binutils for Ubuntu) 2.20.1-system.20100303
Compiler_path =/usr/lib/GCC/i486-linux-gnu/4.4.3/:/usr/lib/GCC/i486-linux-gnu/4.4.3/:/usr/lib/GCC/i486-linux-gnu /: /usr/lib/GCC/i486-linux-gnu/4.4.3/:/usr/lib/GCC/i486-linux-gnu/:/usr/lib/GCC/i486-linux-gnu/4.4.3 /: /usr/lib/GCC/i486-linux-gnu/
LIBRARY_PATH =/usr/lib/GCC/i486-linux-gnu/4.4.3/:/usr/lib/GCC/i486-linux-gnu/4.4.3/:/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /.. /lib/:/lib /.. /lib/:/usr/lib /.. /lib/:/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /:/lib/:/usr/lib/i486-linux-gnu/
Collect_gcc_options = '-v''-O '''helloworld'-mtune = generic ''-March = iyun'
/Usr/lib/GCC/i486-linux-gnu/4.4.3/collect2 -- Build-id -- Eh-frame-HDR-M elf_i386 -- hash-style = both-dynamic-linker/lib/ld-linux.so.2- O helloworld-Z relro/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /.. /lib/crt1.o/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /.. /lib/crti. o/usr/lib/GCC/i486-linux-gnu/4.4.3/crtbegin. o-L/usr/lib/GCC/i486-linux-gnu/4.4.3-L/usr/lib/GCC/i486-linux-gnu/4.4.3-L/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /.. /lib-L/lib /.. /lib-L/usr/lib /.. /lib-L/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. -L/usr/lib/i486-linux-gnu/tmp/ccc02j4q. o-lgcc -- as-needed-lgcc_s -- no-as-needed-LC-lgcc -- as-needed-lgcc_s -- no-as-needed/usr/lib/GCC/i486-linux-gnu/ 4.4.3/crtend. o/usr/lib/GCC/i486-linux-gnu/4.4.3 /.. /.. /.. /.. /lib/crtn. O
-----------------------------------------------------
The actual steps in the output are as follows:
1. /usr/lib/GCC/i486-linux-gnu/4.4.3/PC3-quiet-V helloworld. c-d_fortify_source = 2-quiet-dumpbase helloworld. c-mtune = generic-March = isung-auxbase helloworld-version-fstack-protector-o/tmp/ccte4jk2. s
2. As-v-QY-O/tmp/ccc02j4q. O/tmp/ccte4jk2. s
3./usr/lib/GCC/i486-linux-gnu/4.4.3/collect2 .............
Step 1 is to pre-process and compile data with the help of the software package.
Step 1 is to use as for compilation
Step 2 is to use collect2 for connection operations
In the first step, you can perform two operations, preprocessing and connection, and the actual operations can be divided into two separate steps.
CPP-O helloworld. I helloworld. c
PC3 HW. I-o/tmp/ccte4jk2. s
The result of CPP is to pre-process the code, and # macros such as define are pre-processed here.
The pre-processing result contains the # include code, which leads to a very long helloworld. I. You can open it.
A piece of code like this:
----------------------------------------------------------------------------------
This is the last part of the intercepted code:
Extern char * ctermid (char * _ s) _ attribute _ (_ nothrow __));
#886 "/usr/include/stdio. H" 3 4
Extern void flockfile (File * _ stream) _ attribute _ (_ nothrow __));
Extern int ftrylockfile (File * _ stream) _ attribute _ (_ nothrow __));
Extern void funlockfile (File * _ stream) _ attribute _ (_ nothrow __));
#916 "/usr/include/stdio. H" 3 4
#2 "helloworld. c" 2
Int main (INT argc, char * argv [])
{
Printf ("Hello World/N ");
Return 0;
}
----------------------------------------------------------------------------------
The ccte4jk2. S is the generated assembly language,
Inline inline functions are processed during compilation.
The compilation result of this example is as follows:
---------------------------------------------------------
. File "helloworld. c"
. Section. rodata
. Lc0:
. String "Hello World"
. Text
. Globl main
. Type main, @ Function
Main:
Pushl % EBP
Movl % ESP, % EBP
Andl $-16, % ESP
Subl $16, % ESP
Movl $. lc0, (% ESP)
Call puts
Movl $0, % eax
Leave
RET
. Size main,.-Main
. Ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
. Section. Note. GNU-stack, "", @ progbits
~
------------------------------------------------------------------
The code after compilation and connection in steps 2 and 3 won't be pulled.
If you have time to explain the technical details, everything is transparent in Linux. You can always figure out what you want to understand.
Lixinso
Lixinso [at] Gmail [Dot] com