Compilador para el lenguaje de programación C
El compilador Tiny C (también conocido como TCC, tCc o TinyCC) es un compilador de C para procesadores x86 , X86-64 y ARM escrito inicialmente por Fabrice Bellard . Está diseñado para funcionar en ordenadores lentos con poco espacio en disco (por ejemplo, en discos de rescate ). La compatibilidad con el sistema operativo Windows se añadió en la versión 0.9.23 (17 de junio de 2005). TCC se distribuye bajo la Licencia Pública General Reducida de GNU .
TCC afirma implementar todo el estándar ANSI C (C89/C90), [2] gran parte del estándar ISO C99 , [3] y muchas extensiones GNU C, incluido el ensamblaje en línea .
Características
TCC tiene una serie de características que lo diferencian de otros compiladores de C actuales:
- Su pequeño tamaño de archivo (aproximadamente 100 KB para el ejecutable TCC x86) y el consumo de memoria permiten utilizarlo directamente desde un único disquete de 1,44 M , como por ejemplo un disquete de rescate.
- El objetivo de TCC es producir código nativo x86, x86-64 y ARM muy rápidamente; según Bellard, compila, ensambla y vincula aproximadamente nueve veces más rápido que GCC . [4] A partir de 2023, la rama de desarrollo "mob" también incluye soporte para RISC-V y TMS320C67xx (un chip DSP ).
- TCC tiene una serie de características del lenguaje específicas del compilador destinadas a mejorar su practicidad, como un verificador de memoria y límites opcional, para mejorar la estabilidad del código.
- TCC permite ejecutar programas automáticamente en tiempo de compilación mediante un modificador de línea de comandos. Esto permite ejecutar programas como un script de shell en sistemas tipo Unix que admitan la sintaxis de directivas de intérprete shebang .
Rendimiento del programa compilado
En general, la implementación de TCC enfatiza la pequeñez en lugar de resultados de rendimiento óptimo. TCC genera código en una sola pasada y no realiza la mayoría de las optimizaciones realizadas por otros compiladores. TCC compila cada instrucción por sí mismo y al final de cada instrucción los valores de registro se vuelven a escribir en la pila y deben volver a leerse incluso si la siguiente línea usa los valores de los registros (creando pares de guardado/carga extraños entre instrucciones). TCC usa solo algunos de los registros disponibles (por ejemplo, en x86 nunca usa ebx, esi o edi porque deben conservarse en las llamadas de función). [5]
TCC realiza algunas optimizaciones , como la propagación constante para todas las operaciones, las multiplicaciones y divisiones se optimizan para los cambios cuando corresponde y los operadores de comparación se optimizan especialmente (manteniendo una caché especial para los indicadores del procesador). También realiza una asignación de registros simple , que evita muchos pares de guardado/carga extraños dentro de una sola declaración .
A continuación se muestran dos ejemplos de referencia:
- Un algoritmo recursivo de Fibonacci en un portátil Intel Centrino de 1,8 GHz con 512 MB de RAM arroja una diferencia notable en los resultados entre el compilador Microsoft Visual C++ 13.10.3052 y TCC. Para calcular el número 49 de Fibonacci, un programa de MS Visual C++ tardó aproximadamente un 18 % más que el programa compilado con TCC. [ cita requerida ]
- En una prueba se compararon distintos compiladores de C, usándolos para compilar el compilador GNU C (GCC) y luego usando los compiladores resultantes para compilar GCC nuevamente. En comparación con GCC 3.4.2, un TCC modificado para compilar GCC pudo compilar el compilador diez veces más rápido, pero el archivo .exe resultante que produjo fue un 57% más grande y mucho más lento, ya que tardó 2,2 veces más en compilar GCC nuevamente. [6]
Los resultados fueron los siguientes: ejecutar cc1 (el compilador C de GCC) sobre sí mismo requirió 518 segundos cuando se compiló con GCC 3.4.2, 545 segundos con el compilador C de Microsoft y 1145 segundos con TCC. Para crear estos compiladores en primer lugar, GCC (3.4.2) tardó 744 segundos en compilar el compilador GCC, mientras que TCC tardó solo 73 segundos. El nivel de optimización en cada compilador fue -O1 o similar.
Usos
- TCCBOOT, [7] un hack donde TCC carga y arranca un kernel Linux desde el código fuente en aproximadamente 10 segundos. Es decir, es un " cargador de arranque " que lee el código fuente del kernel Linux desde el disco, escribe instrucciones ejecutables en la memoria y comienza a ejecutarlas. Esto requirió cambios en el proceso de compilación de Linux.
- Se ha utilizado TCC para compilar GCC, aunque se necesitaron varios parches para que esto funcione. [8]
- TCC se utilizó para demostrar una defensa contra el ataque de confianza . [9] También se utiliza en GNU Guix [10] en un intento de hacer que la distribución se pueda arrancar sin usar ningún binario. [11]
- Cinpy [12] es una biblioteca de Python que permite implementar funciones con C en módulos de Python. Las funciones se compilan con TCC en tiempo de ejecución. Los resultados se pueden llamar en Python a través de la biblioteca ctypes .
- Viene instalado en JavaScript Linux [13] (también de Bellard).
- Se ha utilizado como referencia para la versión compilada del programa fuente Super Micro-Max Chess. [14]
Historia
El TCC tiene su origen en el Obfuscated Tiny C Compiler (OTCC), [1] un programa que Bellard escribió para ganar el International Ofuscated C Code Contest (IOCCC) en 2001. Después de ese momento, Bellard expandió y desofuscó el programa para producir tcc. [1]
En algún momento antes del 4 de febrero de 2012, Fabrice Bellard actualizó la página web oficial del proyecto para informar que ya no estaba trabajando en TCC. [15]
Desde que Bellard se fue del proyecto, varias personas y grupos han distribuido parches o mantenido bifurcaciones de TCC para construir sobre TCC o solucionar problemas con este. Esto incluye la colección de parches no oficiales de tcc de Dave Dodge, [16] parches de Debian y kfreebsd [17] y los parches gcc de Grischka. [6] Grischka también creó un repositorio Git público para el proyecto [18] que contiene una rama mob [19] donde se agregaron numerosas contribuciones, incluyendo una compilación compartida, compiladores cruzados y compatibilidad con SELinux . El repositorio GIT de Grischka luego se convirtió en el repositorio oficial de TCC (vinculado a la página del proyecto Savannah de Fabrice Bellard [20] ).
Estado actual
A diciembre de 2017, tanto la lista de correo oficial de TCC [21] como el repositorio oficial de Git (vinculado a la página del proyecto Savannah de Fabrice Bellard [22] ) muestran un debate y desarrollo activos por parte de muchos desarrolladores y usuarios interesados. En diciembre de 2017, grischka anunció en la lista de correo que se había lanzado la versión 0.9.27 de TCC. [23]
Véase también
Referencias
- ^ abc Bellard, Fabrice. Compilador C diminuto ofuscado, propuesta ganadora del IOCCC 2001. https://bellard.org/otcc/ y en Internet Archive en https://web.archive.org/web/20130721162702/http://www.ioccc.org/2001/
- ^ Documentación de referencia del compilador Tiny C, consultada el 7 de agosto de 2008
- ^ Según la lista de tareas pendientes del proyecto, los tipos complejos son la única característica faltante de C99. Se agregaron matrices de longitud variable en TCC 0.9.26
- ^ "TCC: Tiny C Compiler". bellard.org . Consultado el 27 de marzo de 2023 .
- ^ Glockner, Daniel. Re: Tinycc-devel (sin tema), 8 de septiembre de 2006.
- ^ ab grischka, GCC por TCC (algunas correcciones), 29 de septiembre de 2005
- ^ "TCCBOOT: cargador de arranque TinyCC". bellard.org . Consultado el 27 de marzo de 2023 .
- ^ "tinycc-devel (hilo)". lists.gnu.org . Consultado el 27 de marzo de 2023 .
- ^ Wheeler, David A. Cómo contrarrestar la confianza depositada en los demás mediante una doble compilación diversa . ACSAC.
- ^ "Guix reduce aún más la semilla de Bootstrap al 25% — 2020 — Blog — GNU Guix".
- ^ "Compilaciones que se pueden ejecutar con arranque". bootstrappable.org . Consultado el 29 de marzo de 2023 .
- ^ "Cinpy". Archivado desde el original el 20 de noviembre de 2008. Consultado el 27 de marzo de 2023 .
- ^ "JSLinux". bellard.org . Consultado el 27 de marzo de 2023 .
- ^ "Super Micro Chess". SourceForge . Consultado el 27 de marzo de 2023 .
- ^ "TCC: Tiny C Compiler". 4 de febrero de 2012. Archivado desde el original el 4 de febrero de 2012. Consultado el 27 de marzo de 2023 .
- ^ "Parches no oficiales de tcc". www.dododge.net . Archivado desde el original el 31 de marzo de 2007 . Consultado el 27 de marzo de 2023 .
- ^ "Debian -- Detalles del paquete tcc en sid". packages.debian.org . Consultado el 27 de marzo de 2023 .
- ^ grischka, Alojamiento público de Git para tcc
- ^ grischka, rama de la mafia para tcc
- ^ "Tiny C Compiler - Resumen [Savannah]". savannah.nongnu.org . Consultado el 27 de marzo de 2023 .
- ^ "Archivos de tinycc-devel". lists.gnu.org . Consultado el 27 de marzo de 2023 .
- ^ "Alojamiento público de Git - tinycc.git/summary". repo.or.cz . Consultado el 27 de marzo de 2023 .
- ^ "[Tinycc-devel] La versión 0.9.27 de TCC ya está disponible". lists.nongnu.org . Consultado el 27 de marzo de 2023 .
Enlaces externos