2010-07-25 12 views
6

Estoy trabajando en un descompilador muy simple para la arquitectura MIPS y a medida que avanzo tengo que definir muchas reglas para el análisis de código, por ejemplo "si este código de operación es Lui y el próximo código de operación es addiu luego regresar var = valor "o 'si este código de operación es BNE y se está refiriendo a tratar antes de corriente - crear bucle definición en el análisis del árbol'. El problema: hay toneladas de tales reglas y no puedo encontrar una buena manera de definirlas. Intenté escribir funciones separadas para cada regla, definir buenas clases lógicas base OOP y ampliarlas para crear reglas, incluso intenté expresiones regulares en código desastroso (para mi sorpresa esto funciona mejor de lo esperado) pero no importa lo que haya intentado, mi código pronto se volvió grande y difícil de leer, sin importar qué tan bien esté intentando documentarlo y estructurarlo.Buscando una buena forma de definir reglas para descompilador, necesito consejo

Esto me lleva a la conclusión de que estoy tratando de resolver esta tarea usando herramientas incorrectas (sin mencionar que soy demasiado estúpido para una tarea tan compleja :)), pero no tengo una idea real de qué debería intentar. Actualmente tengo dos ideas no probadas, una está usando algún tipo de DSL (no tengo absolutamente ninguna experiencia en esto, entonces puedo estar totalmente equivocado), y otra es escribir algún tipo de herramientas binarias regexp-like para la coincidencia de código de operación.

Espero que alguien pueda señalarme en la dirección correcta, gracias.

+0

No creo que sea posible escribir un descompilador solo mirando patrones de instrucciones. El flujo de código y el análisis de datos son necesarios para construir correctamente bloques de código y expresiones. –

+2

La observación del patrón de código de operación AFAIK es la forma de obtener flujo de código, como en mi segundo ejemplo (usted encuentra un código de operación que se refiere a la dirección anterior = esto es un ciclo), pero tiene razón en que es solo uno de los pasos, Necesito calcular la condición para este ciclo, lo que significa que necesito ver el código antes y verificar las modificaciones de memoria \ registros. Entonces, este es un análisis de dos pasos: primer árbol de flujo de compilación, que calcular todo dentro. – Riz

+1

El método binario regex en realidad suena como una muy buena idea. La única otra cosa que puedo pensar sería escribir una interfaz MIPS para LLVM, y usar el backend de C para obtener código (aunque no tengo idea de lo legible que sería el código generado, por ejemplo, podría usar 'goto's para bucles y reciclar variables, etc.) – Zifre

Respuesta

2

Supongo que algunas de sus reglas son de muy bajo nivel, y es por eso que se vuelven inmanejables.

Reconocer lui seguido de addiu como una carga constante de 32 bits ciertamente parece muy razonable; pero tratar de derivar el flujo de control de las instrucciones de bifurcación en el nivel de código de operación individual parece bastante más sospechoso: creo que quieres trabajar con bloques básicos allí.

Cifuentes 'Reverse Compilation Techniques es una referencia que sigue apareciendo en discusiones de descompilación que he visto; a partir de un resumen bastante breve, parece que valdría la pena pasar algún tiempo leyendo en detalle para su proyecto.

Algunas de las cosas específicas de x86 no serán relevantes; en particular, el paso que traduce x86 a una representación intermedia de bajo nivel probablemente no sea necesario para MIPS (MIPS es básicamente solo una operación básica por opcode) - pero de lo contrario, gran parte del contenido parece que debería ser muy útil.

+0

Ay, esta es una fuente excelente de documentos que empeoran la lectura, no puedo expresar lo agradecido que estoy (por favor, no me pregunten cómo pude perderme esto :)) – Riz

Cuestiones relacionadas