Generating %pc relative address of constant data
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();
}
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.
00000000 : 0: e59f300c ldr r3, [pc, #12] ; 14 4: e59f000c ldr r0, [pc, #12] ; 18 8: e08f3003 add r3, pc, r3 c: e0830000 add 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
Are you getting the same warning I am getting?
/tmp/ccySyaUE.s: Assembler messages: /tmp/ccySyaUE.s:35: Warning: ignoring changed section attributes for .text
精彩评论