Есть ли способ заставить 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();
}