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

qvtsj1bj  于 2024-01-08  发布在  其他
关注(0)|答案(1)|浏览(233)

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

  1. AXPUDATA_START = 0xa0000000;
  2. AXPUDATA_SPACE = 0x100000;
  3. ARGBUF0 = AXPUDATA_START;
  4. ARGBUF1 = AXPUDATA_START + AXPUDATA_SPACE;
  5. ARGBUF2 = AXPUDATA_START + 2*AXPUDATA_SPACE;
  6. ARGBUF3 = AXPUDATA_START + 3*AXPUDATA_SPACE;

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

  1. INCLUDE linkadd.h
  2. ...
  3. . = AXPUDATA_START;
  4. _axpudata_start = .;
  5. .axpudata : {
  6. . = ARGBUF0;
  7. *(.axpudata_args0)
  8. . = ARGBUF1;
  9. *(.axpudata_args1)
  10. . = ARGBUF2;
  11. *(.axpudata_args2)
  12. . = ARGBUF3;
  13. *(.axpudata_args3)
  14. . = ARGBUF4;


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

  1. .axpudata 0x00000000a0000000 0xa0d00800
  2. 0x00000000a0000000 . = ARGBUF0
  3. *fill* 0x00000000a0000000 0xa0000000
  4. *(.axpudata_args0)
  5. .axpudata_args0
  6. 0x0000000140000000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  7. 0x0000000140000000 args_buffer_0
  8. 0x00000000a0100000 . = ARGBUF1
  9. *fill* 0x0000000140002000 0xfe000
  10. *(.axpudata_args1)
  11. .axpudata_args1
  12. 0x0000000140100000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  13. 0x0000000140100000 args_buffer_1
  14. 0x00000000a0200000 . = ARGBUF2
  15. *fill* 0x0000000140102000 0xfe000
  16. *(.axpudata_args2)
  17. .axpudata_args2
  18. 0x0000000140200000 0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  19. 0x0000000140200000 args_buffer_2
  20. 0x00000000a0300000 . = ARGBUF3
  21. *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:

  1. AXPUDATA_START = 0xa0000000;
  2. AXPUDATA_SPACE = 0x100000;
  3. ARGBUF0 = 0;
  4. ARGBUF1 = 1*AXPUDATA_SPACE;
  5. ARGBUF2 = 2*AXPUDATA_SPACE;
  6. ARGBUF3 = 3*AXPUDATA_SPACE;

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

  1. .axpudata 0x00000000a0000000 0xd00800
  2. 0x0000000000000000 . = ARGBUF0
  3. *(.axpudata_args0)
  4. .axpudata_args0
  5. 0x00000000a0000000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  6. 0x00000000a0000000 args_buffer_0
  7. 0x0000000000100000 . = ARGBUF1
  8. *fill* 0x00000000a0002000 0xfe000
  9. *(.axpudata_args1)
  10. .axpudata_args1
  11. 0x00000000a0100000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  12. 0x00000000a0100000 args_buffer_1
  13. 0x0000000000200000 . = ARGBUF2
  14. *fill* 0x00000000a0102000 0xfe000
  15. *(.axpudata_args2)
  16. .axpudata_args2
  17. 0x00000000a0200000 0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
  18. 0x00000000a0200000 args_buffer_2
  19. 0x0000000000300000 . = ARGBUF3
  20. *fill* 0x00000000a0240000 0xc0000

展开查看全部

相关问题