生成常量数据的%pc相对地址
有没有办法让 gcc 生成常量的 %pc
相对地址?即使字符串出现在文本段中,arm-elf-gcc 也会生成一个指向数据的常量指针,通过 %pc
相对地址加载指针的地址,然后取消引用它。由于种种原因,我需要跳过中间步骤。作为一个例子,这个简单的函数:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename;
}
生成(当使用arm-elf-gcc-4.3.2 -nostdlib -c编译时 -O3 -W -Wall logfile.c ):
00000000 <filename>:
0: e59f0000 ldr r0, [pc, #0] ; 8 <filename+0x8>
4: e12fff1e bx lr
8: 0000000c .word 0x0000000c
0000000c <_filename.1175>:
c: 66676f6c .word 0x66676f6c
10: 00656c69 .word 0x00656c69
我希望它生成的内容更像是:
filename:
add r0, pc, #0
bx lr
_filename.1175:
.ascii "logfile\000"
有问题的代码需要部分位置独立,因为它将在加载时重新定位在内存中,但也集成使用未编译的代码-fPIC
,因此没有全局偏移表。
我当前的解决方法是调用一个非内联函数(将通过 %pc
相对地址完成),以类似的技术找到距编译位置的偏移量-fPIC
代码如何工作:
static intptr_t
__attribute__((noinline))
find_offset( void )
{
uintptr_t pc;
asm __volatile__ (
"mov %0, %%pc" : "=&r"(pc)
);
return pc - 8 - (uintptr_t) find_offset;
}
但是这种技术需要手动修复所有数据引用,因此上面的 filename()
函数示例将变为:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename + find_offset();
}
Is there a way to have gcc generate %pc
relative addresses of constants? Even when the string appears in the text segment, arm-elf-gcc will generate a constant pointer to the data, load the address of the pointer via a %pc
relative address and then dereference it. For a variety of reasons, I need to skip the middle step. As an example, this simple function:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename;
}
generates (when compiled with arm-elf-gcc-4.3.2 -nostdlib -c
):
-O3 -W -Wall logfile.c
00000000 <filename>:
0: e59f0000 ldr r0, [pc, #0] ; 8 <filename+0x8>
4: e12fff1e bx lr
8: 0000000c .word 0x0000000c
0000000c <_filename.1175>:
c: 66676f6c .word 0x66676f6c
10: 00656c69 .word 0x00656c69
I would have expected it to generate something more like:
filename:
add r0, pc, #0
bx lr
_filename.1175:
.ascii "logfile\000"
The code in question needs to be partially position independent since it will be relocated in memory at load time, but also integrate with code that was not compiled -fPIC
, so there is no global offset table.
My current work around is to call a non-inline function (which will be done via a %pc
relative address) to find the offset from the compiled location in a technique similar to how -fPIC
code works:
static intptr_t
__attribute__((noinline))
find_offset( void )
{
uintptr_t pc;
asm __volatile__ (
"mov %0, %%pc" : "=&r"(pc)
);
return pc - 8 - (uintptr_t) find_offset;
}
But this technique requires that all data references be fixed up manually, so the filename()
function in the above example would become:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename + find_offset();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,也许你必须将其编译为 -fPIC 才能获得 PIC。或者干脆用汇编程序来写,汇编程序比你写的C容易得多。
您是否收到与我相同的警告?
Hmmm, maybe you have to compile it as -fPIC to get PIC. Or simply write it in assembler, assembler is a lot easier than the C you are writing.
Are you getting the same warning I am getting?