diff options
Diffstat (limited to 'tools/d2c/spec.c')
-rw-r--r-- | tools/d2c/spec.c | 543 |
1 files changed, 0 insertions, 543 deletions
diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c deleted file mode 100644 index 4bf4307..0000000 --- a/tools/d2c/spec.c +++ /dev/null @@ -1,543 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * spec.c - représentation complète d'un encodage - * - * Copyright (C) 2014-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "spec.h" - - -#include <malloc.h> -#include <regex.h> -#include <stdio.h> -#include <string.h> - - -#include "helpers.h" -#include "qckcall.h" - - - -/* Mémorisation d'un encodage complet */ -struct _encoding_spec -{ - char *prefix; /* Distinction principale */ - char *lprefix; /* Distinction en minuscules */ - unsigned int index; /* Distinction secondaire */ - - operands_format *format; /* Définition des opérandes */ - - coding_bits *bits; /* Encodage des bits associés */ - asm_syntax *syntax; /* Calligraphe d'assemblage */ - conv_list *conversions; /* Conversions des données */ - instr_hooks *hooks; /* Fonctions complémentaires */ - decoding_rules *rules; /* Règles supplémentaires */ - -}; - - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau suivi de l'encodage d'une instruction. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -encoding_spec *create_encoding_spec(void) -{ - encoding_spec *result; /* Définition vierge à renvoyer*/ - - result = (encoding_spec *)calloc(1, sizeof(encoding_spec)); - - result->format = create_operands_format(); - - result->bits = create_coding_bits(); - result->syntax = create_asm_syntax(); - result->conversions = create_conv_list(); - result->hooks = create_instr_hooks(); - result->rules = create_decoding_rules(); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à libérer de la mémoire. * -* * -* Description : Supprime de la mémoire un suivi d'encodage d'une instruction.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_encoding_spec(encoding_spec *spec) -{ - delete_operands_format(spec->format); - - delete_coding_bits(spec->bits); - delete_asm_syntax(spec->syntax); - delete_conv_list(spec->conversions); - delete_instr_hooks(spec->hooks); - delete_decoding_rules(spec->rules); - - free(spec); - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à compléter. * -* prefix = distinction principale entre les définitions. * -* index = distinction secondaire entre les définitions. * -* * -* Description : Définit le nom de code d'une spécification d'encodage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void define_encoding_spec_code_name(encoding_spec *spec, char *prefix, unsigned int index) -{ - spec->prefix = prefix; - spec->lprefix = make_string_lower(strdup(prefix)); - spec->index = index; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* prefix = distinction principale entre les définitions. * -* * -* Description : Indique si une spécification se range dans une catégorie. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool has_encoding_spec_prefix(const encoding_spec *spec, const char *prefix) -{ - bool result; /* Bilan à renvoyer */ - - if (spec->prefix == NULL && prefix == NULL) - result = true; - - else if (spec->prefix != NULL && prefix != NULL) - result = strcmp(spec->prefix, prefix) == 0; - - else - result = false; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit le gestionnaire des définitions d'opérandes. * -* * -* Retour : Structure assurant la définition des opérandes * -* * -* Remarques : - * -* * -******************************************************************************/ - -operands_format *get_format_in_encoding_spec(const encoding_spec *spec) -{ - return spec->format; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit le gestionnaire des bits d'un encodage d'instruction.* -* * -* Retour : Structure assurant le suivi des bits. * -* * -* Remarques : - * -* * -******************************************************************************/ - -coding_bits *get_bits_in_encoding_spec(const encoding_spec *spec) -{ - return spec->bits; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit l'indicateur des écritures correctes d'assembleur. * -* * -* Retour : Structure assurant la gestion des éléments de syntaxe. * -* * -* Remarques : - * -* * -******************************************************************************/ - -asm_syntax *get_syntax_in_encoding_spec(const encoding_spec *spec) -{ - return spec->syntax; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit la liste des fonctions de conversion. * -* * -* Retour : Structure assurant la gestion des fonctions de conversion. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_list *get_conversions_in_encoding_spec(const encoding_spec *spec) -{ - return spec->conversions; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit la liste des fonctions à lier à une instruction. * -* * -* Retour : Structure assurant la gestion des fonctions de conversion. * -* * -* Remarques : - * -* * -******************************************************************************/ - -instr_hooks *get_hooks_in_encoding_spec(const encoding_spec *spec) -{ - return spec->hooks; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification d'encodage à consulter. * -* * -* Description : Fournit un ensemble de règles supplémentaires éventuel. * -* * -* Retour : Structure assurant la gestion de ces règles. * -* * -* Remarques : - * -* * -******************************************************************************/ - -decoding_rules *get_rules_in_encoding_spec(const encoding_spec *spec) -{ - return spec->rules; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification servant de base à l'opération. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération. * -* subarch = sous-catégorie de cette même architecture. * -* ins = désignation première de l'instruction manipulée. * -* details = particularités de l'instruction. * -* wide = taille des mots manipulés (en bits). * -* pp = pré-processeur pour les échanges de chaînes. * -* * -* Description : Traduit en code une sous-fonction de désassemblage. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *arch, const char *subarch, const char *ins, const char *details, unsigned int wide, const pre_processor *pp) -{ - bool result; /* Bilan à retourner */ - bool bad_exit; /* Ajout d'une sortie d'échec ?*/ - char *keyword; /* Mot clef appelable en code */ - bool quick_exit; /* Inclusion de sortie rapide ?*/ - const char *new_ins; /* Nouvelle définition de nom */ - char *encoding_fc; /* Spécification d'encodage */ - char *cast; /* Conversion vers le format */ - - result = true; - - bad_exit = false; - - keyword = make_callable(ins, false); - - dprintf(fd, "\tGArchInstruction *%s_decode_%s%s_%s%u(uint%u_t _raw)\n", - arch, keyword, details, spec->lprefix, spec->index, wide); - - dprintf(fd, "\t{\n"); - - dprintf(fd, "\t\tGArchInstruction *instr;\n"); - - /* Déclaration des champs à retrouver */ - - result &= mark_syntax_items(spec->syntax, spec->bits, spec->conversions); - - result &= mark_decoding_rules(spec->rules, spec->bits, spec->conversions); - - result &= declare_used_bits_fields(spec->bits, fd, wide); - - result &= declare_used_intermediate_conversions(spec->conversions, fd, spec->bits, pp, wide); - - result &= declare_syntax_items(spec->syntax, fd, spec->bits, spec->conversions, wide); - - dprintf(fd, "\n"); - - result &= declare_hook_functions(spec->hooks, false, fd); - - /* Vérification que le décodage est possible */ - - result &= check_bits_correctness(spec->bits, fd); - - dprintf(fd, "\n"); - - /* Définition des champs bruts */ - - result &= define_used_bits_fields(spec->bits, fd); - - result &= define_used_intermediate_conversions(spec->conversions, fd, arch, spec->bits, pp, &bad_exit); - - /* Inclusion des éventuelles règles */ - - quick_exit = false; - - result &= write_decoding_rules(spec->rules, false, CAT_SEE, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - result &= write_decoding_rules(spec->rules, false, CAT_UNPREDICTABLE, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - /* Création de l'instruction en elle-même */ - - new_ins = get_new_keyword_from_syntax_items(spec->syntax); - - dprintf(fd, "\t\tinstr = g_%s_instruction_new(\"%s\");\n", arch, new_ins != NULL ? new_ins : ins); - - dprintf(fd, "\n"); - - /* Inscriptions des éventuelles fonctions ou propriété à lier */ - - result &= write_hook_functions(spec->hooks, false, fd); - - result &= write_decoding_rules(spec->rules, false, CAT_CHECKED_CALL, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - result &= write_decoding_rules(spec->rules, false, CAT_CALL, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - /* Création des opérandes */ - - result &= define_syntax_items(spec->syntax, fd, arch, spec->bits, spec->conversions, pp, &bad_exit); - - /* Conclusion de la procédure */ - - if (quick_exit) - { - dprintf(fd, "\t quick_exit:\n"); - dprintf(fd, "\n"); - } - - /* Encodage en dernier lieu */ - - asprintf(&encoding_fc, "g_%s_instruction_set_encoding", arch); - - cast = build_cast_if_needed(encoding_fc); - - dprintf(fd, "\t\t%s(%s(instr), \"%s\");\n", encoding_fc, cast, spec->prefix); - - free(cast); - - free(encoding_fc); - - /* Conclusion globale */ - - dprintf(fd, "\n"); - - dprintf(fd, "\t\treturn instr;\n"); - - dprintf(fd, "\n"); - - if (bad_exit) - { - dprintf(fd, "\t bad_exit:\n"); - dprintf(fd, "\n"); - - dprintf(fd, "\t\tg_object_unref(G_OBJECT(instr));\n"); - dprintf(fd, "\t\treturn NULL;\n"); - - dprintf(fd, "\n"); - - } - - dprintf(fd, "\t}\n"); - - dprintf(fd, "\n"); - - dprintf(fd, "\tif (result == NULL)\n"); - dprintf(fd, "\t\tresult = %s_decode_%s%s_%s%u(raw);\n", - arch, keyword, details, spec->lprefix, spec->index); - - dprintf(fd, "\n"); - - free(keyword); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification servant de base à l'opération. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération. * -* subarch = sous-catégorie de cette même architecture. * -* ins = désignation première de l'instruction manipulée. * -* sep = caractère de séparation avant les détails. * -* details = particularités de l'instruction. * -* pp = pré-processeur pour les échanges de chaînes. * -* prefix = préfixe pour le type de définitions d'opérandes. * -* * -* Description : Traduit en code une sous-fonction de désassemblage. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const char *arch, const char *subarch, const char *ins, char sep, const char *details, const pre_processor *pp, const char *prefix) -{ - bool result; /* Bilan à retourner */ - bool quick_exit; /* Inclusion de sortie rapide ?*/ - bool bad_exit; /* Ajout d'une sortie d'échec ?*/ - const char *new_ins; /* Nouvelle définition de nom */ - - result = true; - - /* Déclarations préalables */ - - dprintf(fd, "\tGArchInstruction *result; /* Instruction créée à renvoyer*/\n"); - dprintf(fd, "\tSourceEndian endian; /* Boutisme lié au binaire */\n"); - - dprintf(fd, "\n"); - - result &= declare_hook_functions(spec->hooks, true, fd); - - /* Création de l'instruction en elle-même */ - - new_ins = get_new_keyword_from_syntax_items(spec->syntax); - - if (new_ins != NULL) - dprintf(fd, "\tresult = g_%s_instruction_new(\"%s\");\n", arch, new_ins); - else - { - if (sep == '\0') - dprintf(fd, "\tresult = g_%s_instruction_new(\"%s\");\n", arch, ins); - else - dprintf(fd, "\tresult = g_%s_instruction_new(\"%s%c%s\");\n", arch, ins, sep, details); - } - - dprintf(fd, "\n"); - - /* Inscriptions des éventuelles fonctions ou propriété à lier */ - - result &= write_hook_functions(spec->hooks, true, fd); - - quick_exit = false; - - result &= write_decoding_rules(spec->rules, true, CAT_CHECKED_CALL, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - result &= write_decoding_rules(spec->rules, true, CAT_CALL, - fd, arch, subarch, spec->bits, spec->conversions, pp, &quick_exit); - - /* Création des opérandes */ - - dprintf(fd, "\tendian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc));\n"); - - dprintf(fd, "\n"); - - bad_exit = false; - - result &= define_operands_loading(spec->format, fd, arch, prefix, &bad_exit); - - /* Conclusion de la procédure */ - - dprintf(fd, "\treturn result;\n"); - - dprintf(fd, "\n"); - - if (quick_exit || bad_exit) - { - if (quick_exit) - dprintf(fd, " quick_exit:\n"); - - if (bad_exit) - dprintf(fd, " bad_exit:\n"); - - dprintf(fd, "\n"); - - dprintf(fd, "\tg_object_unref(G_OBJECT(result));\n"); - dprintf(fd, "\treturn NULL;\n"); - - dprintf(fd, "\n"); - - } - - return result; - -} |