2010-09-01 18 views
14

Me gustaría producir un archivo que pueda cargar en la memoria (por ejemplo, con mmap) y luego saltar al inicio de esa memoria para ejecutar el código.¿Cómo hacer que gcc genere solo código de máquina que pueda cargarse directamente en la memoria y ejecutarse?

Idealmente, me gustaría la opción de hacer el código reubicable (que podría ser ineficiente) o especificar una dirección explícita en la que el código espera cargarse (lo cual es un problema), pero cualquiera de ellos probablemente funcione bien por sí mismo.

+0

¿no es esto lo que es un archivo objeto? – aaronasterling

+1

no, como mínimo, los archivos de objeto contienen información sobre los símbolos que exportan (para el uso del vinculador) –

+2

¿Alguna razón específica por la que no desea utilizar una biblioteca dll/compartida en su lugar? Hay muchos * escollos con binarios en bruto. – snemarch

Respuesta

14

Puede hacerlo, pero tendrá que pasar por el formato de archivo de objeto. En particular, el comando objcopy puede transformar un archivo ejecutable en un archivo binario "plano" (dependiendo de su plataforma de destino). Tal vez algo como esto:

gcc -o test test.c 
objcopy -O binary test test.bin 

Ver man objcopy en su plataforma para obtener más detalles.

+0

+1, sabía que había algo que hacía esto .¿Sabes si necesito cargar esto en una dirección específica? –

+0

Sí, lo harás. Será la dirección a la que se le indicó al vinculador que vincule. Tenga en cuenta que normalmente no ve el archivo de control del enlazador, por lo que puede que no sepa dónde está ... – RBerteig

+0

¿Dónde encontraría el archivo de control? –

6

Quiere saber sobre la utilidad objcopy, que generalmente está disponible junto con GCC. Es un componente del paquete de herramientas binutils, cuyo miembro más visible es el enlazador, ld.

El proceso consiste en que compila sus archivos de origen y los vincula generalmente como de costumbre. Eso le da un ejecutable terminado en formato elf (u otro binario reubicable dependiente de la plataforma). A continuación, usa objcopy para transformar el ejecutable en una imagen binaria plana.

Esto es más útil para preparar código para ejecutar desde ROM, donde debería asegurarse de estar utilizando una biblioteca de tiempo de ejecución de C adecuada para su plataforma de destino, y probablemente necesite personalizar el archivo de script del enlazador así como proporcionar su propio código de inicio de C runtime.

Si su objetivo es obtener algo similar a un archivo .so, para cargar en un proceso existente, tenga en cuenta que parte del trabajo del cargador de la biblioteca compartida es terminar de vincular realmente para que los símbolos en el archivo .so que hace referencia a las direcciones en el ejecutable principal (u otros archivos .so) se resuelven en el momento de la carga. El uso de objcopy no hará eso, por lo que podría ser difícil que las funciones cargadas de esta manera utilicen correctamente su biblioteca C runtime existente y los objetos que mantiene, como archivos abiertos.

Independientemente de tus objetivos, vas a tener que tomar el control del enlazador para ubicar tu binario en una dirección conocida. Para hacer eso, necesitarás crear un script enlazador. La documentación para el lenguaje de script está en the binutils manual. Usted estará interesado principalmente en las secciones ".text *" y posiblemente en las secciones ".rodata *" si planea tener variables globales inicializadas. En realidad, organizar esa inicialización se deja como un ejercicio para el lector.

En general, esto es solo la punta de un iceberg muy grande. Sugiero pasar algún tiempo con una compilación de compilación cruzada para ver cómo se usan estas cosas en la práctica. Las comunidades AVR y MSP430 utilizan GCC, tienen participación activa y hardware de bajo costo (y, a menudo, de código abierto) para comenzar.

Cuestiones relacionadas