问题描述
我想知道如何获取此 berkeley 格式的输出:
$ size --format=berkeley /bin/ls
text data bss dec hex filename
124042 4728 4832 133602 209e2 /bin/ls
从此 sysv 格式输出:
$ size --format=sysv /bin/ls
/bin/ls :
section size addr
.interp 28 568
.note.ABI-tag 32 596
.note.gnu.build-id 36 628
.gnu.hash 236 664
.dynsym 3576 904
.dynstr 1666 4480
.gnu.version 298 6146
.gnu.version_r 112 6448
.rela.dyn 4944 6560
.rela.plt 2664 11504
.init 23 14168
.plt 1792 14192
.plt.got 24 15984
.text 74969 16016
.fini 9 90988
.rodata 19997 91008
.eh_frame_hdr 2180 111008
.eh_frame 11456 113192
.init_array 8 2224112
.fini_array 8 2224120
.data.rel.ro 2616 2224128
.dynamic 512 2226744
.got 968 2227256
.data 616 2228224
.bss 4832 2228864
.gnu_debuglink 52 0
Total 133654
换句话说,“ sysv”格式的哪一部分是小部分(text
,data
和bss
),是“伯克利”格式?
我试图通过观察总和来猜测。
换句话说,我想知道:
-
? + ? + ? = text
-
? + ? + ? = data
-
? + ? + ? = bss
相关:
解决方法
这是答案:
TLDR;
.interp + .note.ABI-tag + .note.gnu.build-id + .gnu.hash + .dynsym + .dynstr
+ .gnu.version + .gnu.version_r + .rela.dyn + .rela.plt + .init + .plt
+ .plt.got + .text + .fini + .rodata + .eh_frame_hdr + .eh_frame
= text
.init_array + .fini_array + .data.rel.ro + .dynamic + .got + .data
= data
.bss = bss
另请查看图像的末尾带有黄色,蓝色和红色框,以获取快速的视觉摘要。
详细信息:
首先,让我们用size -x --format=berkeley /bin/ls
或size -x /bin/ls
以十六进制打印berkeley大小信息(同样,因为berkeley是默认格式):
$ size -x /bin/ls
text data bss dec hex filename
0x1e48a 0x1278 0x12e0 133602 209e2 /bin/ls
这是用size -x --format=sysv /bin/ls
获得的十六进制sysv大小输出:
$ size -x --format=sysv /bin/ls
/bin/ls :
section size addr
.interp 0x1c 0x238
.note.ABI-tag 0x20 0x254
.note.gnu.build-id 0x24 0x274
.gnu.hash 0xec 0x298
.dynsym 0xdf8 0x388
.dynstr 0x682 0x1180
.gnu.version 0x12a 0x1802
.gnu.version_r 0x70 0x1930
.rela.dyn 0x1350 0x19a0
.rela.plt 0xa68 0x2cf0
.init 0x17 0x3758
.plt 0x700 0x3770
.plt.got 0x18 0x3e70
.text 0x124d9 0x3e90
.fini 0x9 0x1636c
.rodata 0x4e1d 0x16380
.eh_frame_hdr 0x884 0x1b1a0
.eh_frame 0x2cc0 0x1ba28
.init_array 0x8 0x21eff0
.fini_array 0x8 0x21eff8
.data.rel.ro 0xa38 0x21f000
.dynamic 0x200 0x21fa38
.got 0x3c8 0x21fc38
.data 0x268 0x220000
.bss 0x12e0 0x220280
.gnu_debuglink 0x34 0x0
Total 0x20a16
接下来,如果您运行objdump -h /bin/ls
,则会得到以下内容,其中显示了/bin/ls
目标文件或可执行。这些输出部分与size -x --format=sysv /bin/ls
命令的输出匹配,但是具有更详细的信息,例如VMA(虚拟内存地址)和LMA(加载内存地址),以及其他内容:
$ objdump -h /bin/ls
/bin/ls: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000000238 0000000000000238 00000238 2**0
CONTENTS,ALLOC,LOAD,READONLY,DATA
1 .note.ABI-tag 00000020 0000000000000254 0000000000000254 00000254 2**2
CONTENTS,DATA
2 .note.gnu.build-id 00000024 0000000000000274 0000000000000274 00000274 2**2
CONTENTS,DATA
3 .gnu.hash 000000ec 0000000000000298 0000000000000298 00000298 2**3
CONTENTS,DATA
4 .dynsym 00000df8 0000000000000388 0000000000000388 00000388 2**3
CONTENTS,DATA
5 .dynstr 00000682 0000000000001180 0000000000001180 00001180 2**0
CONTENTS,DATA
6 .gnu.version 0000012a 0000000000001802 0000000000001802 00001802 2**1
CONTENTS,DATA
7 .gnu.version_r 00000070 0000000000001930 0000000000001930 00001930 2**3
CONTENTS,DATA
8 .rela.dyn 00001350 00000000000019a0 00000000000019a0 000019a0 2**3
CONTENTS,DATA
9 .rela.plt 00000a68 0000000000002cf0 0000000000002cf0 00002cf0 2**3
CONTENTS,DATA
10 .init 00000017 0000000000003758 0000000000003758 00003758 2**2
CONTENTS,CODE
11 .plt 00000700 0000000000003770 0000000000003770 00003770 2**4
CONTENTS,CODE
12 .plt.got 00000018 0000000000003e70 0000000000003e70 00003e70 2**3
CONTENTS,CODE
13 .text 000124d9 0000000000003e90 0000000000003e90 00003e90 2**4
CONTENTS,CODE
14 .fini 00000009 000000000001636c 000000000001636c 0001636c 2**2
CONTENTS,CODE
15 .rodata 00004e1d 0000000000016380 0000000000016380 00016380 2**5
CONTENTS,DATA
16 .eh_frame_hdr 00000884 000000000001b1a0 000000000001b1a0 0001b1a0 2**2
CONTENTS,DATA
17 .eh_frame 00002cc0 000000000001ba28 000000000001ba28 0001ba28 2**3
CONTENTS,DATA
18 .init_array 00000008 000000000021eff0 000000000021eff0 0001eff0 2**3
CONTENTS,DATA
19 .fini_array 00000008 000000000021eff8 000000000021eff8 0001eff8 2**3
CONTENTS,DATA
20 .data.rel.ro 00000a38 000000000021f000 000000000021f000 0001f000 2**5
CONTENTS,DATA
21 .dynamic 00000200 000000000021fa38 000000000021fa38 0001fa38 2**3
CONTENTS,DATA
22 .got 000003c8 000000000021fc38 000000000021fc38 0001fc38 2**3
CONTENTS,DATA
23 .data 00000268 0000000000220000 0000000000220000 00020000 2**5
CONTENTS,DATA
24 .bss 000012e0 0000000000220280 0000000000220280 00020268 2**5
ALLOC
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 00020268 2**2
CONTENTS,READONLY
一个Google search for "vma and lma meaning"带我去this site,它引自GNU ld
链接器手册的有用引用。 Searching for that quote带给我here,它很方便地提供了报价来源。因此,我们直接引用其原始报价:
每个可加载或可分配的输出节都有两个地址。第一个是 VMA ,即虚拟内存地址。这是运行输出文件时该节将具有的地址。第二个是 LMA ,即加载内存地址。这是将加载该节的地址。在大多数情况下,这两个地址是相同的。当它们可能不同时,一个示例是将数据段加载到ROM中,然后在程序启动时将其复制到RAM中(此技术通常用于在基于ROM的系统中初始化全局变量)。在这种情况下,ROM地址为LMA,RAM地址为VMA。
通过将objdump程序与“ -h”选项一起使用,您可以在目标文件中查看各个部分。
(来源:GNU linker script ld
manual)
这意味着objdump -h
所示的任何没有VMA的输出节都不是程序的一部分。这样就省去了.gnu_debuglink
部分。
接下来,我们可以看到.bss
部分的大小(0x12e0)与berkeley bss
部分的大小完全相同,所以这是一个匹配项:
.bss = bss
bss
包含零初始化的全局变量和静态变量。
那么data
输出节呢?该节包含所有非零初始化(即:已用一些非零值初始化)的全局变量和静态变量?
然后,text
输出部分包含所有程序代码以及常量(只读)静态和全局变量 ,该怎么办?
通过逻辑推论和分析,并使用我的prior knowledge about which sections go into Flash vs RAM vs both on microcontrollers,我确定在READONLY
输出节中标记为objdump -h
的所有节(其中包含一些DATA
(非零初始化,const
(只读)静态和全局变量)和一些CODE
(实际程序逻辑)(也为只读)) 存储在text
输出节中。。
所以:
.interp + .note.ABI-tag + .note.gnu.build-id + .gnu.hash + .dynsym + .dynstr
+ .gnu.version + .gnu.version_r + .rela.dyn + .rela.plt + .init + .plt
+ .plt.got + .text + .fini + .rodata + .eh_frame_hdr + .eh_frame
= text
您可以在数学上求和所有大小来确认这一点。十六进制:
1c + 20 + 24 + ec + df8 + 682 + 12a + 70 + 1350 + a68 + 17 + 700 + 18 + 124d9 + 9 + 4e1d
+ 884 + 2cc0 = 1e48a
...这是伯克利大小输出中显示的text
部分的大小。
您可以在下图中看到它们以黄色框出。
因此,标记为DATA
和NOT READONLY
的其余部分是data
部分:
.init_array + .fini_array + .data.rel.ro + .dynamic + .got + .data
= data
同样,十六进制大小总和确认了这一点:
8 + 8 + a38 + 200 + 3c8 + 268 = 1278
...这是伯克利大小输出中data
部分的大小。
您可以在下图中看到它们以蓝色框出。
在此图像中,您可以看到所有3个以不同颜色包装的berkely输出部分:
- berkeley格式的
text
输出节(只读,程序逻辑以及const静态和全局变量)以黄色框出。 - berkeley格式的
data
输出节(非零初始化(即非零初始化)的静态变量和全局变量)用蓝色框起来。 - berkeley格式的
bss
输出节(零初始化的静态变量和全局变量)用红色框出。
在查看微控制器目标文件(例如STM32 MCU)的情况下:
- 闪存使用量=
text
+data
,并且 - 静态和全局变量的RAM内存使用量=
bss
+data
。- 这意味着剩余用于堆栈(局部变量)和堆(动态内存分配)=
RAM_total - (bss + data)
的RAM。
- 这意味着剩余用于堆栈(局部变量)和堆(动态内存分配)=