我不明白为什么链接器将数据放在原来的位置。具体来说,为什么不将所有.rodata
放在一起?
这是链接描述文件的相关部分:
/* Read-only data. When generating assembly code, gcc places
hard-coded strings (among other thigns) in .section .rodata */
.rodata : ALIGN(1024)
{
LONG(0x35343332); /* Mark the beginning of rodata. */
*(.rodata)
LONG(0x32444E45); /* Mark the end of rodata. */
}
/* Read-write data. When generating assembly code, gcc places
global and static data in .section .data. */
.data : ALIGN(1024)
{
LONG(0x47474747)
*(.data)
}
结果图像如下。请注意,部分.rodata
出现在END2
标记之后。
(1)为什么在我放入链接描述文件的“结束”标记后面有.rodata
?
(2).rodata
的结尾和.data
部分的开头(标有'GGGG')之间的所有数据是什么?
000011c0 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000011d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001400 32 33 34 35 19 00 00 00 50 00 00 00 00 00 00 00 |2345....P.......|
00001410 88 13 00 00 3a 20 63 75 72 3d 00 2c 20 61 76 67 |....: cur=., avg|
00001420 3d 00 2c 20 6d 69 6e 3d 00 2c 20 6d 61 78 3d 00 |=., min=., max=.|
00001430 2c 20 76 61 72 3d 00 0a 00 2a 2a 2a 00 42 72 61 |, var=...***.Bra|
00001440 6e 63 68 20 54 69 6d 69 6e 67 3a 0a 00 44 61 74 |nch Timing:..Dat|
00001450 61 20 53 65 63 74 69 6f 6e 3a 0a 00 41 6c 77 61 |a Section:..Alwa|
00001460 79 73 3a 20 00 20 4e 65 76 65 72 3a 20 00 52 61 |ys: . Never: .Ra|
00001470 6e 64 6f 6d 3a 20 00 0a 56 65 72 73 69 6f 6e 20 |ndom: ..Version |
00001480 35 0a 00 20 3c 3d 20 62 75 66 66 65 72 3b 20 20 |5.. <= buffer; |
00001490 20 00 20 3c 3d 20 73 74 61 63 6b 3b 20 20 00 20 | . <= stack; . |
000014a0 3c 3d 20 63 6f 64 65 3b 0a 20 20 00 20 3c 3d 20 |<= code;. . <= |
000014b0 64 61 74 61 20 76 61 6c 3b 20 00 20 3c 3d 20 64 |data val; . <= d|
000014c0 61 74 61 20 2a 0a 00 53 74 61 20 00 45 6e 64 0a |ata *..Sta .End.|
000014d0 00 20 3c 3d 20 53 74 6f 6d 70 21 3b 20 00 20 3c |. <= Stomp!; . <|
000014e0 3d 76 61 6c 75 65 3b 20 20 20 00 45 4e 44 32 30 |=value; .END20|
000014f0 78 30 00 30 78 00 41 6c 6c 20 44 6f 6e 65 21 00 |x0.0x.All Done!.|
00001500 46 41 49 4c 20 46 41 49 4c 20 46 41 49 4c 00 30 |FAIL FAIL FAIL.0|
00001510 78 30 00 30 78 00 00 00 14 00 00 00 00 00 00 00 |x0.0x...........|
00001520 01 7a 52 00 01 7c 08 01 1b 0c 04 04 88 01 00 00 |.zR..|..........|
00001530 10 00 00 00 1c 00 00 00 98 ed ff ff 14 00 00 00 |................|
00001540 00 00 00 00 10 00 00 00 30 00 00 00 a4 ed ff ff |........0.......|
<More of the same. I cut this out.>>
00001b10 1c 00 00 00 1c 00 00 00 7f f5 ff ff 27 01 00 00 |............'...|
00001b20 00 41 0e 08 85 02 42 0d 05 03 23 01 c5 0c 04 04 |.A....B...#.....|
00001b30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001c00 47 47 47 47 70 70 70 70 53 52 51 54 57 57 57 57 |GGGGppppSRQTWWWW|
00001c10 7a 7a 00 00 79 79 79 79 00 00 00 00 00 00 00 00 |zz..yyyy........|
00001c20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
为了完整性,这里是完整的链接描述文件,以及包含.rodata节的gcc生成的程序集
SECTIONS
{
. = 0x7c00; __start = .;
/* First place the code (aka "text") in the image */
.text :
{
*(.boot)
. = 0x1FE;
SHORT(0xAA55)
*(.stage2)
/* All other code (i.e., code that is not part of the boot loader)
is placed in ".section .text". The line below instructs the
linker to place this remainign code next in the image. */
*(.text)
}
/* Read-only data. When generating assembly code, gcc places
hard-coded strings (among other thigns) in .section .rodata */
.rodata : ALIGN(1024)
{
LONG(0x35343332); /* Mark the end of the disk image. */
*(.rodata)
LONG(0x32444E45); /* Mark the end of the disk image. */
}
/* Read-write data. When generating assembly code, gcc places
global and static data in .section .data. */
.data : ALIGN(1024)
{
LONG(0x47474747)
*(.data)
}
.data2 : ALIGN(1024)
{
*(.data2)
}
/* Calculate the total number of sectors used by the code and data.
Normally, the "." gives the value of the linker's internal
pointer relative to the current section. Surrounding the
calculation with ABSOLUTE assures that the values used are
relative to the entire image. This value is used in boot.S to
specify the number of sectors that must be loaded
*/
__stage2_nsectors = ABSOLUTE((. - __start) / 512);
/* Ensure that the generated image is a multiple of 512 bytes
long. (Some machines and VMs freak out if the boot image is not a
multiple of 512 bytes. */
__end = .;
__end_align_4k = ALIGN(4k);
/* This OS exports data by dumping a memory buffer back to the boot
image. When running on a VM, you can't dump data beyond the
original size of the image. This "fake" section below
artifically increases the size of the boot image.
Because the image is padded to a multiple of 512 above, and the
section below is exactly 1MB, we know the resulting image will
be a multiple of 512 bytes long.*/
.data3 :
{
LONG(0x41544144) /* Mark the section in the image that will be used to dump data. */
. = 0x100000 - 4; /* Make sure that the disk image is a multiple of 512 bytes. */
LONG(0x444E4500); /* Mark the end of the disk image. */
}
}
这是gcc生成的程序集,放在(我认为)链接器应该结束.rodata
部分之后:
.cfi_def_cfa_offset 4
ret
.cfi_endproc
.LFE9:
.size vgat_write_string, .-vgat_write_string
.section .text.unlikely
.LCOLDE9:
.text
.LHOTE9:
.section .rodata.str1.1,"aMS",@progbits,1
.LC10:
.string "FAIL FAIL FAIL"
.section .text.unlikely
.LCOLDB11:
.text
.LHOTB11:
.align 16
.globl vgat_write_unsigned
.type vgat_write_unsigned, @function
vgat_write_unsigned:
.LFB10:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
pushl %edi