链接器似乎将数据放在错误的部分

时间:2017-05-01 22:07:34

标签: gcc linker bare-metal

我不明白为什么链接器将数据放在原来的位置。具体来说,为什么不将所有.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

0 个答案:

没有答案