将 binutils `size` 输出从 "sysv" 格式(`size --format=sysv my_executable`)转换为 "berkeley" 格式(`size --format=berkeley my_executable`)
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”格式的哪些小部分(部分)进入哪些大部分(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
这是十六进制的 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
[=115] 中的所有 输出部分 =]目标文件,或可执行文件。这些输出部分与 size -x --format=sysv /bin/ls
命令的输出相匹配,但具有 more-detailed 信息,例如 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
A Google search for "vma and lma meaning" brings me to this site, which has a useful quote from the GNU ld
linker manual. Searching for that quote leads me ,其中方便地提供了引用的来源。因此,让我们直接从其原始来源引用引文:
Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.
You can see the sections in an object file by using the objdump program with the ‘-h’ option.
(来源:GNU linker script ld
manual)
这意味着 objdump -h
显示的任何没有 VMA 的输出部分都不是程序的一部分。这消除了 .gnu_debuglink
部分。
接下来,我们可以看到 .bss
部分与 berkeley bss
部分具有完全相同的大小 (0x12e0),因此匹配:
.bss = bss
bss
包含 zero-initialized 全局和静态变量.
那么,data
输出部分呢,它包含所有 NON-zero-initialized(即:用一些 non-zero 值初始化)全局和静态变量?
还有 text
输出部分呢,它包含所有 程序代码和常量(只读)静态和全局变量?
嗯,通过逻辑推导和分析,并使用我的 prior knowledge about which sections go into Flash vs RAM vs both on microcontrollers,我确定 所有在 objdump -h
输出部分中标记为 READONLY
的部分(其中包含一些DATA
(非zero-initialized、const
(read-only)静态和全局变量)和一些CODE
(实际程序逻辑)(也read-only))被存储到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
...这是 berkeley 大小输出中显示的 text
部分的大小。
您可以在下图中看到它们用黄色框起来。
因此,标记为 DATA
而不是 READONLY
的其余部分是 data
部分:
.init_array + .fini_array + .data.rel.ro + .dynamic + .got + .data
= data
再次,十六进制大小总和证实了这一点:
8 + 8 + a38 + 200 + 3c8 + 268 = 1278
...这是 berkeley 大小输出中 data
部分的大小。
您可以在下图中看到它们用蓝色框起来。
在这张图片中,您可以看到用不同颜色框起来的所有 3 个 berkely 输出部分:
- berkeley-format
text
输出部分(read-only、程序逻辑和 const 静态和全局变量)用黄色框起来。
- berkeley-format
data
输出部分(非zero-initialized[即:other-than-zero初始化的]静态和全局变量)用蓝色框起来。
- berkeley-format
bss
输出部分(zero-initialized 静态和全局变量)用红色框起来。
在查看微控制器目标文件的情况下,例如 STM32 mcu:
- 闪存使用量 =
text
+ data
,并且
- 静态和全局变量的 RAM 内存使用量 =
bss
+ data
。
- 这意味着剩余的 RAM 用于堆栈(局部变量)和堆(动态内存分配)=
RAM_total - (bss + data)
。
主要参考资料:
我想知道如何获得这种 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
这是十六进制的 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
[=115] 中的所有 输出部分 =]目标文件,或可执行文件。这些输出部分与 size -x --format=sysv /bin/ls
命令的输出相匹配,但具有 more-detailed 信息,例如 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
A Google search for "vma and lma meaning" brings me to this site, which has a useful quote from the GNU ld
linker manual. Searching for that quote leads me
Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.
You can see the sections in an object file by using the objdump program with the ‘-h’ option.
(来源:GNU linker script ld
manual)
这意味着 objdump -h
显示的任何没有 VMA 的输出部分都不是程序的一部分。这消除了 .gnu_debuglink
部分。
接下来,我们可以看到 .bss
部分与 berkeley bss
部分具有完全相同的大小 (0x12e0),因此匹配:
.bss = bss
bss
包含 zero-initialized 全局和静态变量.
那么,data
输出部分呢,它包含所有 NON-zero-initialized(即:用一些 non-zero 值初始化)全局和静态变量?
还有 text
输出部分呢,它包含所有 程序代码和常量(只读)静态和全局变量?
嗯,通过逻辑推导和分析,并使用我的 prior knowledge about which sections go into Flash vs RAM vs both on microcontrollers,我确定 所有在 objdump -h
输出部分中标记为 READONLY
的部分(其中包含一些DATA
(非zero-initialized、const
(read-only)静态和全局变量)和一些CODE
(实际程序逻辑)(也read-only))被存储到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
...这是 berkeley 大小输出中显示的 text
部分的大小。
您可以在下图中看到它们用黄色框起来。
因此,标记为 DATA
而不是 READONLY
的其余部分是 data
部分:
.init_array + .fini_array + .data.rel.ro + .dynamic + .got + .data
= data
再次,十六进制大小总和证实了这一点:
8 + 8 + a38 + 200 + 3c8 + 268 = 1278
...这是 berkeley 大小输出中 data
部分的大小。
您可以在下图中看到它们用蓝色框起来。
在这张图片中,您可以看到用不同颜色框起来的所有 3 个 berkely 输出部分:
- berkeley-format
text
输出部分(read-only、程序逻辑和 const 静态和全局变量)用黄色框起来。 - berkeley-format
data
输出部分(非zero-initialized[即:other-than-zero初始化的]静态和全局变量)用蓝色框起来。 - berkeley-format
bss
输出部分(zero-initialized 静态和全局变量)用红色框起来。
在查看微控制器目标文件的情况下,例如 STM32 mcu:
- 闪存使用量 =
text
+data
,并且 - 静态和全局变量的 RAM 内存使用量 =
bss
+data
。- 这意味着剩余的 RAM 用于堆栈(局部变量)和堆(动态内存分配)=
RAM_total - (bss + data)
。
- 这意味着剩余的 RAM 用于堆栈(局部变量)和堆(动态内存分配)=