• Linux 程式減肥(strip & objcopy)(转载)


      转自:http://calamaryshop.blogspot.com/2011/11/linux-strip-objcopy.html

    對於設計嵌入式Linux系統的研發人員來說,記憶體的空間是非常斤斤計較的。
    嵌入式Linux系統所用的記憶體不是軟碟、硬碟、ZIP 盤、CD-ROM、DVD這些大容量記憶裝置,而是使用的是Rom,Flash, CompactFlash, SD...等體積極小,與主板上的BIOS大小相近,存儲容量很小的記憶體。所以怎樣盡可能的節省空間就顯的很重要。嵌入式系統的記憶體中放置的是 Linux核心,文件系統,軟體,以及自己開發的程式。
    以一個簡單的C程式來做例子,讓它減肥。
    HelloWorld.c:
    #include
    int main()
    {
            printf("Hello, World1. ");
            printf("Hello, World2. ");
            printf("Hello, World3. ");
            return 0;
    }
    先用正常的編譯方法編譯,看看生成的程式的大小是多少
    ~#gcc –o HelloWorld HelloWorld.c
    ~# ls HelloWorld -al
    -rwxr-xr-x 1 root root 7144 2011-11-25 11:23 HelloWorld
    從結果可以看到正常編譯後的程式大小是 7144Byte

    1. 用 strip 命令
    二進位程式中包含了大量的符號資訊(symbol table),有一部分是用來gdb除錯提供必要幫助的。可以通過 readelf –S 查看到這些符號資訊。
    ~# readelf -S HelloWorld
    There are 30 section headers, starting at offset 0x1128:
    Section Headers:
      [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
      [ 0] NULL 00000000 000000 000000 00 0 0 0
      [ 1] .interp PROGBITS 08048134 000134 000013 00 A 0 0 1
      [ 2] .note.ABI-tag NOTE 08048148 000148 000020 00 A 0 0 4
      [ 3] .note.gnu.build-i NOTE 08048168 000168 000024 00 A 0 0 4
      [ 4] .hash HASH 0804818c 00018c 000028 04 A 6 0 4
      [ 5] .gnu.hash GNU_HASH 080481b4 0001b4 000020 04 A 6 0 4
      [ 6] .dynsym DYNSYM 080481d4 0001d4 000050 10 A 7 1 4
      [ 7] .dynstr STRTAB 08048224 000224 00004a 00 A 0 0 1
      [ 8] .gnu.version VERSYM 0804826e 00026e 00000a 02 A 6 0 2
      [ 9] .gnu.version_r VERNEED 08048278 000278 000020 00 A 7 1 4
      [10] .rel.dyn REL 08048298 000298 000008 08 A 6 0 4
      [11] .rel.plt REL 080482a0 0002a0 000018 08 A 6 13 4
      [12] .init PROGBITS 080482b8 0002b8 000030 00 AX 0 0 4
      [13] .plt PROGBITS 080482e8 0002e8 000040 04 AX 0 0 4
      [14] .text PROGBITS 08048330 000330 00018c 00 AX 0 0 16
      [15] .fini PROGBITS 080484bc 0004bc 00001c 00 AX 0 0 4
      [16] .rodata PROGBITS 080484d8 0004d8 000035 00 A 0 0 4
      [17] .eh_frame PROGBITS 08048510 000510 000004 00 A 0 0 4
      [18] .ctors PROGBITS 08049f0c 000f0c 000008 00 WA 0 0 4
      [19] .dtors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4
      [20] .jcr PROGBITS 08049f1c 000f1c 000004 00 WA 0 0 4
      [21] .dynamic DYNAMIC 08049f20 000f20 0000d0 08 WA 7 0 4
      [22] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4
      [23] .got.plt PROGBITS 08049ff4 000ff4 000018 04 WA 0 0 4
      [24] .data PROGBITS 0804a00c 00100c 000008 00 WA 0 0 4
      [25] .bss NOBITS 0804a014 001014 000008 00 WA 0 0 4
      [26] .comment PROGBITS 00000000 001014 000023 01 MS 0 0 1
      [27] .shstrtab STRTAB 00000000 001037 0000ee 00 0 0 1
      [28] .symtab SYMTAB 00000000 0015d8 000410 10 29 45 4
      [29] .strtab STRTAB 00000000 0019e8 000200 00 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)
    以減小程式的 size。這裏我們用 strip 命令拿掉它們。
    ~# cp HelloWorld HelloWorld_org
    ~# strip HelloWorld
    ~# ll
    total 28
    drwxr-xr-x 2 root root 4096 2011-11-25 12:01 ./
    drwxr-xr-x 19 root root 4096 2011-11-25 11:20 ../
    -rwxr-xr-x 1 root root 5496 2011-11-25 12:01 HelloWorld*
    -rw-r--r-- 1 root root 156 2011-11-25 11:56 HelloWorld.c
    -rwxr-xr-x 1 root root 7144 2011-11-25 12:01 HelloWorld_org*
    程式立刻變成 5496Byte了,效果不錯。

    2. 用 objcopy 命令
    還有什麼是可以拿掉的呢?上一步的 strip 命令只能拿掉一般 symbol table,有些資訊還是沒拿掉,而這些資訊對於程式的最終執行是沒有什麼影響的。如:.comment; .note.ABI-tag; .gnu.version 就是完全可以去掉的。所以說程式還有簡化的餘地,我們可以使用 objcopy 命令把它們抽取掉。
    ~# objcopy -R .comment -R .note.ABI-tag -R .gnu.version HelloWorld HelloWorld_obj
    ~# ll
    total 52
    drwxr-xr-x 2 root root 4096 2011-11-25 13:17 ./
    drwxr-xr-x 19 root root 4096 2011-11-25 11:20 ../
    -rwxr-xr-x 1 root root 5496 2011-11-25 13:15 HelloWorld*
    -rw-r--r-- 1 root root 156 2011-11-25 11:56 HelloWorld.c
    -rwxr-xr-x 1 root root 5304 2011-11-25 13:17 HelloWorld_obj*
    -rwxr-xr-x 1 root root 7144 2011-11-25 12:01 HelloWorld_org*
    -rwxr-xr-x 1 root root 5496 2011-11-25 12:02 HelloWorld_strip*
    查看一下 HelloWorld_obj為5304Bytes,又少了一點。

    比較一下原始bin,strip後的bin,objcopy後的bin:
    -rwxr-xr-x 1 root root 7144 2011-11-25 12:01 HelloWorld_org*
    -rwxr-xr-x 1 root root 5496 2011-11-25 12:02 HelloWorld_strip*
    -rwxr-xr-x 1 root root 5304 2011-11-25 13:17 HelloWorld_obj*
    程式容量的減小對嵌入式 Linux系統的設計很有意義,節省了大量空間,使得我們可以利用這部分空間來完善我們的系統,如可再加大Linux核心等等。
  • 相关阅读:
    应用程序跳转
    百度地图集成
    导航 -MapKit
    导航
    定位
    ApexSql Log使用体会
    Oracle学习 第16天
    上来冒个泡吧
    Oracle学习 实战心得总结
    好久没上来冒个泡了,整整一个半月
  • 原文地址:https://www.cnblogs.com/lance-ehf/p/5660136.html
Copyright © 2020-2023  润新知