• 【转】GCC 工具链使用


    转自:https://blog.csdn.net/icarman/article/details/108647809

    GCC 工具链使用

    GCC 有很多编译,链接工具,同时还有一些查看工具,方便用户查看生成的object文件,ELF文件信息等。这里简单介绍常用的GCC工具的使用方法。

    1. nm:list symbols from object files

    可以从.a, .o, .out(elf)文件中读出符号表(函数名,变量名),还可以发现函数在那个文件/库中定义和被调用,如:

    $nm -A lib/MSD7853/release/*.a | grep CSUDIPlusOSTimerStop

    获得信息如下:
    libkernel.a:event.o: U CSUDIPlusOSTimerStop
    libkernel.a:dsm_sg.o: U CSUDIPlusOSTimerStop
    libos_udi2_to_udi1.a:udi1_os.o: U CSUDIPlusOSTimerStop
    libUDIPlus.a:udiplus_ostimer.o:00000308 T CSUDIPlusOSTimerStop
    U: 表示undifined,即该库里面调用该函数, 在其他库中定义。
    T:表示函数在库中是全局函数的定义("t"表示局部函数定义)。
    W:表示函数在当前库中定义,被其它库中的函数覆盖

    所以,从这个例子里面可以看到CSUDIPlusOSTimerStop是在库libUDIPlus.a的udiplus_ostimer.c文件中实现。

    nm还有作用就是直接通过可执行文件生成相应的map文件。当然,这个前提是改可执行文件没有被strip命令裁剪过。命令如下:
    nm integration/product/a.out > flash.map

    可以输出执行文件函数地址和函数名称的对照表
    nm -n --defined-only -C a.out > a.sym

    2. readelf: Display information about ELF files

    $readelf -s: 显示ELF的符号表信息(变量和函数)
    列出的项目中有两项比较重要的参考信息
    Type: 
    FILE- ELF中使用到的文件
    FUNC- 定义的函数
    OBJECT- 变量,数组或指针等
    NOTYPE- 未定义的应用,通常是调用到的外部函数
    SECTION-
    Bind:
    GLOBAL-全局的函数或变量
    LOCAL-局部函数或变量

    $readelf -s test.o | grep FILE: 有可能test.o由多个.o直接merge而成,该指令可以找出这个test.o是有那些.c文件合成的
    $readelf -s test.o | grep FUNC: 列出test.c中的函数
    $readelf -s test.o | grep NOTYPE: 列出test.c中调用的其他函数

    如何判断执行文件或者目标文件(.o文件)带有debug信息(-g 编译的)?
    $readelf -S 查看section header信息,即段header信息
    $readelf -S libxxx.so |grep debug
    $readelf -S xx.o |grep debug
    如果输出有debug字样的,就是带有debug信息的(-g 编译的),如:
    [12] .debug_info MIPS_DWARF 00000000 009b90 008200 00 0 0 1
    [13] .rel.debug_info REL 00000000 0220f4 004be8 08 I 28 12 4
    [14] .debug_abbrev MIPS_DWARF 00000000 011d90 00042a 00 0 0 1
    [15] .debug_loc MIPS_DWARF 00000000 0121ba 00574e 00 0 0 1
    [16] .rel.debug_loc REL 00000000 026cdc 000040 08 I 28 15 4
    [17] .debug_aranges MIPS_DWARF 00000000 017908 000020 00 0 0 1
    [18] .rel.debug_arange REL 00000000 026d1c 000010 08 I 28 17 4
    [19] .debug_ranges MIPS_DWARF 00000000 017928 000120 00 0 0 1
    [20] .debug_line MIPS_DWARF 00000000 017a48 001513 00 0 0 1
    [21] .rel.debug_line REL 00000000 026d2c 000008 08 I 28 20 4
    [22] .debug_str MIPS_DWARF 00000000 018f5b 0022b9 01 MS 0 0 1
    [25] .debug_frame MIPS_DWARF 00000000 01b26c 000698 00 0 0 4
    [26] .rel.debug_frame REL 00000000 026d34 0002d0 08 I 28 25 4

    readelf -e
    显示 elf header信息, 和 objdump -h 类似
    $readelf -e a.out
    ELF Header:
    Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
    Class: ELF32
    Data: 2’s complement, little endian
    Version: 1 (current)
    OS/ABI: UNIX - System V
    ABI Version: 0
    Type: EXEC (Executable file)
    Machine: MIPS R3000
    Version: 0x1
    Entry point address: 0x80000200
    Start of program headers: 52 (bytes into file)
    Start of section headers: 16363192 (bytes into file)
    Flags: 0x70001001, noreorder, o32, mips32r2
    Size of this header: 52 (bytes)
    Size of program headers: 32 (bytes)
    Number of program headers: 2
    Size of section headers: 40 (bytes)
    Number of section headers: 29
    Section header string table index: 26

    Section Headers:
    [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
    [ 0] NULL 00000000 000000 000000 00 0 0 0
    [ 1] .jump_boot PROGBITS 80000200 000080 000010 00 AX 0 0 16
    [ 2] .boot PROGBITS 800a0a00 000a00 003df8 00 AX 0 0 4096
    [ 3] .standby PROGBITS 800a47f8 0047f8 00453c 00 WAX 0 0 4096
    [ 4] .text PROGBITS 800a8d34 008d34 3e22dc 00 AX 0 0 16
    [ 5] .rodata PROGBITS 8048c010 3ec010 12c460 00 A 0 0 16
    [ 6] .data PROGBITS 805b8470 518470 02dd7c 00 WA 0 0 8
    [ 7] .structure.init PROGBITS 805e61ec 5461ec 000384 00 A 0 0 4
    [ 8] .sdata PROGBITS 805e6570 546570 0022a8 00 WAp 0 0 8
    [ 9] .sbss NOBITS 805e8818 548818 0014f8 00 WAp 0 0 8
    [10] .bss NOBITS 805e9d10 548818 2a5110 00 WA 0 0 32
    [11] .reginfo MIPS_REGINFO 00000000 548818 000018 18 0 0 4
    [12] .mdebug MIPS_DEBUG 00000000 548830 0818a4 01 0 0 4
    [13] .pdr PROGBITS 00000000 5ca0d4 066260 00 0 0 4
    [14] .mdebug.abi32 PROGBITS 00000000 630334 000000 00 0 0 1
    [15] .debug_abbrev MIPS_DWARF 00000000 630334 06d77b 00 0 0 1
    [16] .debug_info MIPS_DWARF 00000000 69daaf 63d645 00 0 0 1
    [17] .debug_line MIPS_DWARF 00000000 cdb0f4 0f9b51 00 0 0 1
    [18] .debug_frame MIPS_DWARF 00000000 dd4c48 06e1d4 00 0 0 4
    [19] .debug_pubnames MIPS_DWARF 00000000 e42e1c 055890 00 0 0 1
    [20] .debug_aranges MIPS_DWARF 00000000 e986ac 023660 00 0 0 1

    3. ldd: print shared library dependencies

    打印可执行档依赖的共享库文件, 但是ldd本身不是一个程序,而仅是一个shell脚本

    4. objdump: 产生反汇编文件

    $objdump -D a.out > a.dis

    $objdump -h, 获取elf各个段信息
    $ objdump -h a.out
    a.out: file format elf32-tradlittlemips

    Sections:
    Idx Name Size VMA LMA File off Algn
    0 .jump_boot 00000010 80000200 80000200 00000080 24
    CONTENTS, ALLOC, LOAD, READONLY, CODE
    1 .boot 00003df8 800a0a00 800a0a00 00000a00 2
    12
    CONTENTS, ALLOC, LOAD, READONLY, CODE
    2 .standby 0000453c 800a47f8 800a47f8 000047f8 212
    CONTENTS, ALLOC, LOAD, CODE
    3 .text 003e22dc 800a8d34 800a8d34 00008d34 2
    4
    CONTENTS, ALLOC, LOAD, READONLY, CODE
    4 .rodata 0012c460 8048c010 8048c010 003ec010 24
    CONTENTS, ALLOC, LOAD, READONLY, DATA
    5 .data 0002dd7c 805b8470 805b8470 00518470 2
    3
    CONTENTS, ALLOC, LOAD, DATA
    6 .structure.init 00000384 805e61ec 805e61ec 005461ec 22
    CONTENTS, ALLOC, LOAD, READONLY, DATA
    7 .sdata 000022a8 805e6570 805e6570 00546570 2
    3
    CONTENTS, ALLOC, LOAD, DATA
    8 .sbss 000014f8 805e8818 805e8818 00548818 23
    ALLOC
    9 .bss 002a5110 805e9d10 805e9d10 00548818 2
    5
    ALLOC
    10 .reginfo 00000018 00000000 00000000 00548818 22
    CONTENTS, READONLY, LINK_ONCE_SAME_SIZE
    11 .mdebug 000818a4 00000000 00000000 00548830 2
    2
    CONTENTS, READONLY, DEBUGGING
    12 .pdr 00066260 00000000 00000000 005ca0d4 22
    CONTENTS, READONLY
    13 .mdebug.abi32 00000000 00000000 00000000 00630334 2
    0
    CONTENTS, READONLY
    14 .debug_abbrev 0006d77b 00000000 00000000 00630334 2**0

    5. objcopy: 主要用于抽取执行文件.out文件中的各类段。

    6. strip: 丢弃目标文件中的全部或者特定符号

    Remove all debugging symbols & sections of object files,删除object中的全部debug信息
    这样生成的object size较小,并且可以防止反汇编,安全性更高
    $strip -g -S -d ${OBJS}

    7. ar: 把.o 打包生成.a库文件或者把.a 拆成.o文件

    $ar -r a.o b.o c.o test.a

    8. gprof:可以显示程序运行的“flat profile”,包括每个函数的调用次数,每个函数消耗的处理器时间。

    也可以显示“调用图”,包括函数的调用关系,每个	函数调用花费了多少时间。还可以显示“注释的源代码”,
    是程序源代码的一个复本,标记有程序中每行代码的执行次数。命令行参数中加入“-pg”选项
     
    • 1
    • 2

    9. gcov: 一个保险测试工具。当构建一个程序时,gcov会监视一个程序的执行,并且会标识出执行了哪一行源码,哪一行没有执行

    10. size: 列出目标文件每一段的大小以及总体的大小

    11. gcc -M test.c

    不编译test.c, 仅仅列出test.c所依赖的.h头文件
    $gcc -MM test.c
    仅仅列出test.c所依赖的.h头文件,不包括系统头文件
    查看gcc所定义的所有预定义宏
    $cpp -dM /dev/null

    14. gcc -E -P test.c > test_macro.txt

    gcc对test.c 进行预处理即可看到宏展开后的代码,输出到test_macro.txt,方便理解
    但注意会把所有宏都展开,包括系统头文件里面的宏,要自己查找想要的宏

     
  • 相关阅读:
    2014年之新年新愿
    C#解析Xml的Dom和Sax方式性能分析
    WCF协议与绑定
    使用SqlServer数据批量插入
    跨站脚本攻击XSS
    疯狂的JSONP
    SQLiteOpenHelper
    Android常用的UI布局
    Android用户界面
    ListView
  • 原文地址:https://www.cnblogs.com/langqi250/p/13901691.html
Copyright © 2020-2023  润新知