tarjeta - interfaces de red en linux
Vinculación de sÃmbolos a direcciones fijas en Linux (3)
¿Cómo se va a vincular (algunos) símbolos a direcciones fijas específicas usando GNU ld para que el binario se pueda ejecutar de forma normal en Linux (x86)? No habrá ningún acceso a esos símbolos, pero sus direcciones son importantes.
Por ejemplo, tendría la siguiente estructura:
struct FooBar {
Register32 field_1;
Register32 field_2;
//...
};
struct FooBar foobar;
Me gustaría vincular foobar
a la dirección 0x76543210, pero unir las bibliotecas estándar y el resto de la aplicación normalmente. La aplicación hará uso de la dirección de foobar, pero no hará referencia a la memoria (posiblemente inexistente) detrás de ella.
La razón de esta solicitud es que esta misma fuente se puede usar en dos plataformas: en la plataforma nativa, Register32
puede ser simplemente un volatile uint32_t
, pero en Linux Register32
es un objeto C ++ con el mismo tamaño que uint32_t
que define, por ejemplo, operator=
, que luego usará la dirección del objeto y enviará una solicitud a un marco de comunicación con esa dirección (y los datos) para realizar el acceso real en el hardware remoto. El enlazador garantizaría así que los campos Register32
de la estructura se refieran a las "direcciones" correctas.
La sugerencia de litb para usar --defsym symbol=address
funciona, pero es un poco engorrosa cuando tienes que --defsym symbol=address
algunas docenas de esas instancias. Sin embargo, --just-symbols=symbolfile
solo hace el truco. Me tomó un tiempo descubrir la sintaxis del symbolfile
, que es
symbolname1 = address;
symbolname2 = address;
...
Los espacios parecen ser necesarios, ya que de lo contrario ld
informa file format not recognized; treating as linker script
file format not recognized; treating as linker script
.
Pruébalo con
--defsym symbol=expression
Al igual que con esto:
gcc -Wl,--defsym,foobar=0x76543210 file.c
Y haz de foobar en tu código una declaración externa:
extern struct FooBar foobar;
Esto parece prometedor. Sin embargo, es una mala idea hacer tal cosa (a menos que realmente sepas lo que haces). ¿Por qué lo necesitas?
Te daré un buen consejo ... GNU LD puede hacer esto (suponiendo que las librerías del sistema no necesitan la dirección que deseas). Solo necesita construir su propia secuencia de comandos del enlazador en lugar de usar la autogenerada del compilador. Lea la página del manual para ld. Además, construir una secuencia de comandos del enlazador para una pieza compleja de software no es una tarea fácil cuando involucra también al GLIBC.