这是答案:
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
or size -x /bin/ls
(同样的,因为 berkeley 是默认格式):
$ size -x /bin/ls
text data bss dec hex filename
0x1e48a 0x1278 0x12e0 133602 209e2 /bin/ls
这是十六进制的 sysv 大小输出,通过以下方式获得size -x --format=sysv /bin/ls
:
$ 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
,您将得到以下内容,其中显示了目标文件或可执行文件中的所有输出部分。这些输出部分与命令的输出相匹配,但具有更详细的信息,例如 VMA(虚拟内存地址)和 LMA(加载内存地址)等:/bin/ls
size -x --format=sysv /bin/ls
$ 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, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 0000000000000274 0000000000000274 00000274 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 000000ec 0000000000000298 0000000000000298 00000298 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000df8 0000000000000388 0000000000000388 00000388 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 00000682 0000000000001180 0000000000001180 00001180 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 0000012a 0000000000001802 0000000000001802 00001802 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000070 0000000000001930 0000000000001930 00001930 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn 00001350 00000000000019a0 00000000000019a0 000019a0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt 00000a68 0000000000002cf0 0000000000002cf0 00002cf0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000017 0000000000003758 0000000000003758 00003758 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000700 0000000000003770 0000000000003770 00003770 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt.got 00000018 0000000000003e70 0000000000003e70 00003e70 2**3
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 000124d9 0000000000003e90 0000000000003e90 00003e90 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini 00000009 000000000001636c 000000000001636c 0001636c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata 00004e1d 0000000000016380 0000000000016380 00016380 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 00000884 000000000001b1a0 000000000001b1a0 0001b1a0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame 00002cc0 000000000001ba28 000000000001ba28 0001ba28 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array 00000008 000000000021eff0 000000000021eff0 0001eff0 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array 00000008 000000000021eff8 000000000021eff8 0001eff8 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .data.rel.ro 00000a38 000000000021f000 000000000021f000 0001f000 2**5
CONTENTS, ALLOC, LOAD, DATA
21 .dynamic 00000200 000000000021fa38 000000000021fa38 0001fa38 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .got 000003c8 000000000021fc38 000000000021fc38 0001fc38 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000268 0000000000220000 0000000000220000 00020000 2**5
CONTENTS, ALLOC, LOAD, DATA
24 .bss 000012e0 0000000000220280 0000000000220280 00020268 2**5
ALLOC
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 00020268 2**2
CONTENTS, READONLY
谷歌搜索“vma 和 lma 含义”将我带到这个站点ld
,它有一个有用的 GNU链接器手册引用。搜索该引文将我引至此处,该引文的来源很方便。所以让我们直接从它的原始来源引用引用:
每个可加载或可分配的输出部分都有两个地址。第一个是VMA或虚拟内存地址。这是运行输出文件时该部分将具有的地址。第二个是LMA或加载内存地址。这是该部分将被加载的地址。在大多数情况下,这两个地址是相同的。它们可能不同的一个例子是数据段被加载到 ROM 中,然后在程序启动时复制到 RAM 中(这种技术通常用于在基于 ROM 的系统中初始化全局变量)。在这种情况下,ROM 地址将是 LMA,而 RAM 地址将是 VMA。
您可以使用带有“-h”选项的 objdump 程序查看目标文件中的部分。
(来源:GNU 链接器脚本ld
手册)
这意味着任何objdump -h
没有 VMA 的输出部分都不是程序的一部分。这消除了该.gnu_debuglink
部分。
接下来,我们可以看到该.bss
部分与 berkeley 部分具有完全相同的大小 (0x12e0) bss
,因此这是匹配的:
.bss = bss
bss
包含零初始化的全局和静态变量。
那么,data
包含所有非零初始化(即:用一些非零值初始化)全局和静态变量的输出部分呢?
而且,text
包含所有程序代码和常量(只读)静态和全局变量的输出部分呢?
好吧,通过逻辑推论和分析,并利用我关于哪些部分进入闪存、RAM 和微控制器上的先验知识,我确定了在输出部分中标记的所有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 单片机:
- 闪存使用量 =
text
+ data
,并且
- 静态和全局变量的 RAM 内存使用量 =
bss
+ data
。
- 这意味着剩余的 RAM 用于堆栈(局部变量)和堆(动态内存分配)=
RAM_total - (bss + data)
。
主要参考资料:
- GNU Linker (
ld
) 手册,“3.1 基本链接器脚本概念”部分:https ://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts
- [我自己的问题] https://electronics.stackexchange.com/questions/363931/how-do-i-find-out-at-compile-time-how-much-of-an-stm32s-flash-memory-动态