RISC-V:未链接的目标文件中的代码大小

RISC-V: Size of code size in an object file which is not linked

我有一个 .i 文件,我已经编译但没有使用 SiFive risc-v 编译器链接如下:

../riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc clock.i

然而,当我对编译目标文件执行 readelf -S 时,.text 部分是 0 字节:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000000 00  AX  0   0  2
  [ 2] .data             PROGBITS        00000000 000034 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 000034 000000 00  WA  0   0  1
  [ 4] .text.getTime     PROGBITS        00000000 000034 00003a 00  AX  0   0  2
  [ 5] .rela.text.ge     RELA            00000000 000484 0000c0 0c   I 18   4  4
  [ 6] .text.timeGap     PROGBITS        00000000 00006e 00002e 00  AX  0   0  2
  [ 7] .rela.text.ti     RELA            00000000 000544 000024 0c   I 18   6  4
  [ 8] .text.applyTO     PROGBITS        00000000 00009c 000038 00  AX  0   0  2
  [ 9] .rela.text.ap     RELA            00000000 000568 0000c0 0c   I 18   8  4
  [10] .text.clearTO     PROGBITS        00000000 0000d4 000038 00  AX  0   0  2
  [11] .rela.text.cl     RELA            00000000 000628 0000c0 0c   I 18  10  4
  [12] .rodata.getTi     PROGBITS        00000000 00010c 00000c 01 AMS  0   0  4
  [13] .rodata.__func__. PROGBITS        00000000 000118 00000c 00   A  0   0  4
  [14] .rodata.__func__. PROGBITS        00000000 000124 00000c 00   A  0   0  4
  [15] .rodata.__func__. PROGBITS        00000000 000130 00000c 00   A  0   0  4
  [16] .comment          PROGBITS        00000000 00013c 000029 01  MS  0   0  1
  [17] .riscv.attributes LOPROC+0x3      00000000 000165 00001f 00      0   0  1
  [18] .symtab           SYMTAB          00000000 000184 000240 10     19  31  4
  [19] .strtab           STRTAB          00000000 0003c4 0000be 00      0   0  1
  [20] .shstrtab         STRTAB          00000000 0006e8 000100 00      0   0  1

如果我对编译后的目标文件进行大小调整,我得到的大小为 264 字节:

   text    data     bss     dec     hex filename
    264       0       0     264     108 clock.o

如果我执行 nm --print-size 我会得到以下信息:

         U __assert_func
00000000 0000000c r __func__.3507
00000000 0000000c r __func__.3518
00000000 0000000c r __func__.3522
0000000c t .L11
00000036 t .L12
00000034 t .L14
00000036 t .L18
00000034 t .L2
00000034 t .L20
00000032 t .L3
0000001e t .L8
00000000 r .LANCHOR0
00000000 r .LANCHOR1
00000000 r .LANCHOR2
00000000 r .LC0
00000004 r .LC1
00000000 00000038 T applyTO
00000000 00000038 T clearTO
00000000 0000003a T getTime
00000000 0000002e T timeGap

对我来说大小是 0x38 + 0x38 + 0x3A + 0x2E = 0xD8 (216) 字节。

如何计算编译目标文件的大小?

你的目标文件是用 -ffunction-sections 编译的,这是一个特殊的标志,它将每个函数分配到它的专用部分。您可以在 readelf 的输出中看到每个函数的单独 .texts

[ 4] .text.getTime     PROGBITS        00000000 000034 00003a 00  AX  0   0  2
...
[ 6] .text.timeGap     PROGBITS        00000000 00006e 00002e 00  AX  0   0  2
...

要获得完整的代码大小,您需要对以“.text”开头的每个部分的大小求和。一个 Perl 单行代码:

$ readelf ... | perl -ne 'if(/ \.text/) { s/^.*\] *//; $sz += hex((split(/ +/))[4]); print "$sz\n"; }'                 0
58
104
160
216  <-- Full size