create - makefile linux c
¿Cómo hacer que gcc genere solo código de máquina que pueda cargarse directamente en la memoria y ejecutarse? (2)
Desea conocer 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 compilar su (s) archivo (s) de origen y, generalmente, vincularlos 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 la ROM, donde le gustaría asegurarse de que está utilizando una biblioteca de tiempo de ejecución de C adecuada para su plataforma de destino, y es probable que necesite personalizar el archivo de script del enlazador así como proporcionar su propio tiempo de ejecución de C código de inicio.
Si su objetivo es obtener algo similar a un archivo .so, para cargarlo 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 .so archivo que se refiere 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 el manual de binutils . 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. Sugeriría 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.
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.
Idealmente, me gustaría la opción de hacer que el código sea reubicable (lo 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 los dos podría funcionar bien por sí mismo. .
Puede hacerlo, pero deberá 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). Quizás algo como esto:
gcc -o test test.c
objcopy -O binary test test.bin
Vea man objcopy
en su plataforma para más detalles.