GNU 链接器 - 如何填充未使用的内存 space

GNU linker - How to fill unused memory space

我程序中的某些部分位于内存中的不同位置,并且有一些未使用的内存位置。以下是我的程序目标文件的一部分:

a0000128:   20cf8f93            addi    t6,t6,524 # a0000330 <region_1>
a000012c:   000f8067            jr  t6

Disassembly of section .fill:

00000000a0000130 <_end-0x800290>:
    a0000130:   deaa                    sw  a0,124(sp)
    a0000132:   c0ad                    beqz    s1,a0000194 <_start+0x194>
    a0000134:   dede                    sw  s7,124(sp)
    a0000136:   c0ad                    beqz    s1,a0000198 <_start+0x198>
    ...

Disassembly of section .s_region_1:

00000000a0000330 <region_1>:
    a0000330:   00400f97            auipc   t6,0x400
    a0000334:   00cf8f93            addi    t6,t6,12 # a040033c <region_2>
    a0000338:   000f8067            jr  t6

如图所示,地址0xa000012c的指令跳转到地址0xa0000330的另一条指令。由于存在未使用的内存位置,我在链接描述文件中使用了 FILL 命令。但是对应的HEX文件(用objcopy -O verilog生成)不包含region_1的机器码。也就是说,HEX 文件只包含.text 部分和用于填充未使用内存区域的数据:

13 0F 00 00 9B 0F 10 00 93 9F FF 01 1B 08 F0 FF 
13 18 38 03 13 08 18 04 13 18 C8 00 13 08 98 12 
73 10 18 30 97 0F 00 00 93 8F CF 20 67 80 0F 00 
@A0000130
AA DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
...

链接描述文件内容如下:

SECTIONS
{
  . = 0xA0000000;
  .text : { *(.text) }
.fill :
{
    FILL(0xDEADC0DE);
    BYTE(0xAA); 
    . = . + 0x1FF;
}
.s_region_1 : { *(s_region_1) }
.bss : { *(.bss) }
_end = .;
}

上面的链接描述文件有什么问题?

这是我要生成的内存映射:

/*************************/





            .text





/*************************/



    /* EMPTY REGION */



/*************************/



        .section_1



/*************************/

我注意到在定义部分时我必须在我的汇编代码中添加 "aw" flags:

.section ".sregion1","aw"
region_1:
    la x31, region_2
    jr x31

添加“aw”标志后,objcopy 按预期生成了 HEX 文件:

@80000000
1B 00 10 00 13 10 F0 01 B7 F0 0F 00 9B 80 70 81 
93 90 C0 00 93 80 90 A5 13 01 80 00 93 01 80 00 
1B 02 10 00 13 12 F2 01 B7 B2 0F 00 9B 82 12 FB
...
@80400130
97 0F 00 00 93 8F CF 00 67 80 0F 00 97 0F 00 00 
93 8F 0F 00 67 80 0F 00

以下是我的链接器文件的最终版本:

OUTPUT_ARCH( "riscv" )
ENTRY(_start)

/*
MEMORY {
       text (RX): o = 0x80000000, LENGTH = 128M
       s_region_1 (RX): o = 0x80400000, LENGTH = 256K
}
*/

SECTIONS
{

  . = 0x80000000;
  .text :
  {
    *(.text);
    
  }

  . = . + 0x400000;
  .sregion1 : { *(.sregion1) }
  . = . + 0x400000;
  .bss : { *(.bss) }
  _end = .;
}