2010-05-30 11 views
6

Czy istnieje sposób na wygenerowanie przez gcc %pc względnych adresów stałych? Nawet jeśli ciąg pojawi się w segmencie tekstowym, arm-elf-gcc wygeneruje stały wskaźnik do danych, załaduje adres wskaźnika poprzez adres względny, a następnie usunie go. Z wielu powodów muszę pominąć środkowy krok. Jako przykład, ta prosta funkcja:Generowanie adresu% pc stałych danych

const char * filename(void) 
{ 
    static const char _filename[] 
      __attribute__((section(".text"))) 
      = "logfile"; 
    return _filename; 
} 

generuje (gdy skompilowany z 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 

bym oczekuje się, aby wygenerować coś więcej takiego:

filename: 
    add r0, pc, #0 
    bx lr 
_filename.1175: 
    .ascii "logfile\000" 

kodu musi być częściowo niezależny od położenia, ponieważ zostanie przeniesiony do pamięci w czasie ładowania, ale także zintegrowany z kodem, który nie został skompilowany -fPIC, więc Nie ma globalnej tabeli przesunięć.

Moja obecna praca wokół jest do wywołania funkcji non-inline (który będzie być wykonywane poprzez %pc względnego adresu), aby znaleźć odsunięcie od skompilowanej umieszczeniem w technice podobny do tego, jak kod -fPIC działa:

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; 
} 

Ale ta technika wymaga wszystko odniesienia danych ustala się ręcznie, więc funkcja w powyższym przykładzie filename() staną:

const char * filename(void) 
{ 
    static const char _filename[] 
      __attribute__((section(".text"))) 
      = "logfile"; 
    return _filename + find_offset(); 
} 

Odpowiedz

1

Hmmm, może musisz skompilować go jako -fPIC, aby uzyskać PIC. Lub po prostu zapisz go w asembler, asembler jest dużo łatwiejszy niż C, który piszesz.

 
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 

Czy otrzymujesz to samo ostrzeżenie, które otrzymuję?

 
/tmp/ccySyaUE.s: Assembler messages: 
/tmp/ccySyaUE.s:35: Warning: ignoring changed section attributes for .text 
+0

Tak, otrzymuję to samo ostrzeżenie. Najłatwiejszym hackowaniem jest dodanie fałszywego znaku nowej linii i dodanie komentarza: __attribute __ ((sekcja (".tekst \ n #"))). Nie można skompilować z opcją -fPIC, ponieważ istnieją funkcje w pamięci ROM, które znajdują się pod jawnymi adresami. Montaż działa dla mnie, ale nie dla innych użytkowników systemu ... – Hudson

Powiązane problemy