2010-05-30 11 views
6

¿Hay alguna manera de que gcc genere %pc direcciones relativas de constantes? Incluso cuando la cadena aparece en el segmento de texto, arm-elf-gcc generará un puntero constante a los datos, cargará la dirección del puntero a través de una dirección relativa %pc y luego lo desreferenciará. Por una variedad de razones, necesito omitir el paso intermedio. A modo de ejemplo, esta función simple:Generando una dirección relativa% pc de datos constantes

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

genera (cuando se 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 

lo que habría esperado que genere algo más parecido a:

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

El código en cuestión debe ser parcialmente independiente de la posición, ya que se reubicará en la memoria en el momento de la carga, pero también se integrará con el código que no se compiló -fPIC, por lo que No hay una tabla de compensación global.

Mi trabajo actual en torno a es llamar a una función no-inline (que se hacerse a través de una dirección relativa %pc) para encontrar el desplazamiento desde la ubicación recopilada en una técnica similar a cómo funciona -fPIC código:

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

Sin embargo, esta técnica requiere que todos referencias de datos pueden fijar de forma manual, por lo que la función filename() en el ejemplo anterior serían:

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

Respuesta

1

Hmmm, tal vez tenga que compilarlo como -fPIC para obtener el PIC. O simplemente escríbalo en ensamblador, el ensamblador es mucho más fácil que la C que estás escribiendo.

 
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 

¿Recibirá la misma advertencia que recibo?

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

Sí, recibo la misma advertencia. El truco más fácil es añadir una nueva línea falsa y comentar: __atributo __ ((sección (". Text \ n #"))). No se puede compilar con -fPIC ya que hay funciones en ROM que están en direcciones explícitas. El montaje funciona para mí, pero no para los demás usuarios del sistema ... – Hudson

Cuestiones relacionadas