gcc 数组放置在与链接器脚本不同的奇怪地址中(arm64裸机)

qvtsj1bj  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(179)

在aarch64裸金属程序构建中,C程序中的某些数组被赋予了节属性,以便它们被放置在.axpudata_args0,.axpudata_args1,.节中,这是链接器脚本开始处包含的linkadd. h文件。

AXPUDATA_START = 0xa0000000;
AXPUDATA_SPACE = 0x100000;
ARGBUF0 = AXPUDATA_START;
ARGBUF1 = AXPUDATA_START + AXPUDATA_SPACE;
ARGBUF2 = AXPUDATA_START + 2*AXPUDATA_SPACE;
ARGBUF3 = AXPUDATA_START + 3*AXPUDATA_SPACE;

字符串
这是链接器脚本(显示部分)。

INCLUDE linkadd.h
...
  . = AXPUDATA_START;
    _axpudata_start = .;
  .axpudata : {
        . = ARGBUF0;
        *(.axpudata_args0)
        . = ARGBUF1;
        *(.axpudata_args1)
        . = ARGBUF2;
        *(.axpudata_args2)
        . = ARGBUF3;
        *(.axpudata_args3)
        . = ARGBUF4;


我以为数组会被放置在0xa000000,0xa0100000,0xa0200000,.但是生成的Map文件显示它们被分配在0xa000000,0x1400000,0x14010000,如下所示。

.axpudata       0x00000000a0000000 0xa0d00800
                0x00000000a0000000                . = ARGBUF0
 *fill*         0x00000000a0000000 0xa0000000
 *(.axpudata_args0)
 .axpudata_args0
                0x0000000140000000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140000000                args_buffer_0
                0x00000000a0100000                . = ARGBUF1
 *fill*         0x0000000140002000    0xfe000
 *(.axpudata_args1)
 .axpudata_args1
                0x0000000140100000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140100000                args_buffer_1
                0x00000000a0200000                . = ARGBUF2
 *fill*         0x0000000140102000    0xfe000
 *(.axpudata_args2)
 .axpudata_args2
                0x0000000140200000    0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140200000                args_buffer_2
                0x00000000a0300000                . = ARGBUF3
 *fill*         0x0000000140240000    0xc0000


为什么args_buffer0从0x14000000开始而不是0xa0000000?实际的缓冲区大小是0x2000,0x2000,0x40000,..我不知道为什么在程序计数设置为0xa000000后,填充另一个0xa0000000,以便args_buffer_0从0x14000000开始,而不是0xa0000000。我在过去使用过很多次链接器脚本,但我不知道这种情况下有什么问题。如果有人能摆脱一些,我会很感激。光在我这里。

pkwftd7m

pkwftd7m1#

这是迈克尔·佩奇的评论,这是我想要的正确答案。
当你设置。(当前位置计数器),它是相对于当前输出段开始处的虚拟存储器地址的偏移量(在您的情况下为0xa 0000000,因为您将.设置为0xa 0000000)。当您这样做时。= ARGBUF 0;`您正在将位置计数器设置为0xa 0000000 + 0xa 0000000,即0x 140000000. . = ARGBUF 1;在该部分中,将位置计数器设置为0xa 0000000 + 0xa 0000000 + 0x 100000,即0x 140100000,依此类推
所以我这样修改了linkadd.h:

AXPUDATA_START = 0xa0000000;
AXPUDATA_SPACE = 0x100000;
ARGBUF0 = 0;
ARGBUF1 = 1*AXPUDATA_SPACE;
ARGBUF2 = 2*AXPUDATA_SPACE;
ARGBUF3 = 3*AXPUDATA_SPACE;

字符串
输出结果就是我想要的

.axpudata       0x00000000a0000000   0xd00800
                0x0000000000000000                . = ARGBUF0
 *(.axpudata_args0)
 .axpudata_args0
                0x00000000a0000000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x00000000a0000000                args_buffer_0
                0x0000000000100000                . = ARGBUF1
 *fill*         0x00000000a0002000    0xfe000
 *(.axpudata_args1)
 .axpudata_args1
                0x00000000a0100000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x00000000a0100000                args_buffer_1
                0x0000000000200000                . = ARGBUF2
 *fill*         0x00000000a0102000    0xfe000
 *(.axpudata_args2)
 .axpudata_args2
                0x00000000a0200000    0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x00000000a0200000                args_buffer_2
                0x0000000000300000                . = ARGBUF3
 *fill*         0x00000000a0240000    0xc0000

相关问题