2010-05-30 13 views
6

C'è un modo per fare in modo che gcc generi gli indirizzi relativi delle costanti? %pc? Anche quando la stringa appare nel segmento di testo, arm-elf-gcc genererà un puntatore costante ai dati, caricherà l'indirizzo del puntatore tramite un indirizzo relativo %pc e quindi lo denoterà. Per una serie di motivi, ho bisogno di saltare la fase centrale. A titolo di esempio, questa semplice funzione:Generazione dell'indirizzo relativo di dati costanti% pc

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

genera (quando si compila con 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 

mi sarei aspettato di generare qualcosa di più simile:

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

Il codice in questione deve essere parzialmente indipendente dalla posizione poiché verrà riposizionato in memoria al momento del caricamento, ma si integrerà anche con il codice che non è stato compilato -fPIC, quindi non esiste una tabella di offset globale.

Il mio lavoro attuale intorno è quello di chiamare una funzione non in linea (che sarà sia fatta tramite un indirizzo relativo %pc) per trovare l'offset dalla posizione compilato in una tecnica simile a come funziona -fPIC codice:

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

Ma questa tecnica richiede che tutti riferimenti dati fissare manualmente, per cui la funzione filename() nell'esempio precedente diventerebbero:

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

risposta

1

Hmmm, forse devi compilarlo come -fPIC per ottenere PIC. O semplicemente scrivilo in assembler, l'assemblatore è molto più facile del C che stai scrivendo.

 
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 

Stai ricevendo lo stesso avviso che sto ottenendo?

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

Sì, ricevo lo stesso avviso. Il trucco più semplice è quello di aggiungere un nuovo finto commento e commento: __attribute __ ((sezione (". Testo \ n #"))). Non può essere compilato con -fPIC poiché ci sono funzioni nella ROM che sono ad indirizzi espliciti. L'assembly funziona per me, ma non per gli altri utenti del sistema ... – Hudson

Problemi correlati