• Linux下Gcc 的编译过程


             在linux下开发难免会用到gcc编译。GCC(GNU Compiler Collection。GNU编译器套装),是由 GNU 开发的编程语言编译器。它是GNU编译器套装以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。

    使用GCC编译程序时,编译过程能够被细分为四个阶段:
    ◆ 预处理(Pre-Processing)
    ◆ 编译(Compiling)
    ◆ 汇编(Assembling)
    ◆ 链接(Linking)

    1、预处理 对源码文件里的文件包括(include)、预编译语句(如宏定义define等)进行分析,编译选项为gcc -E *.c

    #define DEBUG "debug"
    
    int main()
    {
      char *a = DEBUG;
      return 1;
    }
    经过上面的预处理后,能够看到DEBUG被替换成了提前定义的内容

    # 1 "hello.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "hello.c"
    
    
    
    int main()
    {
      char *a = "debug";
      return 1;
    }
    2、编译 调用cc1进行编译,使用gcc -S选项就能够生成汇编代码,这个阶段依据输入文件生成以.o为后缀的目标文件。生成的汇编代码例如以下:

            .file   "hello.c"
            .section        .rodata
    .LC0:
            .string "debug"
            .text
    .globl main
            .type   main, @function
    main:
    .LFB0:
            .cfi_startproc
            pushq   %rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            movq    %rsp, %rbp
            .cfi_def_cfa_register 6
            movq    $.LC0, -8(%rbp)
            movl    $1, %eax
            leave
            .cfi_def_cfa 7, 8
            ret
            .cfi_endproc
    .LFE0:
            .size   main, .-main
            .ident  "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)"
            .section        .note.GNU-stack,"",@progbits
    3、汇编  汇编过程是针对汇编语言的步骤,调用as进行工作。一般来讲,.S为后缀的汇编语言源码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。此过程生成ELF格式的目标代码,使用gcc -c进行汇编

    使用readelf -a hello.o能够看到具体的elf信息

    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              REL (Relocatable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x0
      Start of program headers:          0 (bytes into file)
      Start of section headers:          296 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           0 (bytes)
      Number of program headers:         0
      Size of section headers:           64 (bytes)
      Number of section headers:         13
      Section header string table index: 10
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
      [ 1] .text             PROGBITS         0000000000000000  00000040
           0000000000000013  0000000000000000  AX       0     0     4
      [ 2] .rela.text        RELA             0000000000000000  00000568
           0000000000000018  0000000000000018          11     1     8
      [ 3] .data             PROGBITS         0000000000000000  00000054
           0000000000000000  0000000000000000  WA       0     0     4
      [ 4] .bss              NOBITS           0000000000000000  00000054
           0000000000000000  0000000000000000  WA       0     0     4
      [ 5] .rodata           PROGBITS         0000000000000000  00000054
           0000000000000006  0000000000000000   A       0     0     1
      [ 6] .comment          PROGBITS         0000000000000000  0000005a
           000000000000002d  0000000000000001  MS       0     0     1
      [ 7] .note.GNU-stack   PROGBITS         0000000000000000  00000087
           0000000000000000  0000000000000000           0     0     1
      [ 8] .eh_frame         PROGBITS         0000000000000000  00000088
           0000000000000038  0000000000000000   A       0     0     8
      [ 9] .rela.eh_frame    RELA             0000000000000000  00000580
           0000000000000018  0000000000000018          11     8     8
      [10] .shstrtab         STRTAB           0000000000000000  000000c0
           0000000000000061  0000000000000000           0     0     1
      [11] .symtab           SYMTAB           0000000000000000  00000468
           00000000000000f0  0000000000000018          12     9     8
      [12] .strtab           STRTAB           0000000000000000  00000558
           000000000000000e  0000000000000000           0     0     1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings)
      I (info), L (link order), G (group), x (unknown)
      O (extra OS processing required) o (OS specific), p (processor specific)
    
    There are no section groups in this file.
    
    There are no program headers in this file.
    
    Relocation section '.rela.text' at offset 0x568 contains 1 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000008  00050000000b R_X86_64_32S      0000000000000000 .rodata + 0
    
    Relocation section '.rela.eh_frame' at offset 0x580 contains 1 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
    
    There are no unwind sections in this file.
    
    Symbol table '.symtab' contains 10 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
         2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
         3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
         4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
         5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
         6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
         7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
         8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
         9: 0000000000000000    19 FUNC    GLOBAL DEFAULT    1 main
    


    4、链接 链接过程。生成可运行代码。链接分为两种,一种是静态链接,第二种是动态链接。

    使用静态链接的优点是,依赖的动态链接库较少,对动态链接库的版本号不会非常敏感,具有较好的兼容性。缺点是生成的程序比較大。使用动态链接的优点是,生成的程序比較小,占用较少的内存。

    gcc hello.o -o hello 就能够完毕最后的链接操作并生成可运行文件,至于怎样生成动态库和静态库,以及怎样链接动态库和静态库,以后会再作介绍。


  • 相关阅读:
    解决execjs 调用js 问题
    处理 get请求套字典问题
    js2py js逆向
    前端页面自适应
    newspaper抓新闻
    easygui
    pycharm 安装插件
    scrapy_代理使用
    SQLAlchemy 介绍,建表,及表的操作 (增 删 改 查)
    数据分析之pandas模块下
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6928091.html
Copyright © 2020-2023  润新知