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 = .;
}
我程序中的某些部分位于内存中的不同位置,并且有一些未使用的内存位置。以下是我的程序目标文件的一部分:
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 = .;
}