arm-none-eabi-gcc
的默认链接器脚本定义了几个VMA为0的部分。其中大部分包含调试信息:
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
//snip several more of these, until...
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
我不明白这是干什么的,DWARF部分的解释性注解也没有帮助--这些部分 * 真的 * 不可能都有相同的起始地址,除非它们的大小都是0!另外,脚本将地址0分配给了这些部分,而不是符号。* 而且 * 该注解不适用于“Stabs”部分...
使用readelf -S
表明,理论上它们的地址都是0,但它们的偏移量也各不相同--假设这些偏移量是它们在加载时的实际地址:
[13] .stab PROGBITS 00000000 009a6c 00009c 0c 14 0 4
[14] .stabstr STRTAB 00000000 009b08 00014d 00 0 0 1
...
[16] .debug_aranges PROGBITS 00000000 009cb0 0005f0 00 0 0 8
[17] .debug_info PROGBITS 00000000 00a2a0 0110c9 00 0 0 1
[18] .debug_abbrev PROGBITS 00000000 01b369 00401d 00 0 0 1
[19] .debug_line PROGBITS 00000000 01f386 0063ed 00 0 0 1
[20] .debug_frame PROGBITS 00000000 025774 00097c 00 0 0 4
[21] .debug_str PROGBITS 00000000 0260f0 001f29 01 MS 0 0 1
[22] .debug_line_str PROGBITS 00000000 028019 0000b3 01 MS 0 0 1
[23] .debug_loclists PROGBITS 00000000 0280cc 00221c 00 0 0 1
[24] .debug_rnglists PROGBITS 00000000 02a2e8 000495 00 0 0 1
[25] .ARM.attributes ARM_ATTRIBUTES 00000000 02a77d 00002e 00 0 0 1
我唯一的想法是虚拟地址0可能被认为是一个特殊的地址,这并不是字面上的意思,而是意味着具有这个地址的部分将不会被加载到内存中(因此将不会有一个加载地址),除非代码在调试器下运行。
有人能给我解释一下这些重复地址到底发生了什么吗?
1条答案
按热度按时间uqzxnwby1#
elf(5)
man page中对此进行了说明:您应该看到这些部分的
SHF_ALLOC
标志未设置(readelf -S
输出的Flags字段中没有A
),因此它们不驻留在内存映像中。因此,不需要指定起始地址,因此该字段设置为零。实际上,无论是否调试,这些部分都不需要由
exec*
加载到内存中。程序员当然不需要运行这些部分,调试时,调试器将打开并读取二进制文件,解析出数据,作为与执行程序不同的操作。