Hud*_*son 6 gcc arm fpic relative-addressing
有没有办法让gcc生成%pc常量的相对地址?即使字符串出现在文本段中,arm-elf-gcc也会生成一个指向数据的常量指针,通过%pc相对地址加载指针的地址,然后取消引用它.出于各种原因,我需要跳过中间步骤.举个例子,这个简单的功能:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename;
}
Run Code Online (Sandbox Code Playgroud)
生成(编译时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
Run Code Online (Sandbox Code Playgroud)
我原以为它会产生更像的东西:
filename:
add r0, pc, #0
bx lr
_filename.1175:
.ascii "logfile\000"
Run Code Online (Sandbox Code Playgroud)
有问题的代码需要部分独立于位置,因为它将在加载时重新定位到内存中,但也与未编译的代码集成-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;
}
Run Code Online (Sandbox Code Playgroud)
但是这种技术要求手动修复所有数据引用,因此filename()上例中的函数将变为:
const char * filename(void)
{
static const char _filename[]
__attribute__((section(".text")))
= "logfile";
return _filename + find_offset();
}
Run Code Online (Sandbox Code Playgroud)
嗯,也许你必须将其编译为 -fPIC 才能获得 PIC。或者干脆用汇编程序来写,汇编程序比你写的C容易得多。
00000000 : 0: e59f300c ldr r3, [pc, #12] ; 14 4: e59f000c ldr r0, [pc, #12] ; 18 8:e08f3003添加r3,pc,r3 c: e0830000 添加 r0, r3, r0 10: e12fff1e bx lr 14: 00000004 andeq r0, r0, r4 18: 00000000 andeq r0, r0, r0 0000001c: 1c: 66676f6c strbtvs r6, [r7], -ip, ror #30 20:00656c69 rsbeq r6、r5、r9、ror #24
您是否收到与我相同的警告?
/tmp/ccySyaUE.s:汇编器消息: /tmp/ccySyaUE.s:35:警告:忽略 .text 已更改的节属性
| 归档时间: |
|
| 查看次数: |
2246 次 |
| 最近记录: |