2012-09-19 5 views
7

Estoy interesado en desarrollar algún tipo de depurador ring0 kernel-mode para x86-64 en Common Lisp que se cargaría como un módulo kernel de Linux y como prefiero Common Lisp a C en programación general, me pregunto cómo diferentes Common Lisp las implementaciones se adaptarían a este tipo de tarea de programación.¿Es viable escribir un depurador en modo kernel de Linux para Intel x86-64 en Common Lisp, y con qué implementación Common Lisp [s]?

El depurador utilizaría alguna biblioteca externa de desmontaje, como udis86 a través de FFI. Me parece que es más fácil escribir módulos kernel en C ya que necesitan contener las funciones C int init_module(void) y void cleanup_module(void) (The Linux Kernel Module Programming Guide), por lo que el código del módulo kernel-land llamaría al código Common Lisp desde C usando CFFI. La idea sería crear un depurador ring0 para Linux de 64 bits inspirado en la idea de Rasta Ring 0 Debugger, que solo está disponible para Linux de 32 bits y requiere teclado PS/2. Creo que la parte más desafiante sería el código del depurador real con puntos de interrupción de hardware y software y el manejo de dispositivos de entrada de video, teclado o USB de bajo nivel. El ensamblaje en línea ayudaría mucho en eso, me parece que en SBCL el ensamblaje en línea se puede implementar usando VOP (SBCL Internals: VOP) (SBCL Internals: Adding VOPs), y este IRC log menciona que ACL (Allegro Common Lisp), CCL (Clozure Common Lisp) y CormanCL tienen LAP (Lisp Programas de ensamblaje). Tanto ACL como CormanCL son propietarios y, por lo tanto, descartados, pero CCL (Clozure Common Lisp) podría ser una opción. La capacidad de construir ejecutables independientes es un requisito también; El SBCL que estoy usando actualmente lo tiene, pero como son imágenes Lisp completas, su tamaño es bastante grande.

Mi pregunta es: es viable para crear un depurador de modo de núcleo ring0 para Intel x86-64 en Common Lisp, con código de bajo nivel implementado en C y/o montaje, y si lo es, lo cual Común Las implementaciones de Lisp para Linux de 64 bits son las mejores para este tipo de empeño, y ¿cuáles son los pros y los contras si hay más de una implementación de Common Lisp adecuada? El esquema también puede ser una opción posible, si ofrece algunos beneficios sobre Common Lisp. Soy consciente de que la gran mayoría de los módulos kernel están escritos en C, y sé que C y x86 se ensamblan lo suficientemente bien como para poder escribir el código de bajo nivel requerido en C y/o ensamblaje. Esto no es un intento de portar kernel de Linux a Lisp (ver: https://stackoverflow.com/questions/1848029/why-not-port-linux-kernel-to-common-lisp), sino un plan para escribir en Common Lisp un módulo de kernel de Linux que se usaría como un ring0 depurador.

+3

Probablemente se podría ejecutar la parte Lisp en un proceso de usuario y simplemente comunicarse con él desde el depurador.. debería ser mucho más fácil de lograr. –

+0

@AlexeyFrunze que podría ser una buena idea, probablemente, hace las cosas mucho más fáciles. – nrz

+0

una downvote, una upvote. me gustaría saber por qué un downvote? – nrz

Respuesta

2

No, no sería factible implementar un módulo kernel en CL por la razón obvia de que solo para hacerlo funcionar tendrá que hacer muchos hacks y puede terminar perdiendo todos los beneficios que el lenguaje lisp brinda y su el código lisp se verá como el código C en S-expressions.

Escriba su módulo kernel para exportar cualquier funcionalidad/datos que necesite del kernel y luego use las operaciones ioctl o de lectura/escritura, cualquier programa en modo usuario puede comunicarse con el módulo.

No estoy seguro de si hay algún módulo kernel que sea lo suficientemente genérico como para implementar Lisp (o puede ser su subconjunto) de forma que escriba código en Lisp y este módulo genérico lea el código lisp y lo ejecute como subcomponente , básicamente Kernel -> Generic lisp module -> tu código de lisp (que se ejecutará en kernel).

+2

+1 Implementar el código del módulo kernel en C y el código de usuario en Common Lisp sería una buena alternativa. Sin embargo, descubrí que [ECL (Common-Lisp incrustado)] (http://ecls.sourceforge.net/) es compatible con C en línea y compila a ejecutables independientes, y estos son los dos requisitos más importantes aquí para cualquier implementación de CL, entonces intento ECL con C en línea primero. – nrz

+0

Después de unos días de piratear el código del módulo del kernel, parece que incluir Common Lisp (ECL) sería una tarea difícil. En el código del kernel solo es posible un subconjunto de C, por lo que incluso si ECL produce el código C (que es algo muy bueno), ese código C probablemente no sea un código válido del kernel C. Editando el código C producido por ECL ej. con regex crearía otra capa de programación, antes de que ese código pudiera compilarse con 'gcc'. Por lo tanto, insisten en '.lisp' ->' ecl' -> '.c' ->' gcc' -> '.o' ->' ld' -> '.ko' pipeline sería, por ejemplo. '.lisp' ->' ecl' -> '.c' ->' vim' o 'perl' ->' .c' -> 'gcc' ->' .o' -> 'ld' ->'. ko' tubería. – nrz

+0

Me parece que la escritura de código del módulo del kernel en ECL podría ser posible con algunos cambios (¿importantes?) En ECL, por lo que podría emitir opcionalmente el código C válido para los módulos del kernel. Es mucho más fácil escribir el módulo kernel en C y el código de usuario en ECL, y hacer la comunicación entre ellos a través de '/ dev' y/o puertos. Eso es posible ya, y ese es el camino a seguir para mí. – nrz

3

Es posible que desee echar un vistazo a la charla de lispvan del 2 de febrero de 2008 "Haciendo cosas malas con Common Lisp" por Brad Beveridge sobre cómo trabajar con un controlador del sistema de archivos de SBCL.

Talk description & files

En él se menciona:

"A C/C++ depurador escrito en CL ??

totalmente castillos en el aire en este momento

Pero, lo genial que sería?

No es que gran parte de un tramo, sólo tiene que ser capaz de escribir en la memoria donde se encuentra la biblioteca para insertar puntos de quiebre & entonces señales de trampa en el lado Lisp

podría usar trucos sucios para reemplazar las funciones de C con llamadas a funciones Lisp

Aparte de algunos detalles, que probablemente no es tan difícil - ciertamente nada “nuevo”

el truco sucio implicaría sobrescribir el código C con otro salto (rama sin enlace) en una devolución de llamada Lisp . Cuando el código Lisp retorna, puede saltar directamente a la función de llamada original a través del registro de enlace.

Además, estoy totalmente pasando por alto la verdadera dificultad para escribir un depurador - sería mucho tiempo "

+1

+1 La tarea parece ser posible, pero requiere bastante tiempo, incluso si la descompilación es mucho más difícil que el desmontaje. Mi plan sería crear un depurador de ensamblaje regular en el estilo de SoftIce, con búsquedas de memoria regex de Vim/Perl. Parece que es posible un depurador en modo kernel escrito en gran parte en Common Lisp, especialmente dado el hecho de que [ECL (Embeddable Common-Lisp)] (http://ecls.sourceforge.net/) admite C en línea con '(ffi: cline c-code *) 'y' (ffi: c-inline (lisp-value *)) 'formas especiales, así que creo que ECL sería una de las mejores implementaciones Common Lisp para una tarea como esta. – nrz