将";sysv";format(`size--format=sysv my_ecutable`)输出的binutils`size`转换为";Berkeley";format(`size--format=Berkeley my_ecutable`) [英] Convert binutils `size` output from "sysv" format (`size --format=sysv my_executable`) to "berkeley" format (`size --format=berkeley my_executable`)
问题描述
我想知道如何获取此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";格式的哪些小部分(节)属于&Berkeley";格式的大部分(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是默认格式)在祸不单行中打印伯克利尺寸信息:
$ 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
,您将看到以下内容,其中显示了/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, 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
AGoogle search for "vma and lma meaning"将我带到this site,其中引用了GNUld
链接器手册中的有用引语。Searching for that quote引导我here,它可以方便地找到引用的来源。因此,让我们直接引用其原始来源的引语:每个可加载或可分配的输出节都有两个地址。第一个是vma,即虚拟内存地址。这是运行输出文件时该节将具有的地址。第二个是LMA,即加载内存地址。这是将加载节的地址。在大多数情况下,这两个地址将是相同的。它们可能不同的一个例子是将数据段加载到ROM中,然后在程序启动时复制到RAM中(此技术通常用于在基于ROM的系统中初始化全局变量)。在这种情况下,ROM地址将是LMA,RAM地址将是VMA。您可以使用带‘-h’选项的objdump程序查看目标文件中的节。
(来源:GNU linker script ld
manual)
objdump -h
显示的任何没有VMA的输出节都不是程序的一部分。这样就消除了.gnu_debuglink
节。
接下来,我们可以看到.bss
部分与Berkeleybss
部分具有完全相同的大小(0x12e0),因此这是匹配的:
.bss = bss
bss
包含零初始化的全局变量和静电变量。
那么,data
输出部分又如何呢?data
输出部分包含所有的非零初始化(即:用某个非零值初始化)全局变量和静电变量?
还有,text
输出部分怎么样,它包含所有程序代码以及常量(只读)静电和全局变量?
objdump -h
输出节(包含一些DATA
(非零初始化,const
(只读)静电和全局变量)和一些CODE
(实际程序逻辑)(也是只读))都存储在
所以:
.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
.,它是Berkeley Size输出中显示的text
节的大小。
您可以在下图中看到黄色方框。
因此,标记为DATA
而不是READONLY
的其余部分是data
部分:
.init_array + .fini_array + .data.rel.ro + .dynamic + .got + .data
= data
祸不单行规模总和再次证实了这一点:
8 + 8 + a38 + 200 + 3c8 + 268 = 1278
.,它是Berkeley Size输出中data
节的大小。
您可以在下图中看到蓝色方框。
在此图像中,您可以看到所有3个Berkely输出节都以不同的颜色装箱:
- Berkeley格式的
text
输出节(只读、程序逻辑以及常量静电和全局变量)以黄色方框显示。 - Berkeley格式的
data
输出节(非零初始化[即:非零初始化]静电和全局变量)以蓝色方框显示。 - Berkeley格式
bss
输出节(零初始化静电和全局变量)用红色方框显示。
在查看微控制器对象文件(如STM32 MCU)的情况下:
- 闪存使用量=
text
+data
, - 静电内存使用量和全局变量=
bss
+data
。- 表示剩余给STACK(局部变量)和HEAP(动态内存分配)的RAM=
RAM_total - (bss + data)
。
- 表示剩余给STACK(局部变量)和HEAP(动态内存分配)的RAM=
主要引用:
- GNU链接器(
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-and-dynami
这篇关于将";sysv";format(`size--format=sysv my_ecutable`)输出的binutils`size`转换为";Berkeley";format(`size--format=Berkeley my_ecutable`)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!