当我在函数内部定义了本地数据时,它会被放入.rodata部分。这意味着.text段将包含.text中的绝对地址(// 2)的相对引用(// 1),后者又指向.rodata中的数据(// 3)。
int function() { int a[] = {97, 98, 99, 100, 101, 103}; }
// Undesirable:
00000000 <.text.function>:
/---/
6: 4b07 ldr r3, [pc, #28] ; (24 <function+0x24>) //1
/---/
24: 00000000 .word 0x00000000 //2 absolute address of .rodata
00000000 <.rodata>: // absolute address will be replaced by linker
0: 00000061 .word 0x00000061 //3
4: 00000062 .word 0x00000062
8: 00000063 .word 0x00000063
c: 00000064 .word 0x00000064
10: 00000065 .word 0x00000065
14: 00000067 .word 0x00000067
据我所知,保持数据和代码分离一般是令人钦佩的,但对于我的嵌入式系统,我希望将本地数据和功能代码纠缠在一起。我希望[pc,#28]相对指针直接指向数据位置,数组值应该直接在.text部分。
我可以使用linkerscript做类似的事情,但绝对地址仍然在那里,我不希望函数.text部分包含任何绝对地址。
// Undesirable:
.text.function : {
*(.text.function)
filename.o(.rodata)
}
00000000 <.text.function>:
/---/
6: 4b07 ldr r3, [pc, #28] ; (24 <function+0x24>)
/---/
24: 00000000 .word 0x00000028 // address of next line
28: 00000061 .word 0x00000061
/---/
是否有任何编译器标志或其他方法强制gcc在代码旁边包含数据并跳过这个额外的间接?
修改
为了进一步澄清我的要求,我想指出一些不会起作用的解决方案。将static const
添加到数组将强制它存储在.rodata部分内,因此与我想要的完全相反。添加__attribute__((section(".text")))
不会起作用,因为这个问题是关于局部变量的,局部变量不能有节属性。不幸的是,-fpic
或-fpie
似乎也不起作用,而是依赖于运行时链接器来替换绝对地址。