From f7add23a8bcb6d4e0c594ce13fe224829759041c Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 15 Nov 2014 00:34:32 +0000 Subject: Given the d2c compiler its own directory. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@420 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 63 ++ configure.ac | 1 + src/arch/arm/v7/opdefs/Makefile.am | 4 +- tools/Makefile.am | 32 +- tools/bits.c | 363 -------- tools/bits.h | 87 -- tools/coder.c | 650 -------------- tools/coder.h | 125 --- tools/conv.c | 1640 ------------------------------------ tools/conv.h | 160 ---- tools/d2c.mk | 31 - tools/d2c/Makefile.am | 32 + tools/d2c/bits.c | 363 ++++++++ tools/d2c/bits.h | 87 ++ tools/d2c/coder.c | 650 ++++++++++++++ tools/d2c/coder.h | 125 +++ tools/d2c/conv.c | 1640 ++++++++++++++++++++++++++++++++++++ tools/d2c/conv.h | 160 ++++ tools/d2c/d2c.mk | 31 + tools/d2c/d2c_gram.y | 442 ++++++++++ tools/d2c/d2c_tok.l | 187 ++++ tools/d2c/helpers.c | 144 ++++ tools/d2c/helpers.h | 47 ++ tools/d2c/macros.c | 167 ++++ tools/d2c/macros.h | 30 + tools/d2c/pproc.c | 214 +++++ tools/d2c/pproc.h | 67 ++ tools/d2c/rules.c | 439 ++++++++++ tools/d2c/rules.h | 91 ++ tools/d2c/spec.c | 349 ++++++++ tools/d2c/spec.h | 72 ++ tools/d2c/syntax.c | 321 +++++++ tools/d2c/syntax.h | 61 ++ tools/d2c_gram.y | 442 ---------- tools/d2c_tok.l | 187 ---- tools/helpers.c | 144 ---- tools/helpers.h | 47 -- tools/macros.c | 167 ---- tools/macros.h | 30 - tools/pproc.c | 214 ----- tools/pproc.h | 67 -- tools/rules.c | 439 ---------- tools/rules.h | 91 -- tools/spec.c | 349 -------- tools/spec.h | 72 -- tools/syntax.c | 321 ------- tools/syntax.h | 61 -- 47 files changed, 5786 insertions(+), 5720 deletions(-) delete mode 100644 tools/bits.c delete mode 100644 tools/bits.h delete mode 100644 tools/coder.c delete mode 100644 tools/coder.h delete mode 100644 tools/conv.c delete mode 100644 tools/conv.h delete mode 100644 tools/d2c.mk create mode 100644 tools/d2c/Makefile.am create mode 100644 tools/d2c/bits.c create mode 100644 tools/d2c/bits.h create mode 100644 tools/d2c/coder.c create mode 100644 tools/d2c/coder.h create mode 100644 tools/d2c/conv.c create mode 100644 tools/d2c/conv.h create mode 100644 tools/d2c/d2c.mk create mode 100644 tools/d2c/d2c_gram.y create mode 100644 tools/d2c/d2c_tok.l create mode 100644 tools/d2c/helpers.c create mode 100644 tools/d2c/helpers.h create mode 100644 tools/d2c/macros.c create mode 100644 tools/d2c/macros.h create mode 100644 tools/d2c/pproc.c create mode 100644 tools/d2c/pproc.h create mode 100644 tools/d2c/rules.c create mode 100644 tools/d2c/rules.h create mode 100644 tools/d2c/spec.c create mode 100644 tools/d2c/spec.h create mode 100644 tools/d2c/syntax.c create mode 100644 tools/d2c/syntax.h delete mode 100644 tools/d2c_gram.y delete mode 100644 tools/d2c_tok.l delete mode 100644 tools/helpers.c delete mode 100644 tools/helpers.h delete mode 100644 tools/macros.c delete mode 100644 tools/macros.h delete mode 100644 tools/pproc.c delete mode 100644 tools/pproc.h delete mode 100644 tools/rules.c delete mode 100644 tools/rules.h delete mode 100644 tools/spec.c delete mode 100644 tools/spec.h delete mode 100644 tools/syntax.c delete mode 100644 tools/syntax.h diff --git a/ChangeLog b/ChangeLog index 2310c44..b136567 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,66 @@ +14-11-15 Cyrille Bagard + + * configure.ac: + Add the new Makefile from the 'tools/d2c' directory. + + * src/arch/arm/v7/opdefs/Makefile.am: + Update paths. + + * tools/bits.c: + * tools/bits.h: + * tools/coder.c: + * tools/coder.h: + * tools/conv.c: + * tools/conv.h: + Moved entries: see the new 'd2c' directory. + + * tools/d2c + * tools/d2c/Makefile.am + * tools/d2c/bits.c + * tools/d2c/bits.h + * tools/d2c/coder.c + * tools/d2c/coder.h + * tools/d2c/conv.c + * tools/d2c/conv.h + * tools/d2c/d2c.mk + * tools/d2c/d2c_gram.y + * tools/d2c/d2c_tok.l + * tools/d2c/helpers.c + * tools/d2c/helpers.h + * tools/d2c/macros.c + * tools/d2c/macros.h + * tools/d2c/pproc.c + * tools/d2c/pproc.h + * tools/d2c/rules.c + * tools/d2c/rules.h + * tools/d2c/spec.c + * tools/d2c/spec.h + * tools/d2c/syntax.c + * tools/d2c/syntax.h + New entries: give the d2c compiler its own directory. + + * tools/d2c_gram.y: + * tools/d2c.mk: + * tools/d2c_tok.l: + * tools/helpers.c: + * tools/helpers.h: + * tools/macros.c: + * tools/macros.h: + Moved entries: see the new 'd2c' directory. + + * tools/Makefile.am: + Create a SUBDIR item, with content equal to 'd2c'. + + * tools/pproc.c: + * tools/pproc.h: + * tools/rules.c: + * tools/rules.h: + * tools/spec.c: + * tools/spec.h: + * tools/syntax.c: + * tools/syntax.h: + Moved entries: see the new 'd2c' directory. + 14-11-14 Cyrille Bagard * src/arch/arm/v7/arm.c: diff --git a/configure.ac b/configure.ac index 85ab307..f60f801 100644 --- a/configure.ac +++ b/configure.ac @@ -351,6 +351,7 @@ AC_CONFIG_FILES([Makefile src/plugins/Makefile src/plugins/overjump/Makefile tools/Makefile + tools/d2c/Makefile themes/Makefile]) AC_OUTPUT diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 9aa6a82..d576782 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -1,8 +1,8 @@ -include ../../../../../tools/d2c.mk +include ../../../../../tools/d2c/d2c.mk -D2C_BIN = ../../../../../tools/d2c +D2C_BIN = ../../../../../tools/d2c/d2c D2C_OUTDIR = $(PWD)/.. diff --git a/tools/Makefile.am b/tools/Makefile.am index d0fdbe8..ed53403 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,32 +1,2 @@ -BUILT_SOURCES = d2c-d2c_gram.h - -AM_YFLAGS = -d - -bin_PROGRAMS = d2c - - -d2c_SOURCES = \ - bits.h bits.c \ - coder.h coder.c \ - conv.h conv.c \ - d2c_tok.l \ - d2c_gram.y \ - helpers.h helpers.c \ - pproc.h pproc.c \ - rules.h rules.c \ - spec.h spec.c \ - syntax.h syntax.c - -d2c_YFLAGS = -v -d -p d2c_ -o y.tab.c - -d2c_LFLAGS = -P d2c_ --header-file=d2c_tok.h -o lex.yy.c - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) - - -# Automake fait les choses à moitié -CLEANFILES = d2c_gram.h d2c_gram.c d2c-d2c_tok.c +SUBDIRS = d2c diff --git a/tools/bits.c b/tools/bits.c deleted file mode 100644 index 32c3fd9..0000000 --- a/tools/bits.c +++ /dev/null @@ -1,363 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * bits.c - compréhension et manipulation des champs de bits - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "bits.h" - - -#include -#include -#include -#include -#include - - -#include "helpers.h" - - - - - -/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ - - -/* Elément d'un mot décodé */ -struct _raw_bitfield -{ - char *name; /* Désignation humaine */ - unsigned int start; /* Position de départ */ - unsigned int length; /* Taille du champ */ - - bool used; /* Champ défini & utilisé */ - -}; - - - - -/* Représentation de l'ensemble des bits de codage */ -struct _coding_bits -{ - raw_bitfield *fields; /* Champs de bits détectés */ - size_t bf_count; /* Nombre de ces champs */ - uint64_t bits; /* Bits invariables */ - uint64_t mask; /* Emplacement de ces bits */ - unsigned int curpos; /* Position pendant l'analyse */ - -}; - - - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : field = champ de bits à consulter. * -* * -* Description : Indique le nombre de bits utilisés par le champ. * -* * -* Retour : Nombre de bits considérés. * -* * -* Remarques : - * -* * -******************************************************************************/ - -unsigned int get_raw_bitfield_length(const raw_bitfield *field) -{ - return field->length; - -} - - -/****************************************************************************** -* * -* Paramètres : field = champ de bits à traiter. * -* * -* Description : Marque un champ de bits comme étant utile. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void mark_raw_bitfield_as_used(raw_bitfield *field) -{ - field->used = true; - -} - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau gestionnaire des bits d'encodage brut. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -coding_bits *create_coding_bits(void) -{ - coding_bits *result; /* Définition vierge à renvoyer*/ - - result = (coding_bits *)calloc(1, sizeof(coding_bits)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire d'un ensemble de bits à libérer. * -* * -* Description : Supprime de la mémoire un gestionnaire de bits d'encodage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_coding_bits(coding_bits *bits) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < bits->bf_count; i++) - free(bits->fields[i].name); - - if (bits->fields != NULL) - free(bits->fields); - - free(bits); - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * -* name = désignation humaine du champ remarqué. * -* length = taille du champ à mémoriser. * -* * -* Description : Note la présence d'un champ remarquable dans une définition. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_named_field_in_bits(coding_bits *bits, char *name, unsigned int length) -{ - raw_bitfield *field; /* Nouveau champ à constituer */ - - assert((bits->curpos + length) < 64); - - bits->fields = (raw_bitfield *)realloc(bits->fields, - ++bits->bf_count * sizeof(raw_bitfield)); - - field = &bits->fields[bits->bf_count - 1]; - - field->name = make_string_lower(name); - field->start = bits->curpos; - field->length = length; - - bits->curpos += length; - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * -* val = valeur du bit à prendre en compte. * -* * -* Description : Note la présence d'un bit invariable dans une définition. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_bit_in_bits(coding_bits *bits, int val) -{ - assert(bits->curpos < 64); - - bits->bits |= (val ? 1 : 0) << bits->curpos; - bits->mask |= 1 << bits->curpos; - - bits->curpos++; - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * -* * -* Description : Indique le nombre de bits traités. * -* * -* Retour : Quantité, positive ou nulle. * -* * -* Remarques : - * -* * -******************************************************************************/ - -unsigned int count_coded_bits(const coding_bits *bits) -{ - return bits->curpos; - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire d'encodage brut à consulter. * -* name = désignation humaine du champ à retrouver. * -* * -* Description : Recherche un champ donné dans un ensemble de champs de bits. * -* * -* Retour : Structure associée au champ trouvé ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -raw_bitfield *find_named_field_in_bits(const coding_bits *bits, const char *name) -{ - raw_bitfield *result; /* Champ de bits à retourner */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - for (i = 0; i < bits->bf_count && result == NULL; i++) - if (strcmp(bits->fields[i].name, name) == 0) - result = &bits->fields[i]; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification servant de base à l'opération. * -* fd = descripteur d'un flux ouvert en écriture. * -* wide = taille des mots manipulés (en bits). * -* * -* Description : Déclare les variables C associées aux champs de bits. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool declare_used_bits_fields(const coding_bits *bits, int fd, unsigned int wide) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < bits->bf_count; i++) - if (bits->fields[i].used) - dprintf(fd, "\t\tuint%u_t raw_%s;\n", wide, bits->fields[i].name); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification servant de base à l'opération. * -* fd = descripteur d'un flux ouvert en écriture. * -* * -* Description : Vérifie que les bits fixes correspondent au masque attendu. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool check_bits_correctness(const coding_bits *bits, int fd) -{ - dprintf(fd, "\t\tif ((raw & 0x%" PRIx64 ") != 0x%" PRIx64 ") return NULL;\n", bits->mask, bits->bits); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : spec = spécification servant de base à l'opération. * -* fd = descripteur d'un flux ouvert en écriture. * -* * -* Description : Définit les variables C associées aux champs de bits. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool define_used_bits_fields(const coding_bits *bits, int fd) -{ - size_t i; /* Boucle de parcours */ - raw_bitfield *rf; /* Accès confortable à un champ*/ - - for (i = 0; i < bits->bf_count; i++) - { - rf = &bits->fields[i]; - if (!rf->used) continue; - - dprintf(fd, "\t\traw_%s = (_raw >> %u) & 0x%llx;\n", rf->name, rf->start, (1ull << rf->length) - 1); - - } - - return true; - -} diff --git a/tools/bits.h b/tools/bits.h deleted file mode 100644 index aa4b7aa..0000000 --- a/tools/bits.h +++ /dev/null @@ -1,87 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * bits.h - prototypes pour la compréhension et la manipulation des champs de bits - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_BITS_H -#define _TOOLS_BITS_H - - -#include - - - - -/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ - - -/* Elément d'un mot décodé */ -typedef struct _raw_bitfield raw_bitfield; - - - -/* Indique le nombre de bits utilisés par le champ. */ -unsigned int get_raw_bitfield_length(const raw_bitfield *); - -/* Marque un champ de bits comme étant utile. */ -void mark_raw_bitfield_as_used(raw_bitfield *); - - - - - -/* Représentation de l'ensemble des bits de codage */ -typedef struct _coding_bits coding_bits; - - - -/* Crée un nouveau gestionnaire des bits d'encodage brut. */ -coding_bits *create_coding_bits(void); - -/* Supprime de la mémoire un gestionnaire de bits d'encodage. */ -void delete_coding_bits(coding_bits *); - - - -/* Note la présence d'un champ remarquable dans une définition. */ -void register_named_field_in_bits(coding_bits *, char *, unsigned int); - -/* Note la présence d'un bit invariable dans une définition. */ -void register_bit_in_bits(coding_bits *, int); - -/* Indique le nombre de bits traités. */ -unsigned int count_coded_bits(const coding_bits *); - -/* Recherche un champ donné dans un ensemble de champs de bits. */ -raw_bitfield *find_named_field_in_bits(const coding_bits *, const char *); - -/* Déclare les variables C associées aux champs de bits. */ -bool declare_used_bits_fields(const coding_bits *, int, unsigned int); - -/* Vérifie que les bits fixes correspondent au masque attendu. */ -bool check_bits_correctness(const coding_bits *, int); - -/* Définit les variables C associées aux champs de bits. */ -bool define_used_bits_fields(const coding_bits *, int); - - - -#endif /* _TOOLS_BITS_H */ diff --git a/tools/coder.c b/tools/coder.c deleted file mode 100644 index 5856d80..0000000 --- a/tools/coder.c +++ /dev/null @@ -1,650 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * coder.c - lecture automatisée des spécifications d'architecture - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "coder.h" - - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "helpers.h" - - - -/* -------------------------- CONSTRUCTION SELON COMMANDES -------------------------- */ - - - - - -/* Suivi des constructions */ -struct _rented_coder -{ - const char *outdir; /* Lieu d'enregistrement */ - const char *arch; /* Architecture à traiter */ - const char *header; /* En-tête pour les en-têtes */ - - pre_processor *pp; /* Pré-processeur avec macros */ - - char *copyright; /* Récupération des droits */ - char *ins; /* Désignation humaine */ - char *details; /* Eventuels compléments */ - - encoding_spec **specs; /* Définitions déjà en place */ - size_t specs_count; /* Nombre de ces définitions */ - encoding_spec *cur_spec; /* Définition courante */ - -}; - - - - -/* --------------------------- REPRESENTATION D'ENCODAGES --------------------------- */ - - - - - -/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ - - -/* Elément d'un mot décodé */ -typedef struct _dec_bitfield -{ - char *name; /* Désignation humaine */ - unsigned int start; /* Position de départ */ - unsigned int length; /* Taille du champ */ - -} dec_bitfield; - - - - - - - -/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ - - -/* Fonction de conversion */ -typedef struct _conv_func -{ - char *dest; /* Variable de destination */ - char *func; /* Fonction de conversion */ - char *arg; /* Argument de cette fonction */ - -} conv_func; - - - -/* --------------------------- GENERATIONS DE CODE SOURCE --------------------------- */ - - -/* Ouvre un fichier en écriture pour y placer du code. */ -static int create_code_file(const rented_coder *, const char *, const char *, const char *, char, bool *); - -/* Ecrit une partie des fonctions issues des spécifications. */ -static bool dump_all_matching_specs_in_coder(const rented_coder *, const string_exch *, int, int); - - - -/* ---------------------------------------------------------------------------------- */ -/* CONSTRUCTION SELON COMMANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Débute la définition d'une fonction de désassemblage. * -* * -* Retour : Gestionnaire mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -rented_coder *create_coder(void) -{ - rented_coder *result; /* Structure à renvoyer */ - - result = (rented_coder *)calloc(1, sizeof(rented_coder)); - - result->pp = create_pre_processor(); - - result->cur_spec = create_encoding_spec(); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* * -* Description : Supprime le codeur de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_coder(rented_coder *coder) -{ - size_t i; /* Boucle de parcours */ - - delete_pre_processor(coder->pp); - - if (coder->ins != NULL) - free(coder->ins); - - if (coder->details != NULL) - free(coder->details); - - for (i = 0; i < coder->specs_count; i++) - delete_encoding_spec(coder->specs[i]); - - if (coder->specs != NULL) - free(coder->specs); - - delete_encoding_spec(coder->cur_spec); - - free(coder); - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* * -* Description : Détermine si les propriétés de base d'un codeur sont là. * -* * -* Retour : Bilan de l'état opérationnel. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool do_basic_checks_with_coder(const rented_coder *coder) -{ - return (coder->outdir != NULL && coder->arch != NULL && coder->header != NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* outdir = répertoire de génération des fichiers. * -* * -* Description : Spécifie le répertoire de base pour les sorties de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void set_coder_output_directory(rented_coder *coder, const char *outdir) -{ - coder->outdir = outdir; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* arch = désignation pour le code de l'architecture lue. * -* * -* Description : Détermine l'architecture visée par les traitements. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void set_coder_arch(rented_coder *coder, const char *arch) -{ - coder->arch = arch; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* header = base des définitions de protection d'en-têtes. * -* * -* Description : Définit la base des protections des fichiers d'en-tête. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void set_coder_header_base(rented_coder *coder, const char *header) -{ - coder->header = header; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* * -* Description : Fournit le pré-processeur du compilateur. * -* * -* Retour : Pré-processeur à manipuler. * -* * -* Remarques : - * -* * -******************************************************************************/ - -pre_processor *get_coder_pre_proc(const rented_coder *coder) -{ - return coder->pp; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain.* -* copy = droits de copie en anglais. * -* ins = désignation humaine de l'instruction. * -* details = compléments d'informations éventuels ou NULL. * -* * -* Description : Enregistre les contours d'une instruction d'assemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void save_notes_for_coder(rented_coder *coder, char *copy, char *ins, const char *details) -{ - coder->copyright = copy; - coder->ins = make_string_lower(ins); - coder->details = (details != NULL ? make_callable(details, true) : strdup("")); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* REPRESENTATION D'ENCODAGES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* * -* Description : Fournit un lien vers les spécifications courantes. * -* * -* Retour : Spécification en cours d'édition. * -* * -* Remarques : - * -* * -******************************************************************************/ - -encoding_spec *get_current_encoding_spec(const rented_coder *coder) -{ - return coder->cur_spec; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* prefix = distinction principale entre les définitions. * -* index = distinction secondaire entre les définitions. * -* * -* Description : Enregistre une définition supplémentaire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void push_encoding_spec(rented_coder *coder, char *prefix, unsigned int index) -{ - encoding_spec *spec; /* Définition à compléter */ - - spec = coder->cur_spec; - - define_encoding_spec_code_name(spec, prefix, index); - - coder->specs = (encoding_spec **)realloc(coder->specs, ++coder->specs_count * sizeof(encoding_spec *)); - coder->specs[coder->specs_count - 1] = spec; - - coder->cur_spec = create_encoding_spec(); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* GENERATIONS DE CODE SOURCE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* dir = répertoire final de destination. * -* prefix = type d'encodage à répercuter sur le nom de fichier. * -* name = nom brut du fichier à ouvrir. * -* ext = extension à donner au fichier à ouvrir. * -* exist = indique si le fichier était présent avant. [OUT] * -* * -* Description : Ouvre un fichier en écriture pour y placer du code. * -* * -* Retour : Descripteur du fichier ouvert ou -1 en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int create_code_file(const rented_coder *coder, const char *dir, const char *prefix, const char *name, char ext, bool *exist) -{ - int result; /* Descripteur à retourner */ - size_t length; /* Taille du nom de fichier */ - char *pathname; /* Chemin d'accès à constituer */ - - length = strlen(coder->outdir) + 1 + strlen(dir) + 1 + strlen(prefix) + strlen(name) + 3; - pathname = (char *)calloc(length, sizeof(char)); - snprintf(pathname, length, "%s/%s/%s%s.%c", coder->outdir, dir, prefix, name, ext); - - *exist = (access(pathname, W_OK) == 0); - - result = open(pathname, O_WRONLY | O_CREAT | O_APPEND, 0644); - if (result == -1) perror("open()"); - - free(pathname); - - if (!*exist && result != -1) - { - dprintf(result, "\n"); - - dprintf(result, "/* Chrysalide - Outil d'analyse de fichiers binaires\n"); - dprintf(result, " * %s%s.%c - traduction d'instructions ARMv7\n", prefix, name, ext); - dprintf(result, " *\n"); - dprintf(result, " * %s\n", coder->copyright); - dprintf(result, " *\n"); - dprintf(result, " * This file is part of Chrysalide.\n"); - dprintf(result, " *\n"); - dprintf(result, " * Chrysalide is free software; you can redistribute it and/or modify\n"); - dprintf(result, " * it under the terms of the GNU General Public License as published by\n"); - dprintf(result, " * the Free Software Foundation; either version 3 of the License, or\n"); - dprintf(result, " * (at your option) any later version.\n"); - dprintf(result, " *\n"); - dprintf(result, " * Chrysalide is distributed in the hope that it will be useful,\n"); - dprintf(result, " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); - dprintf(result, " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); - dprintf(result, " * GNU General Public License for more details.\n"); - dprintf(result, " *\n"); - dprintf(result, " * You should have received a copy of the GNU General Public License\n"); - dprintf(result, " * along with Foobar. If not, see .\n"); - dprintf(result, " */\n"); - - dprintf(result, "\n"); - dprintf(result, "\n"); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain.* -* * -* Description : Débute la définition des fonctions issues des spécifications.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool dump_all_routines_using_coder(const rented_coder *coder) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - const string_exch *encoding; /* Type d'encodage visé */ - bool exist; /* Présence du fichier visé ? */ - int header_fd; /* Fichier de déclarations */ - char *dash; /* Présence d'un tiret ? */ - char *filename; /* Nom de fichier commun */ - int code_fd; /* Fichier de définitions */ - - result = true; - - for (i = 0; i < count_encodings(coder->pp) && result; i++) - { - encoding = find_encoding(coder->pp, i); - - /* Fichier de déclarations */ - - header_fd = create_code_file(coder, "opcodes", encoding->dest, "opcodes", 'h', &exist); - if (header_fd == -1) return false; - - if (!exist) - { - dprintf(header_fd, "#ifndef %s_OPCODES_OPCODES_H\n", coder->header); - dprintf(header_fd, "#define %s_OPCODES_OPCODES_H\n", coder->header); - - dprintf(header_fd, "\n"); - dprintf(header_fd, "\n"); - dprintf(header_fd, "##INCLUDES##\n"); - dprintf(header_fd, "\n"); - dprintf(header_fd, "\n"); - dprintf(header_fd, "\n"); - - } - - /* Fichier de définitions */ - - dash = strchr(coder->ins, '-'); - - if (dash == NULL) - code_fd = create_code_file(coder, "opcodes", encoding->dest, coder->ins, 'c', &exist); - - else - { - filename = strdup(coder->ins); - - dash = strchr(filename, '-'); - *dash = '\0'; - - code_fd = create_code_file(coder, "opcodes", encoding->dest, filename, 'c', &exist); - - free(filename); - - } - - if (!exist) - { - dprintf(code_fd, "#include \"opcodes.h\"\n"); - dprintf(code_fd, "\n"); - dprintf(code_fd, "##INCLUDES##\n"); - - } - - if (code_fd == -1) - { - close(header_fd); - return false; - } - - /* Production de code... */ - - result = dump_all_matching_specs_in_coder(coder, encoding, header_fd, code_fd); - - close(header_fd); - close(code_fd); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement d'humain. * -* encoding = sélection de l'encodage à traiter. * -* hfd = flux ouvert en écriture pour les déclarations. * -* cfd = flux ouvert en écriture pour les définitions. * -* * -* Description : Ecrit une partie des fonctions issues des spécifications. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool dump_all_matching_specs_in_coder(const rented_coder *coder, const string_exch *encoding, int hfd, int cfd) -{ - bool result; /* Bilan à retourner */ - char *keyword; /* Mot clef appelable en code */ - unsigned int wide; /* Taille des mots */ - size_t i; /* Boucle de parcours */ - encoding_spec *spec; /* Définition à traiter */ - coding_bits *bits; /* Gestionnaire de bits */ - size_t maxlen; /* Taille à compléter */ - - result = true; - - keyword = make_callable(coder->ins, false); - - /* Recherche de la taille des mots */ - - wide = -1; - - for (i = 0; i < coder->specs_count; i++) - { - spec = coder->specs[i]; - - if (!has_encoding_spec_prefix(spec, encoding->src)) - continue; - - bits = get_bits_in_encoding_spec(spec); - wide = count_coded_bits(bits); - break; - - } - - /* Rien n'a été trouvé à faire... */ - if (wide == -1) goto damsic_exit; - - /* Désassemblage : déclaration */ - - dprintf(hfd, "/* Décode une instruction de type '%s'. */\n", coder->ins); - dprintf(hfd, "GArchInstruction *%s_read_instr_%s%s(uint%u_t);\n", coder->arch, keyword, coder->details, wide); - dprintf(hfd, "\n"); - - /* Désassemblage : définitions */ - - dprintf(cfd, "\n"); - - dprintf(cfd, "/******************************************************************************\n"); - dprintf(cfd, "* *\n"); - dprintf(cfd, "* Paramètres : raw = données brutes à analyser. *\n"); - dprintf(cfd, "* *\n"); - dprintf(cfd, "* Description : Décode une instruction de type '%s'.", coder->ins); - - maxlen = 28 - strlen(coder->ins); - - if (maxlen < 28) - dprintf(cfd, "%*s\n", (int)maxlen, "*"); - else - dprintf(cfd, "*\n"); - - dprintf(cfd, " *\n"); - dprintf(cfd, "* Retour : Bilan de l'opération. *\n"); - dprintf(cfd, "* *\n"); - dprintf(cfd, "* Remarques : - *\n"); - dprintf(cfd, "* *\n"); - dprintf(cfd, "******************************************************************************/\n"); - - dprintf(cfd, "\n"); - - dprintf(cfd, "GArchInstruction *%s_read_instr_%s%s(uint%u_t raw)", coder->arch, keyword, coder->details, wide); - dprintf(cfd, "\n"); - dprintf(cfd, "{"); - dprintf(cfd, "\n"); - - dprintf(cfd, "\tGArchInstruction *result; /* Instruction créée à renvoyer*/\n"); - - dprintf(cfd, "\n"); - dprintf(cfd, "\tresult = NULL;\n"); - dprintf(cfd, "\n"); - - for (i = 0; i < coder->specs_count && result; i++) - { - spec = coder->specs[i]; - - if (!has_encoding_spec_prefix(spec, encoding->src)) - continue; - - result = write_encoding_spec_disass(spec, cfd, coder->arch, coder->ins, coder->details, wide, coder->pp); - - } - - dprintf(cfd, "\treturn result;\n"); - dprintf(cfd, "\n"); - - dprintf(cfd, "}\n"); - dprintf(cfd, "\n"); - - damsic_exit: - - free(keyword); - - return result; - -} diff --git a/tools/coder.h b/tools/coder.h deleted file mode 100644 index e72764c..0000000 --- a/tools/coder.h +++ /dev/null @@ -1,125 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * coder.h - prototypes pour la lecture automatisée des spécifications d'architecture - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _ARCH_ARM_V7_OPDEFS_CODER_H -#define _ARCH_ARM_V7_OPDEFS_CODER_H - - -#include - - -#include "pproc.h" -#include "spec.h" - - - -/* Suivi des constructions */ -typedef struct _rented_coder rented_coder; - - - -/* -------------------------- CONSTRUCTION SELON COMMANDES -------------------------- */ - - -/* Débute la définition d'une fonction de désassemblage. */ -rented_coder *create_coder(void); - -/* Supprime le codeur de la mémoire. */ -void delete_coder(rented_coder *); - -/* Détermine si les propriétés de base d'un codeur sont là. */ -bool do_basic_checks_with_coder(const rented_coder *); - -/* Spécifie le répertoire de base pour les sorties de code. */ -void set_coder_output_directory(rented_coder *, const char *); - -/* Détermine l'architecture visée par les traitements. */ -void set_coder_arch(rented_coder *, const char *); - -/* Définit la base des protections des fichiers d'en-tête. */ -void set_coder_header_base(rented_coder *, const char *); - -/* Fournit le pré-processeur du compilateur. */ -pre_processor *get_coder_pre_proc(const rented_coder *); - -/* Enregistre les contours d'une instruction d'assemblage. */ -void save_notes_for_coder(rented_coder *, char *, char *, const char *); - - - -/* --------------------------- REPRESENTATION D'ENCODAGES --------------------------- */ - - -/* Fournit un lien vers les spécifications courantes. */ -encoding_spec *get_current_encoding_spec(const rented_coder *); - -/* Enregistre une définition supplémentaire. */ -void push_encoding_spec(rented_coder *, char *, unsigned int); - - - -/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ - - -/* Note la présence d'un champ remarquable dans une définition. */ -void register_named_field_in_coder(rented_coder *, char *, unsigned int); - -/* Note la présence d'un bit invariable dans une définition. */ -void register_bit_in_coder(rented_coder *, int); - -/* Indique le nombre de bits traités. */ -//unsigned int count_coder_bits(const rented_coder *); - - - -/* ---------------------------- SYNTAXE DES INSTRUCTIONS ---------------------------- */ - - -/* Enregistre la présence d'un nouvel opérande. */ -void register_syntax_item_in_coder(rented_coder *, char *, bool); - - - -/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ - - -/* Enregistre la function de conversion du brut à l'utile. */ -void register_conversion_in_coder(rented_coder *, conv_func *); - - - -/* --------------------------- CONDITIONS ET CONSEQUENCES --------------------------- */ - - - - - -/* --------------------------- GENERATIONS DE CODE SOURCE --------------------------- */ - - -/* Débute la définition des fonctions issues des spécifications. */ -bool dump_all_routines_using_coder(const rented_coder *); - - - -#endif /* _ARCH_ARM_V7_OPDEFS_CODER_H */ diff --git a/tools/conv.c b/tools/conv.c deleted file mode 100644 index 323f63d..0000000 --- a/tools/conv.c +++ /dev/null @@ -1,1640 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * conv.c - substitutions de valeurs depuis un contenu binaire - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "conv.h" - - -#include -#include -#include -#include -#include -#include -#include - - -#include "helpers.h" - - - - - -/* Types d'expressions représentés */ -typedef enum _ConvExprType -{ - CET_NAME, /* Désignation de variable */ - CET_NUMBER, /* Valeur codée en dur */ - CET_COMPOSED, /* Agrégat de champs divers */ - CET_UNARY, /* Opération unaire */ - CET_BINARY, /* Opération binaire */ - - CET_COUNT - -} ConvExprType; - - -/* Représentation d'une expression de conversion */ -struct _conv_expr_t -{ - ConvExprType type; - - bool declared; /* Expression déjà déclarée ? */ - bool defined; /* Expression déjà définie ? */ - - union - { - /* CET_NAME */ - char *name; /* Désignation de variable */ - - /* CET_NUMBER */ - unsigned long number; /* Valeur durablement définie */ - - /* CET_COMPOSED */ - struct - { - char **comp_items; /* Elements à agréger */ - size_t comp_count; /* Quantité de ces éléments */ - }; - - /* CET_UNARY */ - struct - { - conv_expr_t *un_expr; /* Expression à traiter */ - ConvUnaryOperation un_op; /* Type d'opération à mener */ - - }; - - /* CET_BINARY */ - struct - { - conv_expr_t *bin_expr1; /* Expression à traiter */ - conv_expr_t *bin_expr2; /* Expression à traiter */ - ConvBinaryOperation bin_op; /* Type d'opération à mener */ - - }; - - }; - -}; - - -/* Visite une expression en traitant en premier ses composantes. */ -typedef bool (* visit_expr_fc) (conv_expr_t *, int, const coding_bits *, const conv_list *, void *); - - -/* Détermine la taille en bits d'une expression donnée. */ -static bool compute_conv_expr_size(const conv_expr_t *, const coding_bits *, const conv_list *, unsigned int *); - -/* Visite une expression en traitant en premier ses composantes. */ -static bool visit_conv_expr(conv_expr_t *, visit_expr_fc, int, const coding_bits *, const conv_list *, void *); - -/* Retrouve si elle existe une variable manipulée. */ -static bool find_var_by_name(const coding_bits *, const conv_list *, const char *, raw_bitfield **, conv_func **); - -/* S'assure du marquage des expressions pre-requises. */ -static bool ensure_conv_expr_content_fully_marked(conv_expr_t *, const coding_bits *, const conv_list *); - -/* S'assure de la déclaration des expressions pre-requises. */ -static bool ensure_conv_expr_content_fully_declared(conv_expr_t *, int, const coding_bits *, const conv_list *, unsigned int); - -/* S'assure de la définition des expressions pre-requises. */ -static bool ensure_conv_expr_content_fully_defined(conv_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); - -/* Définit une expression utilisée dans une conversion. */ -static bool define_conv_expr(conv_expr_t *, int, const coding_bits *, const conv_list *); - - - -/* ------------------------ LISTES D'ARGUMENTS DE CONVERSION ------------------------ */ - - -/* Liste d'expressions utilisées en arguments de conversion */ -struct _conv_arg_list_t -{ - conv_expr_t **items; /* Liste d'expressions */ - size_t count; /* Taille de cette liste */ - -}; - - -/* S'assure du marquage des expressions pre-requises. */ -static bool ensure_arg_list_content_fully_marked(conv_arg_list_t *, const coding_bits *, const conv_list *); - -/* S'assure de la déclaration des expressions pre-requises. */ -static bool ensure_arg_list_content_fully_declared(conv_arg_list_t *, int, const coding_bits *, const conv_list *, unsigned int); - -/* S'assure de la définition des expressions pre-requises. */ -static bool ensure_arg_list_content_fully_defined(conv_arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); - -/* Définit les variables associées à un appel de fonction. */ -static bool define_arg_list(conv_arg_list_t *, int, const coding_bits *, const conv_list *); - - - -/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ - - -/* Fonction de conversion */ -struct _conv_func -{ - bool declared; /* Expression déjà déclarée ? */ - bool defined; /* Expression déjà définie ? */ - - char *dest; /* Variable de destination */ - - bool is_expr; /* Choix du contenu réel */ - - union - { - conv_expr_t *expr; /* Valeur expressive directe */ - - struct - { - char *name; /* Fonction de conversion */ - conv_arg_list_t *args; /* Liste des arguments */ - - }; - - }; - -}; - - -/* Détermine la taille en bits du résultat d'une fonction. */ -static bool compute_conv_func_size(const conv_func *, const coding_bits *, const conv_list *, unsigned int *); - - - - - - -#define delete_conv_expr(e) - - - - - - -/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ - - -/* Liste des fonctions de conversions présentes */ -struct _conv_list -{ - conv_func **functions; /* Fonctions de conversion */ - size_t func_count; /* Nombre de ces fonctions */ - -}; - - - - - - - - - - - - -/****************************************************************************** -* * -* Paramètres : name = désignation d'une variable quelconque. * -* * -* Description : Référence une variable en tant qu'expression de conversion. * -* * -* Retour : Nouvelle expression mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *build_conv_expr_from_name(char *name) -{ - conv_expr_t *result; /* Structure à retourner */ - - result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); - - result->type = CET_NAME; - - result->name = make_string_lower(name); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : number = valeur à conserver dans sa forme brute. * -* * -* Description : Conserve une valeur en tant qu'expression de conversion. * -* * -* Retour : Nouvelle expression mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *build_conv_expr_from_number(unsigned long number) -{ - conv_expr_t *result; /* Structure à retourner */ - - result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); - - result->type = CET_NUMBER; - - result->number = number; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item1 = premier élément à agréger. * -* item2 = second élément à agréger. * -* * -* Description : Construit une base d'expression de conversion composée. * -* * -* Retour : Nouvelle expression mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *build_composed_conv_expr(char *item1, char *item2) -{ - conv_expr_t *result; /* Structure à retourner */ - - result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); - - result->type = CET_COMPOSED; - - result->comp_items = (char **)calloc(2, sizeof(char *)); - result->comp_count = 2; - - result->comp_items[0] = make_string_lower(item1); - result->comp_items[1] = make_string_lower(item2); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = expression déjà en place à compléter. * -* item = nouvel élément à agréger. * -* * -* Description : Etend une base d'expression de conversion composée. * -* * -* Retour : Expression en place et mise à jour. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *extend_composed_conv_expr(conv_expr_t *expr, char *item) -{ - assert(expr->type == CET_COMPOSED); - - expr->comp_items = (char **)realloc(expr->comp_items, ++expr->comp_count * sizeof(char *)); - - expr->comp_items[expr->comp_count - 1] = make_string_lower(item); - - return expr; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = expression à encapsuler. * -* op = opération unaire à associer à l'opération. * -* * -* Description : Traduit une opération unaire sur expression de conversion. * -* * -* Retour : Nouvelle expression mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *build_unary_conv_expr(conv_expr_t *expr, ConvUnaryOperation op) -{ - conv_expr_t *result; /* Structure à retourner */ - - result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); - - result->type = CET_UNARY; - - result->un_expr = expr; - result->un_op = op; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr1 = première expression à encapsuler. * -* expr2 = seconde expression à encapsuler. * -* op = opération binaire à associer à l'opération. * -* * -* Description : Traduit une opération binaire sur expression de conversion. * -* * -* Retour : Nouvelle expression mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_expr_t *build_binary_conv_expr(conv_expr_t *expr1, conv_expr_t *expr2, ConvBinaryOperation op) -{ - conv_expr_t *result; /* Structure à retourner */ - - result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); - - result->type = CET_BINARY; - - result->bin_expr1 = expr1; - result->bin_expr2 = expr2; - result->bin_op = op; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à consulter. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* size = taille déterminée avec précision. [OUT] * -* * -* Description : Détermine la taille en bits d'une expression donnée. * -* * -* Retour : true si la taille a pu être déterminée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool compute_conv_expr_size(const conv_expr_t *expr, const coding_bits *bits, const conv_list *list, unsigned int *size) -{ - bool result; /* Bilan à retourner */ - raw_bitfield *field; /* Eventuel champ brut associé */ - conv_func *func; /* Eventuelle fonction liée */ - size_t i; /* Boucle de parcours */ - unsigned int tmp; /* Stockage temporaire */ - - switch (expr->type) - { - case CET_NAME: - - result = find_var_by_name(bits, list, expr->name, &field, &func); - - if (result) - { - if (field != NULL) - *size = get_raw_bitfield_length(field); - else - result = compute_conv_func_size(func, bits, list, size); - } - - break; - - case CET_COMPOSED: - - result = true; - *size = 0; - - for (i = 0; i < expr->comp_count && result; i++) - { - if (isdigit(expr->comp_items[i][0])) - *size += strlen(expr->comp_items[i]); - - else - { - if (!find_var_by_name(bits, list, expr->comp_items[i], &field, &func)) - result = false; - - else - { - if (field != NULL) - *size += get_raw_bitfield_length(field); - else - { - result = compute_conv_func_size(func, bits, list, &tmp); - *size += tmp; - } - } - - } - - } - - break; - - case CET_UNARY: - result = compute_conv_expr_size(expr->un_expr, bits, list, size); - break; - - case CET_BINARY: - - result = compute_conv_expr_size(expr->bin_expr1, bits, list, &tmp); - - if (result) - result = compute_conv_expr_size(expr->bin_expr1, bits, list, size); - - if (tmp > *size) *size = tmp; - - break; - - default: - result = false; - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à encapsuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* data = éventuelle donnée à transmettre à chaque visite. * -* * -* Description : Visite une expression en traitant en premier ses composantes.* -* * -* Retour : Bilan des traitements effectués. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool visit_conv_expr(conv_expr_t *expr, visit_expr_fc visit, int fd, const coding_bits *bits, const conv_list *list, void *data) -{ - bool result; /* Bilan à retourner */ - - switch (expr->type) - { - case CET_UNARY: - result = visit_conv_expr(expr->un_expr, visit, fd, bits, list, data); - break; - - case CET_BINARY: - result = visit_conv_expr(expr->bin_expr1, visit, fd, bits, list, data); - result = visit_conv_expr(expr->bin_expr2, visit, fd, bits, list, data); - break; - - default: - result = true; - break; - - } - - result &= visit(expr, fd, bits, list, data); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* name = déssignation de la variable recherchée. * -* field = éventuel élement brut de décodage. * -* func = éventuelle fonction de conversion pour intermédiaire.* -* * -* Description : Retrouve si elle existe une variable manipulée. * -* * -* Retour : Bilan des recherches : trouvaille ou non ? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool find_var_by_name(const coding_bits *bits, const conv_list *list, const char *name, raw_bitfield **field, conv_func **func) -{ - bool result; /* Bilan à retourner */ - raw_bitfield *cached_field; /* Champ, version cachée */ - conv_func *cached_func; /* Fonction, version cachée */ - - cached_field = find_named_field_in_bits(bits, name); - result = (cached_field != NULL); - - if (!result) - { - cached_func = find_named_conv_in_list(list, name); - result = (cached_func != NULL); - } - else - cached_func = NULL; - - if (field != NULL) *field = cached_field; - if (func != NULL) *func = cached_func; - - if (!result) - fprintf(stderr, "Variable '%s' not found!\n", name); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à encapsuler. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : S'assure du marquage des expressions pre-requises. * -* * -* Retour : Bilan des traitements effectués. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_conv_expr_content_fully_marked(conv_expr_t *expr, const coding_bits *bits, const conv_list *list) -{ - bool mark_sub_expr(conv_expr_t *sub, int dummy, const coding_bits *bts, const conv_list *lst, void *unused) - { - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - bool mark_by_name(const coding_bits *_bts, const conv_list *_lst, const char *name) - { - bool found; /* Bilan d'opération à renvoyer*/ - raw_bitfield *field; /* Eventuel champ brut associé */ - - found = find_var_by_name(bts, lst, name, &field, NULL); - - if (found && field != NULL) - mark_raw_bitfield_as_used(field); - - return found; - - } - - /* Il est uniquement nécessaire de s'attacher aux références */ - switch (sub->type) - { - case CET_NAME: - result = mark_by_name(bits, lst, sub->name); - break; - - case CET_COMPOSED: - result = true; - for (i = 0; i < sub->comp_count && result; i++) - if (!isdigit(sub->comp_items[i][0])) - result = mark_by_name(bits, lst, sub->comp_items[i]); - break; - - default: - result = true; - break; - - } - - return result; - - } - - return visit_conv_expr(expr, (visit_expr_fc)mark_sub_expr, -1, bits, list, NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à encapsuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* wide = taille des mots décodés. * -* * -* Description : S'assure de la déclaration des expressions pre-requises. * -* * -* Retour : Bilan des traitements effectués. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_conv_expr_content_fully_declared(conv_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) -{ - bool declare_sub_expr(conv_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wide) - { - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - /* Si l'expression a déjà été définie lors d'un précédent besoin... */ - if (sub->declared) return true; - - bool declare_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, unsigned int _wide, const char *name) - { - bool found; /* Bilan d'opération à renvoyer*/ - conv_func *func; /* Eventuelle fonction liée */ - - found = find_var_by_name(bts, lst, name, NULL, &func); - - if (found && func != NULL) - { - dprintf(_f, "\t\tuint%u_t val_%s;\n", _wide, name); - found = declare_conv_func(func, _f, _bts, _lst, _wide); - } - - return found; - - } - - /* Il est uniquement nécessaire de s'attacher aux références */ - switch (sub->type) - { - case CET_NAME: - result = declare_by_name(f, bits, lst, *wide, sub->name); - break; - - case CET_COMPOSED: - result = true; - for (i = 0; i < sub->comp_count && result; i++) - if (!isdigit(sub->comp_items[i][0])) - printf("... trying to declare... '%s'\n", sub->comp_items[i]); - for (i = 0; i < sub->comp_count && result; i++) - if (!isdigit(sub->comp_items[i][0])) - result = declare_by_name(f, bits, lst, *wide, sub->comp_items[i]); - break; - - default: - result = true; - break; - - } - - sub->declared = result; - - return result; - - } - - return visit_conv_expr(expr, (visit_expr_fc)declare_sub_expr, fd, bits, list, &wide); - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à encapsuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * -* * -* Description : S'assure de la définition des expressions pre-requises. * -* * -* Retour : Bilan des traitements effectués. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_conv_expr_content_fully_defined(conv_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) -{ - typedef struct _def_info - { - const char *arch; - const pre_processor *pp; - - } def_info; - - def_info info; /* Transmissions au visiteur */ - - bool define_sub_expr(conv_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, def_info *info) - { - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - - /* Si l'expression a déjà été définie lors d'un précédent besoin... */ - if (sub->defined) return true; - - bool define_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, def_info *_info, const char *name) - { - bool found; /* Bilan d'opération à renvoyer*/ - conv_func *func; /* Eventuelle fonction liée */ - - found = find_var_by_name(bts, lst, name, NULL, &func); - - if (found && func != NULL) - found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp); - - return found; - - } - - /* Il est uniquement nécessaire de s'attacher aux références */ - switch (sub->type) - { - case CET_NAME: - result = define_by_name(f, bits, lst, info, sub->name); - break; - - case CET_COMPOSED: - result = true; - for (i = 0; i < sub->comp_count && result; i++) - if (!isdigit(sub->comp_items[i][0])) - result = define_by_name(f, bits, lst, info, sub->comp_items[i]); - break; - - default: - result = true; - break; - - } - - sub->defined = result; - - return result; - - } - - info.arch = arch; - info.pp = pp; - - return visit_conv_expr(expr, (visit_expr_fc)define_sub_expr, fd, bits, list, &info); - -} - - -/****************************************************************************** -* * -* Paramètres : expr = première expression à encapsuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : Définit une expression utilisée dans une conversion. * -* * -* Retour : Bilan des traitements effectués. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool define_conv_expr(conv_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list) -{ - bool result; /* Bilan à retourner */ - raw_bitfield *field; /* Eventuel champ brut associé */ - conv_func *func; /* Eventuelle fonction liée */ - unsigned int max_size; /* Quantité de bits totale */ - size_t i; /* Boucle de parcours */ - const char *cname; /* Raccourci de confort */ - unsigned int used_size; /* Quantité de bits utilisée */ - - result = true; - - switch (expr->type) - { - case CET_NAME: - - if (!find_var_by_name(bits, list, expr->name, &field, &func)) - result = false; - - else - { - if (field != NULL) - dprintf(fd, "raw_%s", expr->name); - else - dprintf(fd, "val_%s", expr->name); - } - - break; - - case CET_NUMBER: - dprintf(fd, "%lu", expr->number); - break; - - case CET_COMPOSED: - - result = compute_conv_expr_size(expr, bits, list, &max_size); - - printf("MAX SIZE :: %u\n", max_size); - - for (i = 0; i < expr->comp_count && result; i++) - { - cname = expr->comp_items[i]; - - if (i > 0) - dprintf(fd, " | "); - - /* Constante binaire ? */ - if (isdigit(cname[0])) - { - max_size -= strlen(cname); - - if (max_size == 0) - dprintf(fd, "b%s", cname); - else - dprintf(fd, "b%s << %u", cname, max_size); - - } - - /* Ou variable définie ? */ - else - { - result = find_var_by_name(bits, list, cname, &field, &func); - - if (result) - { - if (field != NULL) - used_size = get_raw_bitfield_length(field); - else - /*result = */compute_conv_func_size(func, bits, list, &used_size); - - max_size -= used_size; - - if (field != NULL) - { - if (max_size == 0) - dprintf(fd, "raw_%s", cname); - else - dprintf(fd, "raw_%s << %u", cname, max_size); - } - else - { - if (max_size == 0) - dprintf(fd, "val_%s", cname); - else - dprintf(fd, "val_%s << %u", cname, max_size); - } - - } - - } - - } - - break; - - case CET_UNARY: - - switch (expr->un_op) - { - case CUO_NOT: - dprintf(fd, "!"); - break; - default: - result = false; - break; - } - - result &= define_conv_expr(expr->un_expr, fd, bits, list); - - break; - - case CET_BINARY: - - dprintf(fd, "("); - - result = define_conv_expr(expr->bin_expr1, fd, bits, list); - - switch (expr->bin_op) - { - case CBO_EOR: - dprintf(fd, " ^ "); - break; - default: - result = false; - break; - } - - result &= define_conv_expr(expr->bin_expr2, fd, bits, list); - - dprintf(fd, ")"); - - break; - - default: - result = false; - break; - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* LISTES D'ARGUMENTS DE CONVERSION */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : expr = expression initial pour constituer une liste. * -* * -* Description : Crée une liste d'arguments de conversion. * -* * -* Retour : Nouvelle structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_arg_list_t *build_conv_arg_list(conv_expr_t *expr) -{ - conv_arg_list_t *result; /* Structure à retourner */ - - result = (conv_arg_list_t *)calloc(1, sizeof(conv_arg_list_t)); - - result->items = (conv_expr_t **)calloc(1, sizeof(conv_expr_t *)); - result->count = 1; - - result->items[0] = expr; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste d'expressions à supprimer de la mémoire. * -* * -* Description : Libère la mémoire occupée par une liste d'expressions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_conv_arg_list(conv_arg_list_t *list) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < list->count; i++) - delete_conv_expr(list->items[i]); - - if (list->items != NULL) - free(list->items); - - free(list); - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste d'expressions à supprimer de la mémoire. [OUT] * -* expr = expression à ajouter à la liste courante. * -* * -* Description : Ajoute un élément à une liste d'arguments de conversion. * -* * -* Retour : Structure en place mise à jour. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_arg_list_t *extend_conv_arg_list(conv_arg_list_t *list, conv_expr_t *expr) -{ - list->items = (conv_expr_t **)realloc(list->items, ++list->count * sizeof(conv_expr_t *)); - - list->items[list->count - 1] = expr; - - return list; - -} - - -/****************************************************************************** -* * -* Paramètres : args = liste d'expressions à supprimer de la mémoire. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : S'assure du marquage des expressions pre-requises. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_arg_list_content_fully_marked(conv_arg_list_t *args, const coding_bits *bits, const conv_list *list) -{ - bool result; /* Bilan à remonter */ - size_t i; /* Boucle de parcours */ - - result = true; - - for (i = 0; i < args->count && result; i++) - result = ensure_conv_expr_content_fully_marked(args->items[i], bits, list); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : args = liste d'expressions à supprimer de la mémoire. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* wide = taille des mots décodés. * -* * -* Description : S'assure de la déclaration des expressions pre-requises. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_arg_list_content_fully_declared(conv_arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) -{ - bool result; /* Bilan à remonter */ - size_t i; /* Boucle de parcours */ - - result = true; - - for (i = 0; i < args->count && result; i++) - result = ensure_conv_expr_content_fully_declared(args->items[i], fd, bits, list, wide); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : args = liste d'expressions à supprimer de la mémoire. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * -* * -* Description : S'assure de la définition des expressions pre-requises. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool ensure_arg_list_content_fully_defined(conv_arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) -{ - bool result; /* Bilan à remonter */ - size_t i; /* Boucle de parcours */ - - result = true; - - for (i = 0; i < args->count && result; i++) - result = ensure_conv_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : args = liste d'expressions à supprimer de la mémoire. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : Définit les variables associées à un appel de fonction. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool define_arg_list(conv_arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list) -{ - bool result; /* Bilan à remonter */ - size_t i; /* Boucle de parcours */ - - result = true; - - for (i = 0; i < args->count && result; i++) - { - if (i > 0) dprintf(fd, ", "); - result = define_conv_expr(args->items[i], fd, bits, list); - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONVERSION DES ARGUMENTS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : dest = désignation de la variable de destination. * -* expr = expression dont la valeur est à assigner. * -* * -* Description : Définit une conversion à partir d'une simple expression. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_func *make_conv_from_expr(char *dest, conv_expr_t *expr) -{ - conv_func *result; /* Conversion à retourner */ - - result = (conv_func *)calloc(1, sizeof(conv_func)); - - result->dest = make_string_lower(dest); - - result->is_expr = true; - result->expr = expr; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : dest = désignation de la variable de destination. * -* func = nom de la fonction assurant le calcul de valeur. * -* args = argument(s) à fournir à cette fonction. * -* * -* Description : Définit une conversion à partir d'une function à appeler. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_func *make_conv_from_func(char *dest, char *func, conv_arg_list_t *args) -{ - conv_func *result; /* Conversion à retourner */ - - result = (conv_func *)calloc(1, sizeof(conv_func)); - - result->dest = make_string_lower(dest); - - result->is_expr = false; - result->name = func; - result->args = args; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : func = éléments de conversion à supprimer de la mémoire. * -* * -* Description : Libère de la mémoire une conversion enregistrée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_conv_func(conv_func *func) -{ - if (func->is_expr) - delete_conv_expr(func->expr); - - else - { - free(func->name); - delete_conv_arg_list(func->args); - } - - free(func); - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à consulter. * -* * -* Description : Indique la variable de destination d'une conversion. * -* * -* Retour : Désignation humaine de la variable de destination. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *get_conv_dest_name(const conv_func *func) -{ - return func->dest; - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à consulter. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* size = taille déterminée avec précision. [OUT] * -* * -* Description : Détermine la taille en bits du résultat d'une fonction. * -* * -* Retour : true si la taille a pu être déterminée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, const conv_list *list, unsigned int *size) -{ - bool result; /* Bilan à retourner */ - - result = func->is_expr; - - if (result) - result = compute_conv_expr_size(func->expr, bits, list, size); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à manipuler. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : Marque les champs utilisés par une fonction de conversion. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list) -{ - bool result; /* Bilan à remonter */ - - if (func->is_expr) - result = ensure_conv_expr_content_fully_marked(func->expr, bits, list); - else - result = ensure_arg_list_content_fully_marked(func->args, bits, list); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à manipuler. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* wide = taille des mots décodés. * -* * -* Description : Déclare les variables associées à une fonction de conversion.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) -{ - bool result; /* Bilan à remonter */ - - /* Si la fonction a déjà été définie lors d'un précédent besoin... */ - if (func->declared) return true; - - if (func->is_expr) - result = ensure_conv_expr_content_fully_declared(func->expr, fd, bits, list, wide); - else - result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide); - - func->declared = result; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : func = fonction de conversion à manipuler. * -* last = précise si la conversion est la dernière. * -* internal = indique le type de manipulation finale. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * -* * -* Description : Définit les variables associées à une fonction de conversion.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) -{ - bool result; /* Bilan à remonter */ - const char *callable; /* Fonction à appeler */ - regex_t preg; /* Expression régulière */ - int ret; /* Bilan d'une manipulation */ - regmatch_t pmatch[3]; /* Correspondances de chaînes */ - size_t cmplen; /* Taille de comparaison */ - char *cast; /* Macro de transtypage */ - - /* Si la fonction a déjà été définie lors d'un précédent besoin... */ - if (func->defined) return true; - - if (func->is_expr) - result = ensure_conv_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp); - else - result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp); - - /* Nom de la fonction effectivement appelée */ - - if (!func->is_expr) - { - callable = find_macro(pp, func->name); - - if (callable == NULL) - callable = func->name; - - } - else callable = NULL; - - if (last && callable == NULL) - { - fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest); - return false; - } - - /* Dernier niveau : la variable de destination est imposée ! */ - if (last) - { - /* Si l'on doit manipuler une propriété d'instructon... */ - if (internal) - { - ret = regcomp(&preg, "(g_([a-z0-9]*)_instruction)", REG_EXTENDED); - if (ret != 0) - { - fprintf(stderr, "Internal error: bad regular expression.\n"); - return false; - } - - ret = regexec(&preg, callable, sizeof(pmatch) / sizeof(regmatch_t), pmatch, 0); - if (ret == REG_NOMATCH) - { - fprintf(stderr, "Internal error: bad function for dealing wih instruction: '%s'.\n", callable); - result = false; - goto dcf_skip_internal; - } - - /** - * La variable de résultat est de type 'GArchInstruction', - * donc toute fonction différente de g_arch_instruction_*() attend un transtypage... - */ - - cmplen = MAX(strlen(arch), pmatch[2].rm_eo - pmatch[2].rm_so); - - if (strncmp("arch", &callable[pmatch[2].rm_so], cmplen) == 0) - dprintf(fd, "\t\tif (!%s(instr, ", callable); - - else - { - cast = strndup(&callable[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so); - - cast = make_string_upper(cast); - - dprintf(fd, "\t\tif (!%s(%s(instr), ", callable, cast); - - free(cast); - - } - - result &= define_arg_list(func->args, fd, bits, list); - - dprintf(fd, "))\n"); - - dcf_skip_internal: - - regfree(&preg); - - } - - /* Si on doit constituer un opérande à ajouter... */ - else - { - if (strchr(callable, '(') == NULL) - dprintf(fd, "\t\top = %s(", callable); - else - dprintf(fd, "\t\top = %s", callable); - - result &= define_arg_list(func->args, fd, bits, list); - - dprintf(fd, ");\n"); - - } - - } - - /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */ - else - { - dprintf(fd, "\t\tval_%s = ", func->dest); - - if (func->is_expr) - result &= define_conv_expr(func->expr, fd, bits, list); - - else - { - dprintf(fd, "%s(", callable); - - result = define_arg_list(func->args, fd, bits, list); - - dprintf(fd, ")"); - - } - - dprintf(fd, ";\n"); - - } - - func->defined = result; - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* ENSEMBLES DE CONVERSIONS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouvelle liste vierge de fonctions de conversion. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_list *create_conv_list(void) -{ - conv_list *result; /* Définition vierge à renvoyer*/ - - result = (conv_list *)calloc(1, sizeof(conv_list)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : list = ensemble de fonctions de conversion à supprimer. * -* * -* Description : Supprime de la mémoire une de fonctions de conversion. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_conv_list(conv_list *list) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < list->func_count; i++) - delete_conv_func(list->functions[i]); - - if (list->functions != NULL) - free(list->functions); - - free(list); - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste de fonctions de conversion à compléter. * -* func = nom de la fonction assurant le calcul de valeur. * -* * -* Description : Enregistre une function de conversion du brut à l'utile. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_conversion(conv_list *list, conv_func *func) -{ - list->functions = (conv_func **)realloc(list->functions, ++list->func_count * sizeof(conv_func *)); - - list->functions[list->func_count - 1] = func; - -} - - -/****************************************************************************** -* * -* Paramètres : list = liste de fonctions de conversion à consulter. * -* name = désignation humaine du champ à retrouver. * -* * -* Description : Recherche un résultat précis dans une liste de fonctions. * -* * -* Retour : Structure associée au résulat trouvé ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -conv_func *find_named_conv_in_list(const conv_list *list, const char *name) -{ - conv_func *result; /* Fonction à retourner */ - size_t i; /* Boucle de parcours */ - const char *dest; /* Nom de variable existante */ - - result = NULL; - - for (i = 0; i < list->func_count && result == NULL; i++) - { - dest = get_conv_dest_name(list->functions[i]); - - if (strcmp(dest, name) == 0) - result = list->functions[i]; - - } - - return result; - -} diff --git a/tools/conv.h b/tools/conv.h deleted file mode 100644 index acf007b..0000000 --- a/tools/conv.h +++ /dev/null @@ -1,160 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * conv.h - prototypes pour les substitutions de valeurs depuis un contenu binaire - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_CONV_H -#define _TOOLS_CONV_H - - -#include "bits.h" -#include "pproc.h" - - - - -/* Liste des fonctions de conversions présentes */ -typedef struct _conv_list conv_list; - - - - - - - -/* Types d'opérations unaires */ -typedef enum _ConvUnaryOperation -{ - CUO_NOT, /* NOT (booléen) */ - - CUO_COUNT - -} ConvUnaryOperation; - - - -/* Types d'opérations binaires */ -typedef enum _ConvBinaryOperation -{ - CBO_EOR, /* Ou exclusif (booléen) */ - - CBO_COUNT - -} ConvBinaryOperation; - - -/* Représentation d'une expression de conversion */ -typedef struct _conv_expr_t conv_expr_t; - - - -/* Référence une variable en tant qu'expression de conversion. */ -conv_expr_t *build_conv_expr_from_name(char *); - -/* Conserve une valeur en tant qu'expression de conversion. */ -conv_expr_t *build_conv_expr_from_number(unsigned long ); - -/* Construit une base d'expression de conversion composée. */ -conv_expr_t *build_composed_conv_expr(char *, char *); - -/* Etend une base d'expression de conversion composée. */ -conv_expr_t *extend_composed_conv_expr(conv_expr_t *, char *); - -/* Traduit une opération unaire sur expression de conversion. */ -conv_expr_t *build_unary_conv_expr(conv_expr_t *, ConvUnaryOperation); - -/* Traduit une opération binaire sur expression de conversion. */ -conv_expr_t *build_binary_conv_expr(conv_expr_t *, conv_expr_t *, ConvBinaryOperation); - - - - - - - - -/* ------------------------ LISTES D'ARGUMENTS DE CONVERSION ------------------------ */ - - -/* Liste d'expressions utilisées en arguments de conversion */ -typedef struct _conv_arg_list_t conv_arg_list_t; - - -/* Crée une liste d'arguments de conversion. */ -conv_arg_list_t *build_conv_arg_list(conv_expr_t *); - -/* Libère la mémoire occupée par une liste d'expressions. */ -void delete_conv_arg_list(conv_arg_list_t *); - -/* Ajoute un élément à une liste d'arguments de conversion. */ -conv_arg_list_t *extend_conv_arg_list(conv_arg_list_t *, conv_expr_t *); - - - - -/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ - - -/* Fonction de conversion */ -typedef struct _conv_func conv_func; - - -/* Définit une conversion à partir d'une simple expression. */ -conv_func *make_conv_from_expr(char *, conv_expr_t *); - -/* Définit une conversion à partir d'une function à appeler. */ -conv_func *make_conv_from_func(char *, char *, conv_arg_list_t *); - -/* Libère de la mémoire une conversion enregistrée. */ -void delete_conv_func(conv_func *); - -/* Indique la variable de destination d'une conversion. */ -const char *get_conv_dest_name(const conv_func *); - -/* Marque les champs utilisés par une fonction de conversion. */ -bool mark_conv_func(conv_func *, const coding_bits *, const conv_list *); - -/* Déclare les variables associées à une fonction de conversion. */ -bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, unsigned int); - -/* Définit les variables associées à une fonction de conversion. */ -bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); - - - -/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ - - -/* Crée un nouvelle liste vierge de fonctions de conversion. */ -conv_list *create_conv_list(void); - -/* Supprime de la mémoire une de fonctions de conversion. */ -void delete_conv_list(conv_list *); - -/* Enregistre une function de conversion du brut à l'utile. */ -void register_conversion(conv_list *, conv_func *); - -/* Recherche un résultat précis dans une liste de fonctions. */ -conv_func *find_named_conv_in_list(const conv_list *, const char *); - - - -#endif /* _TOOLS_CONV_H */ diff --git a/tools/d2c.mk b/tools/d2c.mk deleted file mode 100644 index 25596cf..0000000 --- a/tools/d2c.mk +++ /dev/null @@ -1,31 +0,0 @@ - -.NOTPARALLEL: - -d2c_verbose = $(d2c_verbose_@AM_V@) -d2c_verbose_ = $(d2c_verbose_@AM_DEFAULT_V@) -d2c_verbose_0 = @echo " D2C " $<; - -fix_verbose = $(fix_verbose_@AM_V@) -fix_verbose_ = $(fix_verbose_@AM_DEFAULT_V@) -fix_verbose_0 = echo " FIX " `basename $$f`; - -fix2_verbose = $(fix2_verbose_@AM_V@) -fix2_verbose_ = $(fix2_verbose_@AM_DEFAULT_V@) -fix2_verbose_0 = echo " FIX " `basename $<`; - -# D2C_BIN = -# D2C_OUTDIR = -# D2C_ARCH = -# D2C_HEADER = -# D2C_ENCODINGS = -# D2C_MACROS = - -SUFFIXES = .g - -.d.g: - $(d2c_verbose)$(D2C_BIN) -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS) < $< - @touch $@ - -# Merci http://www.commandlinefu.com/commands/view/10276/grep-tab-t -untabify_disass: - find $(D2C_OUTDIR)/opcodes -name '*c' -exec grep -q $$'\t' {} \; -exec sed -i 's/\t/ /g' {} \; diff --git a/tools/d2c/Makefile.am b/tools/d2c/Makefile.am new file mode 100644 index 0000000..d0fdbe8 --- /dev/null +++ b/tools/d2c/Makefile.am @@ -0,0 +1,32 @@ + +BUILT_SOURCES = d2c-d2c_gram.h + +AM_YFLAGS = -d + +bin_PROGRAMS = d2c + + +d2c_SOURCES = \ + bits.h bits.c \ + coder.h coder.c \ + conv.h conv.c \ + d2c_tok.l \ + d2c_gram.y \ + helpers.h helpers.c \ + pproc.h pproc.c \ + rules.h rules.c \ + spec.h spec.c \ + syntax.h syntax.c + +d2c_YFLAGS = -v -d -p d2c_ -o y.tab.c + +d2c_LFLAGS = -P d2c_ --header-file=d2c_tok.h -o lex.yy.c + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) + + +# Automake fait les choses à moitié +CLEANFILES = d2c_gram.h d2c_gram.c d2c-d2c_tok.c diff --git a/tools/d2c/bits.c b/tools/d2c/bits.c new file mode 100644 index 0000000..32c3fd9 --- /dev/null +++ b/tools/d2c/bits.c @@ -0,0 +1,363 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bits.c - compréhension et manipulation des champs de bits + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "bits.h" + + +#include +#include +#include +#include +#include + + +#include "helpers.h" + + + + + +/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ + + +/* Elément d'un mot décodé */ +struct _raw_bitfield +{ + char *name; /* Désignation humaine */ + unsigned int start; /* Position de départ */ + unsigned int length; /* Taille du champ */ + + bool used; /* Champ défini & utilisé */ + +}; + + + + +/* Représentation de l'ensemble des bits de codage */ +struct _coding_bits +{ + raw_bitfield *fields; /* Champs de bits détectés */ + size_t bf_count; /* Nombre de ces champs */ + uint64_t bits; /* Bits invariables */ + uint64_t mask; /* Emplacement de ces bits */ + unsigned int curpos; /* Position pendant l'analyse */ + +}; + + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à consulter. * +* * +* Description : Indique le nombre de bits utilisés par le champ. * +* * +* Retour : Nombre de bits considérés. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int get_raw_bitfield_length(const raw_bitfield *field) +{ + return field->length; + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à traiter. * +* * +* Description : Marque un champ de bits comme étant utile. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void mark_raw_bitfield_as_used(raw_bitfield *field) +{ + field->used = true; + +} + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau gestionnaire des bits d'encodage brut. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +coding_bits *create_coding_bits(void) +{ + coding_bits *result; /* Définition vierge à renvoyer*/ + + result = (coding_bits *)calloc(1, sizeof(coding_bits)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire d'un ensemble de bits à libérer. * +* * +* Description : Supprime de la mémoire un gestionnaire de bits d'encodage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_coding_bits(coding_bits *bits) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < bits->bf_count; i++) + free(bits->fields[i].name); + + if (bits->fields != NULL) + free(bits->fields); + + free(bits); + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * +* name = désignation humaine du champ remarqué. * +* length = taille du champ à mémoriser. * +* * +* Description : Note la présence d'un champ remarquable dans une définition. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_named_field_in_bits(coding_bits *bits, char *name, unsigned int length) +{ + raw_bitfield *field; /* Nouveau champ à constituer */ + + assert((bits->curpos + length) < 64); + + bits->fields = (raw_bitfield *)realloc(bits->fields, + ++bits->bf_count * sizeof(raw_bitfield)); + + field = &bits->fields[bits->bf_count - 1]; + + field->name = make_string_lower(name); + field->start = bits->curpos; + field->length = length; + + bits->curpos += length; + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * +* val = valeur du bit à prendre en compte. * +* * +* Description : Note la présence d'un bit invariable dans une définition. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_bit_in_bits(coding_bits *bits, int val) +{ + assert(bits->curpos < 64); + + bits->bits |= (val ? 1 : 0) << bits->curpos; + bits->mask |= 1 << bits->curpos; + + bits->curpos++; + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire de bits d'encodage brut à consulter. * +* * +* Description : Indique le nombre de bits traités. * +* * +* Retour : Quantité, positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int count_coded_bits(const coding_bits *bits) +{ + return bits->curpos; + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire d'encodage brut à consulter. * +* name = désignation humaine du champ à retrouver. * +* * +* Description : Recherche un champ donné dans un ensemble de champs de bits. * +* * +* Retour : Structure associée au champ trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +raw_bitfield *find_named_field_in_bits(const coding_bits *bits, const char *name) +{ + raw_bitfield *result; /* Champ de bits à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < bits->bf_count && result == NULL; i++) + if (strcmp(bits->fields[i].name, name) == 0) + result = &bits->fields[i]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* wide = taille des mots manipulés (en bits). * +* * +* Description : Déclare les variables C associées aux champs de bits. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool declare_used_bits_fields(const coding_bits *bits, int fd, unsigned int wide) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < bits->bf_count; i++) + if (bits->fields[i].used) + dprintf(fd, "\t\tuint%u_t raw_%s;\n", wide, bits->fields[i].name); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* * +* Description : Vérifie que les bits fixes correspondent au masque attendu. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool check_bits_correctness(const coding_bits *bits, int fd) +{ + dprintf(fd, "\t\tif ((raw & 0x%" PRIx64 ") != 0x%" PRIx64 ") return NULL;\n", bits->mask, bits->bits); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* * +* Description : Définit les variables C associées aux champs de bits. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_used_bits_fields(const coding_bits *bits, int fd) +{ + size_t i; /* Boucle de parcours */ + raw_bitfield *rf; /* Accès confortable à un champ*/ + + for (i = 0; i < bits->bf_count; i++) + { + rf = &bits->fields[i]; + if (!rf->used) continue; + + dprintf(fd, "\t\traw_%s = (_raw >> %u) & 0x%llx;\n", rf->name, rf->start, (1ull << rf->length) - 1); + + } + + return true; + +} diff --git a/tools/d2c/bits.h b/tools/d2c/bits.h new file mode 100644 index 0000000..aa4b7aa --- /dev/null +++ b/tools/d2c/bits.h @@ -0,0 +1,87 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bits.h - prototypes pour la compréhension et la manipulation des champs de bits + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_BITS_H +#define _TOOLS_BITS_H + + +#include + + + + +/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ + + +/* Elément d'un mot décodé */ +typedef struct _raw_bitfield raw_bitfield; + + + +/* Indique le nombre de bits utilisés par le champ. */ +unsigned int get_raw_bitfield_length(const raw_bitfield *); + +/* Marque un champ de bits comme étant utile. */ +void mark_raw_bitfield_as_used(raw_bitfield *); + + + + + +/* Représentation de l'ensemble des bits de codage */ +typedef struct _coding_bits coding_bits; + + + +/* Crée un nouveau gestionnaire des bits d'encodage brut. */ +coding_bits *create_coding_bits(void); + +/* Supprime de la mémoire un gestionnaire de bits d'encodage. */ +void delete_coding_bits(coding_bits *); + + + +/* Note la présence d'un champ remarquable dans une définition. */ +void register_named_field_in_bits(coding_bits *, char *, unsigned int); + +/* Note la présence d'un bit invariable dans une définition. */ +void register_bit_in_bits(coding_bits *, int); + +/* Indique le nombre de bits traités. */ +unsigned int count_coded_bits(const coding_bits *); + +/* Recherche un champ donné dans un ensemble de champs de bits. */ +raw_bitfield *find_named_field_in_bits(const coding_bits *, const char *); + +/* Déclare les variables C associées aux champs de bits. */ +bool declare_used_bits_fields(const coding_bits *, int, unsigned int); + +/* Vérifie que les bits fixes correspondent au masque attendu. */ +bool check_bits_correctness(const coding_bits *, int); + +/* Définit les variables C associées aux champs de bits. */ +bool define_used_bits_fields(const coding_bits *, int); + + + +#endif /* _TOOLS_BITS_H */ diff --git a/tools/d2c/coder.c b/tools/d2c/coder.c new file mode 100644 index 0000000..5856d80 --- /dev/null +++ b/tools/d2c/coder.c @@ -0,0 +1,650 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * coder.c - lecture automatisée des spécifications d'architecture + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "coder.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "helpers.h" + + + +/* -------------------------- CONSTRUCTION SELON COMMANDES -------------------------- */ + + + + + +/* Suivi des constructions */ +struct _rented_coder +{ + const char *outdir; /* Lieu d'enregistrement */ + const char *arch; /* Architecture à traiter */ + const char *header; /* En-tête pour les en-têtes */ + + pre_processor *pp; /* Pré-processeur avec macros */ + + char *copyright; /* Récupération des droits */ + char *ins; /* Désignation humaine */ + char *details; /* Eventuels compléments */ + + encoding_spec **specs; /* Définitions déjà en place */ + size_t specs_count; /* Nombre de ces définitions */ + encoding_spec *cur_spec; /* Définition courante */ + +}; + + + + +/* --------------------------- REPRESENTATION D'ENCODAGES --------------------------- */ + + + + + +/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ + + +/* Elément d'un mot décodé */ +typedef struct _dec_bitfield +{ + char *name; /* Désignation humaine */ + unsigned int start; /* Position de départ */ + unsigned int length; /* Taille du champ */ + +} dec_bitfield; + + + + + + + +/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ + + +/* Fonction de conversion */ +typedef struct _conv_func +{ + char *dest; /* Variable de destination */ + char *func; /* Fonction de conversion */ + char *arg; /* Argument de cette fonction */ + +} conv_func; + + + +/* --------------------------- GENERATIONS DE CODE SOURCE --------------------------- */ + + +/* Ouvre un fichier en écriture pour y placer du code. */ +static int create_code_file(const rented_coder *, const char *, const char *, const char *, char, bool *); + +/* Ecrit une partie des fonctions issues des spécifications. */ +static bool dump_all_matching_specs_in_coder(const rented_coder *, const string_exch *, int, int); + + + +/* ---------------------------------------------------------------------------------- */ +/* CONSTRUCTION SELON COMMANDES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Débute la définition d'une fonction de désassemblage. * +* * +* Retour : Gestionnaire mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +rented_coder *create_coder(void) +{ + rented_coder *result; /* Structure à renvoyer */ + + result = (rented_coder *)calloc(1, sizeof(rented_coder)); + + result->pp = create_pre_processor(); + + result->cur_spec = create_encoding_spec(); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* * +* Description : Supprime le codeur de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_coder(rented_coder *coder) +{ + size_t i; /* Boucle de parcours */ + + delete_pre_processor(coder->pp); + + if (coder->ins != NULL) + free(coder->ins); + + if (coder->details != NULL) + free(coder->details); + + for (i = 0; i < coder->specs_count; i++) + delete_encoding_spec(coder->specs[i]); + + if (coder->specs != NULL) + free(coder->specs); + + delete_encoding_spec(coder->cur_spec); + + free(coder); + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* * +* Description : Détermine si les propriétés de base d'un codeur sont là. * +* * +* Retour : Bilan de l'état opérationnel. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool do_basic_checks_with_coder(const rented_coder *coder) +{ + return (coder->outdir != NULL && coder->arch != NULL && coder->header != NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* outdir = répertoire de génération des fichiers. * +* * +* Description : Spécifie le répertoire de base pour les sorties de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_coder_output_directory(rented_coder *coder, const char *outdir) +{ + coder->outdir = outdir; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* arch = désignation pour le code de l'architecture lue. * +* * +* Description : Détermine l'architecture visée par les traitements. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_coder_arch(rented_coder *coder, const char *arch) +{ + coder->arch = arch; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* header = base des définitions de protection d'en-têtes. * +* * +* Description : Définit la base des protections des fichiers d'en-tête. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_coder_header_base(rented_coder *coder, const char *header) +{ + coder->header = header; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* * +* Description : Fournit le pré-processeur du compilateur. * +* * +* Retour : Pré-processeur à manipuler. * +* * +* Remarques : - * +* * +******************************************************************************/ + +pre_processor *get_coder_pre_proc(const rented_coder *coder) +{ + return coder->pp; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain.* +* copy = droits de copie en anglais. * +* ins = désignation humaine de l'instruction. * +* details = compléments d'informations éventuels ou NULL. * +* * +* Description : Enregistre les contours d'une instruction d'assemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void save_notes_for_coder(rented_coder *coder, char *copy, char *ins, const char *details) +{ + coder->copyright = copy; + coder->ins = make_string_lower(ins); + coder->details = (details != NULL ? make_callable(details, true) : strdup("")); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* REPRESENTATION D'ENCODAGES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* * +* Description : Fournit un lien vers les spécifications courantes. * +* * +* Retour : Spécification en cours d'édition. * +* * +* Remarques : - * +* * +******************************************************************************/ + +encoding_spec *get_current_encoding_spec(const rented_coder *coder) +{ + return coder->cur_spec; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* prefix = distinction principale entre les définitions. * +* index = distinction secondaire entre les définitions. * +* * +* Description : Enregistre une définition supplémentaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void push_encoding_spec(rented_coder *coder, char *prefix, unsigned int index) +{ + encoding_spec *spec; /* Définition à compléter */ + + spec = coder->cur_spec; + + define_encoding_spec_code_name(spec, prefix, index); + + coder->specs = (encoding_spec **)realloc(coder->specs, ++coder->specs_count * sizeof(encoding_spec *)); + coder->specs[coder->specs_count - 1] = spec; + + coder->cur_spec = create_encoding_spec(); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GENERATIONS DE CODE SOURCE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* dir = répertoire final de destination. * +* prefix = type d'encodage à répercuter sur le nom de fichier. * +* name = nom brut du fichier à ouvrir. * +* ext = extension à donner au fichier à ouvrir. * +* exist = indique si le fichier était présent avant. [OUT] * +* * +* Description : Ouvre un fichier en écriture pour y placer du code. * +* * +* Retour : Descripteur du fichier ouvert ou -1 en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int create_code_file(const rented_coder *coder, const char *dir, const char *prefix, const char *name, char ext, bool *exist) +{ + int result; /* Descripteur à retourner */ + size_t length; /* Taille du nom de fichier */ + char *pathname; /* Chemin d'accès à constituer */ + + length = strlen(coder->outdir) + 1 + strlen(dir) + 1 + strlen(prefix) + strlen(name) + 3; + pathname = (char *)calloc(length, sizeof(char)); + snprintf(pathname, length, "%s/%s/%s%s.%c", coder->outdir, dir, prefix, name, ext); + + *exist = (access(pathname, W_OK) == 0); + + result = open(pathname, O_WRONLY | O_CREAT | O_APPEND, 0644); + if (result == -1) perror("open()"); + + free(pathname); + + if (!*exist && result != -1) + { + dprintf(result, "\n"); + + dprintf(result, "/* Chrysalide - Outil d'analyse de fichiers binaires\n"); + dprintf(result, " * %s%s.%c - traduction d'instructions ARMv7\n", prefix, name, ext); + dprintf(result, " *\n"); + dprintf(result, " * %s\n", coder->copyright); + dprintf(result, " *\n"); + dprintf(result, " * This file is part of Chrysalide.\n"); + dprintf(result, " *\n"); + dprintf(result, " * Chrysalide is free software; you can redistribute it and/or modify\n"); + dprintf(result, " * it under the terms of the GNU General Public License as published by\n"); + dprintf(result, " * the Free Software Foundation; either version 3 of the License, or\n"); + dprintf(result, " * (at your option) any later version.\n"); + dprintf(result, " *\n"); + dprintf(result, " * Chrysalide is distributed in the hope that it will be useful,\n"); + dprintf(result, " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + dprintf(result, " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); + dprintf(result, " * GNU General Public License for more details.\n"); + dprintf(result, " *\n"); + dprintf(result, " * You should have received a copy of the GNU General Public License\n"); + dprintf(result, " * along with Foobar. If not, see .\n"); + dprintf(result, " */\n"); + + dprintf(result, "\n"); + dprintf(result, "\n"); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain.* +* * +* Description : Débute la définition des fonctions issues des spécifications.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dump_all_routines_using_coder(const rented_coder *coder) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + const string_exch *encoding; /* Type d'encodage visé */ + bool exist; /* Présence du fichier visé ? */ + int header_fd; /* Fichier de déclarations */ + char *dash; /* Présence d'un tiret ? */ + char *filename; /* Nom de fichier commun */ + int code_fd; /* Fichier de définitions */ + + result = true; + + for (i = 0; i < count_encodings(coder->pp) && result; i++) + { + encoding = find_encoding(coder->pp, i); + + /* Fichier de déclarations */ + + header_fd = create_code_file(coder, "opcodes", encoding->dest, "opcodes", 'h', &exist); + if (header_fd == -1) return false; + + if (!exist) + { + dprintf(header_fd, "#ifndef %s_OPCODES_OPCODES_H\n", coder->header); + dprintf(header_fd, "#define %s_OPCODES_OPCODES_H\n", coder->header); + + dprintf(header_fd, "\n"); + dprintf(header_fd, "\n"); + dprintf(header_fd, "##INCLUDES##\n"); + dprintf(header_fd, "\n"); + dprintf(header_fd, "\n"); + dprintf(header_fd, "\n"); + + } + + /* Fichier de définitions */ + + dash = strchr(coder->ins, '-'); + + if (dash == NULL) + code_fd = create_code_file(coder, "opcodes", encoding->dest, coder->ins, 'c', &exist); + + else + { + filename = strdup(coder->ins); + + dash = strchr(filename, '-'); + *dash = '\0'; + + code_fd = create_code_file(coder, "opcodes", encoding->dest, filename, 'c', &exist); + + free(filename); + + } + + if (!exist) + { + dprintf(code_fd, "#include \"opcodes.h\"\n"); + dprintf(code_fd, "\n"); + dprintf(code_fd, "##INCLUDES##\n"); + + } + + if (code_fd == -1) + { + close(header_fd); + return false; + } + + /* Production de code... */ + + result = dump_all_matching_specs_in_coder(coder, encoding, header_fd, code_fd); + + close(header_fd); + close(code_fd); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement d'humain. * +* encoding = sélection de l'encodage à traiter. * +* hfd = flux ouvert en écriture pour les déclarations. * +* cfd = flux ouvert en écriture pour les définitions. * +* * +* Description : Ecrit une partie des fonctions issues des spécifications. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool dump_all_matching_specs_in_coder(const rented_coder *coder, const string_exch *encoding, int hfd, int cfd) +{ + bool result; /* Bilan à retourner */ + char *keyword; /* Mot clef appelable en code */ + unsigned int wide; /* Taille des mots */ + size_t i; /* Boucle de parcours */ + encoding_spec *spec; /* Définition à traiter */ + coding_bits *bits; /* Gestionnaire de bits */ + size_t maxlen; /* Taille à compléter */ + + result = true; + + keyword = make_callable(coder->ins, false); + + /* Recherche de la taille des mots */ + + wide = -1; + + for (i = 0; i < coder->specs_count; i++) + { + spec = coder->specs[i]; + + if (!has_encoding_spec_prefix(spec, encoding->src)) + continue; + + bits = get_bits_in_encoding_spec(spec); + wide = count_coded_bits(bits); + break; + + } + + /* Rien n'a été trouvé à faire... */ + if (wide == -1) goto damsic_exit; + + /* Désassemblage : déclaration */ + + dprintf(hfd, "/* Décode une instruction de type '%s'. */\n", coder->ins); + dprintf(hfd, "GArchInstruction *%s_read_instr_%s%s(uint%u_t);\n", coder->arch, keyword, coder->details, wide); + dprintf(hfd, "\n"); + + /* Désassemblage : définitions */ + + dprintf(cfd, "\n"); + + dprintf(cfd, "/******************************************************************************\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "* Paramètres : raw = données brutes à analyser. *\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "* Description : Décode une instruction de type '%s'.", coder->ins); + + maxlen = 28 - strlen(coder->ins); + + if (maxlen < 28) + dprintf(cfd, "%*s\n", (int)maxlen, "*"); + else + dprintf(cfd, "*\n"); + + dprintf(cfd, " *\n"); + dprintf(cfd, "* Retour : Bilan de l'opération. *\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "* Remarques : - *\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "******************************************************************************/\n"); + + dprintf(cfd, "\n"); + + dprintf(cfd, "GArchInstruction *%s_read_instr_%s%s(uint%u_t raw)", coder->arch, keyword, coder->details, wide); + dprintf(cfd, "\n"); + dprintf(cfd, "{"); + dprintf(cfd, "\n"); + + dprintf(cfd, "\tGArchInstruction *result; /* Instruction créée à renvoyer*/\n"); + + dprintf(cfd, "\n"); + dprintf(cfd, "\tresult = NULL;\n"); + dprintf(cfd, "\n"); + + for (i = 0; i < coder->specs_count && result; i++) + { + spec = coder->specs[i]; + + if (!has_encoding_spec_prefix(spec, encoding->src)) + continue; + + result = write_encoding_spec_disass(spec, cfd, coder->arch, coder->ins, coder->details, wide, coder->pp); + + } + + dprintf(cfd, "\treturn result;\n"); + dprintf(cfd, "\n"); + + dprintf(cfd, "}\n"); + dprintf(cfd, "\n"); + + damsic_exit: + + free(keyword); + + return result; + +} diff --git a/tools/d2c/coder.h b/tools/d2c/coder.h new file mode 100644 index 0000000..e72764c --- /dev/null +++ b/tools/d2c/coder.h @@ -0,0 +1,125 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * coder.h - prototypes pour la lecture automatisée des spécifications d'architecture + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _ARCH_ARM_V7_OPDEFS_CODER_H +#define _ARCH_ARM_V7_OPDEFS_CODER_H + + +#include + + +#include "pproc.h" +#include "spec.h" + + + +/* Suivi des constructions */ +typedef struct _rented_coder rented_coder; + + + +/* -------------------------- CONSTRUCTION SELON COMMANDES -------------------------- */ + + +/* Débute la définition d'une fonction de désassemblage. */ +rented_coder *create_coder(void); + +/* Supprime le codeur de la mémoire. */ +void delete_coder(rented_coder *); + +/* Détermine si les propriétés de base d'un codeur sont là. */ +bool do_basic_checks_with_coder(const rented_coder *); + +/* Spécifie le répertoire de base pour les sorties de code. */ +void set_coder_output_directory(rented_coder *, const char *); + +/* Détermine l'architecture visée par les traitements. */ +void set_coder_arch(rented_coder *, const char *); + +/* Définit la base des protections des fichiers d'en-tête. */ +void set_coder_header_base(rented_coder *, const char *); + +/* Fournit le pré-processeur du compilateur. */ +pre_processor *get_coder_pre_proc(const rented_coder *); + +/* Enregistre les contours d'une instruction d'assemblage. */ +void save_notes_for_coder(rented_coder *, char *, char *, const char *); + + + +/* --------------------------- REPRESENTATION D'ENCODAGES --------------------------- */ + + +/* Fournit un lien vers les spécifications courantes. */ +encoding_spec *get_current_encoding_spec(const rented_coder *); + +/* Enregistre une définition supplémentaire. */ +void push_encoding_spec(rented_coder *, char *, unsigned int); + + + +/* --------------------------- GESTION DES CHAMPS DE BITS --------------------------- */ + + +/* Note la présence d'un champ remarquable dans une définition. */ +void register_named_field_in_coder(rented_coder *, char *, unsigned int); + +/* Note la présence d'un bit invariable dans une définition. */ +void register_bit_in_coder(rented_coder *, int); + +/* Indique le nombre de bits traités. */ +//unsigned int count_coder_bits(const rented_coder *); + + + +/* ---------------------------- SYNTAXE DES INSTRUCTIONS ---------------------------- */ + + +/* Enregistre la présence d'un nouvel opérande. */ +void register_syntax_item_in_coder(rented_coder *, char *, bool); + + + +/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ + + +/* Enregistre la function de conversion du brut à l'utile. */ +void register_conversion_in_coder(rented_coder *, conv_func *); + + + +/* --------------------------- CONDITIONS ET CONSEQUENCES --------------------------- */ + + + + + +/* --------------------------- GENERATIONS DE CODE SOURCE --------------------------- */ + + +/* Débute la définition des fonctions issues des spécifications. */ +bool dump_all_routines_using_coder(const rented_coder *); + + + +#endif /* _ARCH_ARM_V7_OPDEFS_CODER_H */ diff --git a/tools/d2c/conv.c b/tools/d2c/conv.c new file mode 100644 index 0000000..323f63d --- /dev/null +++ b/tools/d2c/conv.c @@ -0,0 +1,1640 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * conv.c - substitutions de valeurs depuis un contenu binaire + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "conv.h" + + +#include +#include +#include +#include +#include +#include +#include + + +#include "helpers.h" + + + + + +/* Types d'expressions représentés */ +typedef enum _ConvExprType +{ + CET_NAME, /* Désignation de variable */ + CET_NUMBER, /* Valeur codée en dur */ + CET_COMPOSED, /* Agrégat de champs divers */ + CET_UNARY, /* Opération unaire */ + CET_BINARY, /* Opération binaire */ + + CET_COUNT + +} ConvExprType; + + +/* Représentation d'une expression de conversion */ +struct _conv_expr_t +{ + ConvExprType type; + + bool declared; /* Expression déjà déclarée ? */ + bool defined; /* Expression déjà définie ? */ + + union + { + /* CET_NAME */ + char *name; /* Désignation de variable */ + + /* CET_NUMBER */ + unsigned long number; /* Valeur durablement définie */ + + /* CET_COMPOSED */ + struct + { + char **comp_items; /* Elements à agréger */ + size_t comp_count; /* Quantité de ces éléments */ + }; + + /* CET_UNARY */ + struct + { + conv_expr_t *un_expr; /* Expression à traiter */ + ConvUnaryOperation un_op; /* Type d'opération à mener */ + + }; + + /* CET_BINARY */ + struct + { + conv_expr_t *bin_expr1; /* Expression à traiter */ + conv_expr_t *bin_expr2; /* Expression à traiter */ + ConvBinaryOperation bin_op; /* Type d'opération à mener */ + + }; + + }; + +}; + + +/* Visite une expression en traitant en premier ses composantes. */ +typedef bool (* visit_expr_fc) (conv_expr_t *, int, const coding_bits *, const conv_list *, void *); + + +/* Détermine la taille en bits d'une expression donnée. */ +static bool compute_conv_expr_size(const conv_expr_t *, const coding_bits *, const conv_list *, unsigned int *); + +/* Visite une expression en traitant en premier ses composantes. */ +static bool visit_conv_expr(conv_expr_t *, visit_expr_fc, int, const coding_bits *, const conv_list *, void *); + +/* Retrouve si elle existe une variable manipulée. */ +static bool find_var_by_name(const coding_bits *, const conv_list *, const char *, raw_bitfield **, conv_func **); + +/* S'assure du marquage des expressions pre-requises. */ +static bool ensure_conv_expr_content_fully_marked(conv_expr_t *, const coding_bits *, const conv_list *); + +/* S'assure de la déclaration des expressions pre-requises. */ +static bool ensure_conv_expr_content_fully_declared(conv_expr_t *, int, const coding_bits *, const conv_list *, unsigned int); + +/* S'assure de la définition des expressions pre-requises. */ +static bool ensure_conv_expr_content_fully_defined(conv_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); + +/* Définit une expression utilisée dans une conversion. */ +static bool define_conv_expr(conv_expr_t *, int, const coding_bits *, const conv_list *); + + + +/* ------------------------ LISTES D'ARGUMENTS DE CONVERSION ------------------------ */ + + +/* Liste d'expressions utilisées en arguments de conversion */ +struct _conv_arg_list_t +{ + conv_expr_t **items; /* Liste d'expressions */ + size_t count; /* Taille de cette liste */ + +}; + + +/* S'assure du marquage des expressions pre-requises. */ +static bool ensure_arg_list_content_fully_marked(conv_arg_list_t *, const coding_bits *, const conv_list *); + +/* S'assure de la déclaration des expressions pre-requises. */ +static bool ensure_arg_list_content_fully_declared(conv_arg_list_t *, int, const coding_bits *, const conv_list *, unsigned int); + +/* S'assure de la définition des expressions pre-requises. */ +static bool ensure_arg_list_content_fully_defined(conv_arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); + +/* Définit les variables associées à un appel de fonction. */ +static bool define_arg_list(conv_arg_list_t *, int, const coding_bits *, const conv_list *); + + + +/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ + + +/* Fonction de conversion */ +struct _conv_func +{ + bool declared; /* Expression déjà déclarée ? */ + bool defined; /* Expression déjà définie ? */ + + char *dest; /* Variable de destination */ + + bool is_expr; /* Choix du contenu réel */ + + union + { + conv_expr_t *expr; /* Valeur expressive directe */ + + struct + { + char *name; /* Fonction de conversion */ + conv_arg_list_t *args; /* Liste des arguments */ + + }; + + }; + +}; + + +/* Détermine la taille en bits du résultat d'une fonction. */ +static bool compute_conv_func_size(const conv_func *, const coding_bits *, const conv_list *, unsigned int *); + + + + + + +#define delete_conv_expr(e) + + + + + + +/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ + + +/* Liste des fonctions de conversions présentes */ +struct _conv_list +{ + conv_func **functions; /* Fonctions de conversion */ + size_t func_count; /* Nombre de ces fonctions */ + +}; + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : name = désignation d'une variable quelconque. * +* * +* Description : Référence une variable en tant qu'expression de conversion. * +* * +* Retour : Nouvelle expression mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *build_conv_expr_from_name(char *name) +{ + conv_expr_t *result; /* Structure à retourner */ + + result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); + + result->type = CET_NAME; + + result->name = make_string_lower(name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : number = valeur à conserver dans sa forme brute. * +* * +* Description : Conserve une valeur en tant qu'expression de conversion. * +* * +* Retour : Nouvelle expression mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *build_conv_expr_from_number(unsigned long number) +{ + conv_expr_t *result; /* Structure à retourner */ + + result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); + + result->type = CET_NUMBER; + + result->number = number; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item1 = premier élément à agréger. * +* item2 = second élément à agréger. * +* * +* Description : Construit une base d'expression de conversion composée. * +* * +* Retour : Nouvelle expression mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *build_composed_conv_expr(char *item1, char *item2) +{ + conv_expr_t *result; /* Structure à retourner */ + + result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); + + result->type = CET_COMPOSED; + + result->comp_items = (char **)calloc(2, sizeof(char *)); + result->comp_count = 2; + + result->comp_items[0] = make_string_lower(item1); + result->comp_items[1] = make_string_lower(item2); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = expression déjà en place à compléter. * +* item = nouvel élément à agréger. * +* * +* Description : Etend une base d'expression de conversion composée. * +* * +* Retour : Expression en place et mise à jour. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *extend_composed_conv_expr(conv_expr_t *expr, char *item) +{ + assert(expr->type == CET_COMPOSED); + + expr->comp_items = (char **)realloc(expr->comp_items, ++expr->comp_count * sizeof(char *)); + + expr->comp_items[expr->comp_count - 1] = make_string_lower(item); + + return expr; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = expression à encapsuler. * +* op = opération unaire à associer à l'opération. * +* * +* Description : Traduit une opération unaire sur expression de conversion. * +* * +* Retour : Nouvelle expression mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *build_unary_conv_expr(conv_expr_t *expr, ConvUnaryOperation op) +{ + conv_expr_t *result; /* Structure à retourner */ + + result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); + + result->type = CET_UNARY; + + result->un_expr = expr; + result->un_op = op; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr1 = première expression à encapsuler. * +* expr2 = seconde expression à encapsuler. * +* op = opération binaire à associer à l'opération. * +* * +* Description : Traduit une opération binaire sur expression de conversion. * +* * +* Retour : Nouvelle expression mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_expr_t *build_binary_conv_expr(conv_expr_t *expr1, conv_expr_t *expr2, ConvBinaryOperation op) +{ + conv_expr_t *result; /* Structure à retourner */ + + result = (conv_expr_t *)calloc(1, sizeof(conv_expr_t)); + + result->type = CET_BINARY; + + result->bin_expr1 = expr1; + result->bin_expr2 = expr2; + result->bin_op = op; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à consulter. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* size = taille déterminée avec précision. [OUT] * +* * +* Description : Détermine la taille en bits d'une expression donnée. * +* * +* Retour : true si la taille a pu être déterminée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool compute_conv_expr_size(const conv_expr_t *expr, const coding_bits *bits, const conv_list *list, unsigned int *size) +{ + bool result; /* Bilan à retourner */ + raw_bitfield *field; /* Eventuel champ brut associé */ + conv_func *func; /* Eventuelle fonction liée */ + size_t i; /* Boucle de parcours */ + unsigned int tmp; /* Stockage temporaire */ + + switch (expr->type) + { + case CET_NAME: + + result = find_var_by_name(bits, list, expr->name, &field, &func); + + if (result) + { + if (field != NULL) + *size = get_raw_bitfield_length(field); + else + result = compute_conv_func_size(func, bits, list, size); + } + + break; + + case CET_COMPOSED: + + result = true; + *size = 0; + + for (i = 0; i < expr->comp_count && result; i++) + { + if (isdigit(expr->comp_items[i][0])) + *size += strlen(expr->comp_items[i]); + + else + { + if (!find_var_by_name(bits, list, expr->comp_items[i], &field, &func)) + result = false; + + else + { + if (field != NULL) + *size += get_raw_bitfield_length(field); + else + { + result = compute_conv_func_size(func, bits, list, &tmp); + *size += tmp; + } + } + + } + + } + + break; + + case CET_UNARY: + result = compute_conv_expr_size(expr->un_expr, bits, list, size); + break; + + case CET_BINARY: + + result = compute_conv_expr_size(expr->bin_expr1, bits, list, &tmp); + + if (result) + result = compute_conv_expr_size(expr->bin_expr1, bits, list, size); + + if (tmp > *size) *size = tmp; + + break; + + default: + result = false; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à encapsuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* data = éventuelle donnée à transmettre à chaque visite. * +* * +* Description : Visite une expression en traitant en premier ses composantes.* +* * +* Retour : Bilan des traitements effectués. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool visit_conv_expr(conv_expr_t *expr, visit_expr_fc visit, int fd, const coding_bits *bits, const conv_list *list, void *data) +{ + bool result; /* Bilan à retourner */ + + switch (expr->type) + { + case CET_UNARY: + result = visit_conv_expr(expr->un_expr, visit, fd, bits, list, data); + break; + + case CET_BINARY: + result = visit_conv_expr(expr->bin_expr1, visit, fd, bits, list, data); + result = visit_conv_expr(expr->bin_expr2, visit, fd, bits, list, data); + break; + + default: + result = true; + break; + + } + + result &= visit(expr, fd, bits, list, data); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* name = déssignation de la variable recherchée. * +* field = éventuel élement brut de décodage. * +* func = éventuelle fonction de conversion pour intermédiaire.* +* * +* Description : Retrouve si elle existe une variable manipulée. * +* * +* Retour : Bilan des recherches : trouvaille ou non ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool find_var_by_name(const coding_bits *bits, const conv_list *list, const char *name, raw_bitfield **field, conv_func **func) +{ + bool result; /* Bilan à retourner */ + raw_bitfield *cached_field; /* Champ, version cachée */ + conv_func *cached_func; /* Fonction, version cachée */ + + cached_field = find_named_field_in_bits(bits, name); + result = (cached_field != NULL); + + if (!result) + { + cached_func = find_named_conv_in_list(list, name); + result = (cached_func != NULL); + } + else + cached_func = NULL; + + if (field != NULL) *field = cached_field; + if (func != NULL) *func = cached_func; + + if (!result) + fprintf(stderr, "Variable '%s' not found!\n", name); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à encapsuler. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : S'assure du marquage des expressions pre-requises. * +* * +* Retour : Bilan des traitements effectués. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_conv_expr_content_fully_marked(conv_expr_t *expr, const coding_bits *bits, const conv_list *list) +{ + bool mark_sub_expr(conv_expr_t *sub, int dummy, const coding_bits *bts, const conv_list *lst, void *unused) + { + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + bool mark_by_name(const coding_bits *_bts, const conv_list *_lst, const char *name) + { + bool found; /* Bilan d'opération à renvoyer*/ + raw_bitfield *field; /* Eventuel champ brut associé */ + + found = find_var_by_name(bts, lst, name, &field, NULL); + + if (found && field != NULL) + mark_raw_bitfield_as_used(field); + + return found; + + } + + /* Il est uniquement nécessaire de s'attacher aux références */ + switch (sub->type) + { + case CET_NAME: + result = mark_by_name(bits, lst, sub->name); + break; + + case CET_COMPOSED: + result = true; + for (i = 0; i < sub->comp_count && result; i++) + if (!isdigit(sub->comp_items[i][0])) + result = mark_by_name(bits, lst, sub->comp_items[i]); + break; + + default: + result = true; + break; + + } + + return result; + + } + + return visit_conv_expr(expr, (visit_expr_fc)mark_sub_expr, -1, bits, list, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à encapsuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* wide = taille des mots décodés. * +* * +* Description : S'assure de la déclaration des expressions pre-requises. * +* * +* Retour : Bilan des traitements effectués. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_conv_expr_content_fully_declared(conv_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) +{ + bool declare_sub_expr(conv_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wide) + { + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + /* Si l'expression a déjà été définie lors d'un précédent besoin... */ + if (sub->declared) return true; + + bool declare_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, unsigned int _wide, const char *name) + { + bool found; /* Bilan d'opération à renvoyer*/ + conv_func *func; /* Eventuelle fonction liée */ + + found = find_var_by_name(bts, lst, name, NULL, &func); + + if (found && func != NULL) + { + dprintf(_f, "\t\tuint%u_t val_%s;\n", _wide, name); + found = declare_conv_func(func, _f, _bts, _lst, _wide); + } + + return found; + + } + + /* Il est uniquement nécessaire de s'attacher aux références */ + switch (sub->type) + { + case CET_NAME: + result = declare_by_name(f, bits, lst, *wide, sub->name); + break; + + case CET_COMPOSED: + result = true; + for (i = 0; i < sub->comp_count && result; i++) + if (!isdigit(sub->comp_items[i][0])) + printf("... trying to declare... '%s'\n", sub->comp_items[i]); + for (i = 0; i < sub->comp_count && result; i++) + if (!isdigit(sub->comp_items[i][0])) + result = declare_by_name(f, bits, lst, *wide, sub->comp_items[i]); + break; + + default: + result = true; + break; + + } + + sub->declared = result; + + return result; + + } + + return visit_conv_expr(expr, (visit_expr_fc)declare_sub_expr, fd, bits, list, &wide); + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à encapsuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* pp = pré-processeur pour les échanges de chaînes. * +* * +* Description : S'assure de la définition des expressions pre-requises. * +* * +* Retour : Bilan des traitements effectués. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_conv_expr_content_fully_defined(conv_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) +{ + typedef struct _def_info + { + const char *arch; + const pre_processor *pp; + + } def_info; + + def_info info; /* Transmissions au visiteur */ + + bool define_sub_expr(conv_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, def_info *info) + { + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + /* Si l'expression a déjà été définie lors d'un précédent besoin... */ + if (sub->defined) return true; + + bool define_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, def_info *_info, const char *name) + { + bool found; /* Bilan d'opération à renvoyer*/ + conv_func *func; /* Eventuelle fonction liée */ + + found = find_var_by_name(bts, lst, name, NULL, &func); + + if (found && func != NULL) + found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp); + + return found; + + } + + /* Il est uniquement nécessaire de s'attacher aux références */ + switch (sub->type) + { + case CET_NAME: + result = define_by_name(f, bits, lst, info, sub->name); + break; + + case CET_COMPOSED: + result = true; + for (i = 0; i < sub->comp_count && result; i++) + if (!isdigit(sub->comp_items[i][0])) + result = define_by_name(f, bits, lst, info, sub->comp_items[i]); + break; + + default: + result = true; + break; + + } + + sub->defined = result; + + return result; + + } + + info.arch = arch; + info.pp = pp; + + return visit_conv_expr(expr, (visit_expr_fc)define_sub_expr, fd, bits, list, &info); + +} + + +/****************************************************************************** +* * +* Paramètres : expr = première expression à encapsuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Définit une expression utilisée dans une conversion. * +* * +* Retour : Bilan des traitements effectués. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool define_conv_expr(conv_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à retourner */ + raw_bitfield *field; /* Eventuel champ brut associé */ + conv_func *func; /* Eventuelle fonction liée */ + unsigned int max_size; /* Quantité de bits totale */ + size_t i; /* Boucle de parcours */ + const char *cname; /* Raccourci de confort */ + unsigned int used_size; /* Quantité de bits utilisée */ + + result = true; + + switch (expr->type) + { + case CET_NAME: + + if (!find_var_by_name(bits, list, expr->name, &field, &func)) + result = false; + + else + { + if (field != NULL) + dprintf(fd, "raw_%s", expr->name); + else + dprintf(fd, "val_%s", expr->name); + } + + break; + + case CET_NUMBER: + dprintf(fd, "%lu", expr->number); + break; + + case CET_COMPOSED: + + result = compute_conv_expr_size(expr, bits, list, &max_size); + + printf("MAX SIZE :: %u\n", max_size); + + for (i = 0; i < expr->comp_count && result; i++) + { + cname = expr->comp_items[i]; + + if (i > 0) + dprintf(fd, " | "); + + /* Constante binaire ? */ + if (isdigit(cname[0])) + { + max_size -= strlen(cname); + + if (max_size == 0) + dprintf(fd, "b%s", cname); + else + dprintf(fd, "b%s << %u", cname, max_size); + + } + + /* Ou variable définie ? */ + else + { + result = find_var_by_name(bits, list, cname, &field, &func); + + if (result) + { + if (field != NULL) + used_size = get_raw_bitfield_length(field); + else + /*result = */compute_conv_func_size(func, bits, list, &used_size); + + max_size -= used_size; + + if (field != NULL) + { + if (max_size == 0) + dprintf(fd, "raw_%s", cname); + else + dprintf(fd, "raw_%s << %u", cname, max_size); + } + else + { + if (max_size == 0) + dprintf(fd, "val_%s", cname); + else + dprintf(fd, "val_%s << %u", cname, max_size); + } + + } + + } + + } + + break; + + case CET_UNARY: + + switch (expr->un_op) + { + case CUO_NOT: + dprintf(fd, "!"); + break; + default: + result = false; + break; + } + + result &= define_conv_expr(expr->un_expr, fd, bits, list); + + break; + + case CET_BINARY: + + dprintf(fd, "("); + + result = define_conv_expr(expr->bin_expr1, fd, bits, list); + + switch (expr->bin_op) + { + case CBO_EOR: + dprintf(fd, " ^ "); + break; + default: + result = false; + break; + } + + result &= define_conv_expr(expr->bin_expr2, fd, bits, list); + + dprintf(fd, ")"); + + break; + + default: + result = false; + break; + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* LISTES D'ARGUMENTS DE CONVERSION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : expr = expression initial pour constituer une liste. * +* * +* Description : Crée une liste d'arguments de conversion. * +* * +* Retour : Nouvelle structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_arg_list_t *build_conv_arg_list(conv_expr_t *expr) +{ + conv_arg_list_t *result; /* Structure à retourner */ + + result = (conv_arg_list_t *)calloc(1, sizeof(conv_arg_list_t)); + + result->items = (conv_expr_t **)calloc(1, sizeof(conv_expr_t *)); + result->count = 1; + + result->items[0] = expr; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste d'expressions à supprimer de la mémoire. * +* * +* Description : Libère la mémoire occupée par une liste d'expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_conv_arg_list(conv_arg_list_t *list) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->count; i++) + delete_conv_expr(list->items[i]); + + if (list->items != NULL) + free(list->items); + + free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste d'expressions à supprimer de la mémoire. [OUT] * +* expr = expression à ajouter à la liste courante. * +* * +* Description : Ajoute un élément à une liste d'arguments de conversion. * +* * +* Retour : Structure en place mise à jour. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_arg_list_t *extend_conv_arg_list(conv_arg_list_t *list, conv_expr_t *expr) +{ + list->items = (conv_expr_t **)realloc(list->items, ++list->count * sizeof(conv_expr_t *)); + + list->items[list->count - 1] = expr; + + return list; + +} + + +/****************************************************************************** +* * +* Paramètres : args = liste d'expressions à supprimer de la mémoire. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : S'assure du marquage des expressions pre-requises. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_arg_list_content_fully_marked(conv_arg_list_t *args, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à remonter */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < args->count && result; i++) + result = ensure_conv_expr_content_fully_marked(args->items[i], bits, list); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : args = liste d'expressions à supprimer de la mémoire. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* wide = taille des mots décodés. * +* * +* Description : S'assure de la déclaration des expressions pre-requises. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_arg_list_content_fully_declared(conv_arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) +{ + bool result; /* Bilan à remonter */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < args->count && result; i++) + result = ensure_conv_expr_content_fully_declared(args->items[i], fd, bits, list, wide); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : args = liste d'expressions à supprimer de la mémoire. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* pp = pré-processeur pour les échanges de chaînes. * +* * +* Description : S'assure de la définition des expressions pre-requises. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool ensure_arg_list_content_fully_defined(conv_arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) +{ + bool result; /* Bilan à remonter */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < args->count && result; i++) + result = ensure_conv_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : args = liste d'expressions à supprimer de la mémoire. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Définit les variables associées à un appel de fonction. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool define_arg_list(conv_arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à remonter */ + size_t i; /* Boucle de parcours */ + + result = true; + + for (i = 0; i < args->count && result; i++) + { + if (i > 0) dprintf(fd, ", "); + result = define_conv_expr(args->items[i], fd, bits, list); + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONVERSION DES ARGUMENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : dest = désignation de la variable de destination. * +* expr = expression dont la valeur est à assigner. * +* * +* Description : Définit une conversion à partir d'une simple expression. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *make_conv_from_expr(char *dest, conv_expr_t *expr) +{ + conv_func *result; /* Conversion à retourner */ + + result = (conv_func *)calloc(1, sizeof(conv_func)); + + result->dest = make_string_lower(dest); + + result->is_expr = true; + result->expr = expr; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = désignation de la variable de destination. * +* func = nom de la fonction assurant le calcul de valeur. * +* args = argument(s) à fournir à cette fonction. * +* * +* Description : Définit une conversion à partir d'une function à appeler. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *make_conv_from_func(char *dest, char *func, conv_arg_list_t *args) +{ + conv_func *result; /* Conversion à retourner */ + + result = (conv_func *)calloc(1, sizeof(conv_func)); + + result->dest = make_string_lower(dest); + + result->is_expr = false; + result->name = func; + result->args = args; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = éléments de conversion à supprimer de la mémoire. * +* * +* Description : Libère de la mémoire une conversion enregistrée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_conv_func(conv_func *func) +{ + if (func->is_expr) + delete_conv_expr(func->expr); + + else + { + free(func->name); + delete_conv_arg_list(func->args); + } + + free(func); + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à consulter. * +* * +* Description : Indique la variable de destination d'une conversion. * +* * +* Retour : Désignation humaine de la variable de destination. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_conv_dest_name(const conv_func *func) +{ + return func->dest; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à consulter. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* size = taille déterminée avec précision. [OUT] * +* * +* Description : Détermine la taille en bits du résultat d'une fonction. * +* * +* Retour : true si la taille a pu être déterminée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, const conv_list *list, unsigned int *size) +{ + bool result; /* Bilan à retourner */ + + result = func->is_expr; + + if (result) + result = compute_conv_expr_size(func->expr, bits, list, size); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Marque les champs utilisés par une fonction de conversion. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à remonter */ + + if (func->is_expr) + result = ensure_conv_expr_content_fully_marked(func->expr, bits, list); + else + result = ensure_arg_list_content_fully_marked(func->args, bits, list); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* wide = taille des mots décodés. * +* * +* Description : Déclare les variables associées à une fonction de conversion.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) +{ + bool result; /* Bilan à remonter */ + + /* Si la fonction a déjà été définie lors d'un précédent besoin... */ + if (func->declared) return true; + + if (func->is_expr) + result = ensure_conv_expr_content_fully_declared(func->expr, fd, bits, list, wide); + else + result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide); + + func->declared = result; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* last = précise si la conversion est la dernière. * +* internal = indique le type de manipulation finale. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* pp = pré-processeur pour les échanges de chaînes. * +* * +* Description : Définit les variables associées à une fonction de conversion.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) +{ + bool result; /* Bilan à remonter */ + const char *callable; /* Fonction à appeler */ + regex_t preg; /* Expression régulière */ + int ret; /* Bilan d'une manipulation */ + regmatch_t pmatch[3]; /* Correspondances de chaînes */ + size_t cmplen; /* Taille de comparaison */ + char *cast; /* Macro de transtypage */ + + /* Si la fonction a déjà été définie lors d'un précédent besoin... */ + if (func->defined) return true; + + if (func->is_expr) + result = ensure_conv_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp); + else + result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp); + + /* Nom de la fonction effectivement appelée */ + + if (!func->is_expr) + { + callable = find_macro(pp, func->name); + + if (callable == NULL) + callable = func->name; + + } + else callable = NULL; + + if (last && callable == NULL) + { + fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest); + return false; + } + + /* Dernier niveau : la variable de destination est imposée ! */ + if (last) + { + /* Si l'on doit manipuler une propriété d'instructon... */ + if (internal) + { + ret = regcomp(&preg, "(g_([a-z0-9]*)_instruction)", REG_EXTENDED); + if (ret != 0) + { + fprintf(stderr, "Internal error: bad regular expression.\n"); + return false; + } + + ret = regexec(&preg, callable, sizeof(pmatch) / sizeof(regmatch_t), pmatch, 0); + if (ret == REG_NOMATCH) + { + fprintf(stderr, "Internal error: bad function for dealing wih instruction: '%s'.\n", callable); + result = false; + goto dcf_skip_internal; + } + + /** + * La variable de résultat est de type 'GArchInstruction', + * donc toute fonction différente de g_arch_instruction_*() attend un transtypage... + */ + + cmplen = MAX(strlen(arch), pmatch[2].rm_eo - pmatch[2].rm_so); + + if (strncmp("arch", &callable[pmatch[2].rm_so], cmplen) == 0) + dprintf(fd, "\t\tif (!%s(instr, ", callable); + + else + { + cast = strndup(&callable[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so); + + cast = make_string_upper(cast); + + dprintf(fd, "\t\tif (!%s(%s(instr), ", callable, cast); + + free(cast); + + } + + result &= define_arg_list(func->args, fd, bits, list); + + dprintf(fd, "))\n"); + + dcf_skip_internal: + + regfree(&preg); + + } + + /* Si on doit constituer un opérande à ajouter... */ + else + { + if (strchr(callable, '(') == NULL) + dprintf(fd, "\t\top = %s(", callable); + else + dprintf(fd, "\t\top = %s", callable); + + result &= define_arg_list(func->args, fd, bits, list); + + dprintf(fd, ");\n"); + + } + + } + + /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */ + else + { + dprintf(fd, "\t\tval_%s = ", func->dest); + + if (func->is_expr) + result &= define_conv_expr(func->expr, fd, bits, list); + + else + { + dprintf(fd, "%s(", callable); + + result = define_arg_list(func->args, fd, bits, list); + + dprintf(fd, ")"); + + } + + dprintf(fd, ";\n"); + + } + + func->defined = result; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ENSEMBLES DE CONVERSIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouvelle liste vierge de fonctions de conversion. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_list *create_conv_list(void) +{ + conv_list *result; /* Définition vierge à renvoyer*/ + + result = (conv_list *)calloc(1, sizeof(conv_list)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de fonctions de conversion à supprimer. * +* * +* Description : Supprime de la mémoire une de fonctions de conversion. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_conv_list(conv_list *list) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->func_count; i++) + delete_conv_func(list->functions[i]); + + if (list->functions != NULL) + free(list->functions); + + free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de fonctions de conversion à compléter. * +* func = nom de la fonction assurant le calcul de valeur. * +* * +* Description : Enregistre une function de conversion du brut à l'utile. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_conversion(conv_list *list, conv_func *func) +{ + list->functions = (conv_func **)realloc(list->functions, ++list->func_count * sizeof(conv_func *)); + + list->functions[list->func_count - 1] = func; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de fonctions de conversion à consulter. * +* name = désignation humaine du champ à retrouver. * +* * +* Description : Recherche un résultat précis dans une liste de fonctions. * +* * +* Retour : Structure associée au résulat trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *find_named_conv_in_list(const conv_list *list, const char *name) +{ + conv_func *result; /* Fonction à retourner */ + size_t i; /* Boucle de parcours */ + const char *dest; /* Nom de variable existante */ + + result = NULL; + + for (i = 0; i < list->func_count && result == NULL; i++) + { + dest = get_conv_dest_name(list->functions[i]); + + if (strcmp(dest, name) == 0) + result = list->functions[i]; + + } + + return result; + +} diff --git a/tools/d2c/conv.h b/tools/d2c/conv.h new file mode 100644 index 0000000..acf007b --- /dev/null +++ b/tools/d2c/conv.h @@ -0,0 +1,160 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * conv.h - prototypes pour les substitutions de valeurs depuis un contenu binaire + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_CONV_H +#define _TOOLS_CONV_H + + +#include "bits.h" +#include "pproc.h" + + + + +/* Liste des fonctions de conversions présentes */ +typedef struct _conv_list conv_list; + + + + + + + +/* Types d'opérations unaires */ +typedef enum _ConvUnaryOperation +{ + CUO_NOT, /* NOT (booléen) */ + + CUO_COUNT + +} ConvUnaryOperation; + + + +/* Types d'opérations binaires */ +typedef enum _ConvBinaryOperation +{ + CBO_EOR, /* Ou exclusif (booléen) */ + + CBO_COUNT + +} ConvBinaryOperation; + + +/* Représentation d'une expression de conversion */ +typedef struct _conv_expr_t conv_expr_t; + + + +/* Référence une variable en tant qu'expression de conversion. */ +conv_expr_t *build_conv_expr_from_name(char *); + +/* Conserve une valeur en tant qu'expression de conversion. */ +conv_expr_t *build_conv_expr_from_number(unsigned long ); + +/* Construit une base d'expression de conversion composée. */ +conv_expr_t *build_composed_conv_expr(char *, char *); + +/* Etend une base d'expression de conversion composée. */ +conv_expr_t *extend_composed_conv_expr(conv_expr_t *, char *); + +/* Traduit une opération unaire sur expression de conversion. */ +conv_expr_t *build_unary_conv_expr(conv_expr_t *, ConvUnaryOperation); + +/* Traduit une opération binaire sur expression de conversion. */ +conv_expr_t *build_binary_conv_expr(conv_expr_t *, conv_expr_t *, ConvBinaryOperation); + + + + + + + + +/* ------------------------ LISTES D'ARGUMENTS DE CONVERSION ------------------------ */ + + +/* Liste d'expressions utilisées en arguments de conversion */ +typedef struct _conv_arg_list_t conv_arg_list_t; + + +/* Crée une liste d'arguments de conversion. */ +conv_arg_list_t *build_conv_arg_list(conv_expr_t *); + +/* Libère la mémoire occupée par une liste d'expressions. */ +void delete_conv_arg_list(conv_arg_list_t *); + +/* Ajoute un élément à une liste d'arguments de conversion. */ +conv_arg_list_t *extend_conv_arg_list(conv_arg_list_t *, conv_expr_t *); + + + + +/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ + + +/* Fonction de conversion */ +typedef struct _conv_func conv_func; + + +/* Définit une conversion à partir d'une simple expression. */ +conv_func *make_conv_from_expr(char *, conv_expr_t *); + +/* Définit une conversion à partir d'une function à appeler. */ +conv_func *make_conv_from_func(char *, char *, conv_arg_list_t *); + +/* Libère de la mémoire une conversion enregistrée. */ +void delete_conv_func(conv_func *); + +/* Indique la variable de destination d'une conversion. */ +const char *get_conv_dest_name(const conv_func *); + +/* Marque les champs utilisés par une fonction de conversion. */ +bool mark_conv_func(conv_func *, const coding_bits *, const conv_list *); + +/* Déclare les variables associées à une fonction de conversion. */ +bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, unsigned int); + +/* Définit les variables associées à une fonction de conversion. */ +bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); + + + +/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ + + +/* Crée un nouvelle liste vierge de fonctions de conversion. */ +conv_list *create_conv_list(void); + +/* Supprime de la mémoire une de fonctions de conversion. */ +void delete_conv_list(conv_list *); + +/* Enregistre une function de conversion du brut à l'utile. */ +void register_conversion(conv_list *, conv_func *); + +/* Recherche un résultat précis dans une liste de fonctions. */ +conv_func *find_named_conv_in_list(const conv_list *, const char *); + + + +#endif /* _TOOLS_CONV_H */ diff --git a/tools/d2c/d2c.mk b/tools/d2c/d2c.mk new file mode 100644 index 0000000..25596cf --- /dev/null +++ b/tools/d2c/d2c.mk @@ -0,0 +1,31 @@ + +.NOTPARALLEL: + +d2c_verbose = $(d2c_verbose_@AM_V@) +d2c_verbose_ = $(d2c_verbose_@AM_DEFAULT_V@) +d2c_verbose_0 = @echo " D2C " $<; + +fix_verbose = $(fix_verbose_@AM_V@) +fix_verbose_ = $(fix_verbose_@AM_DEFAULT_V@) +fix_verbose_0 = echo " FIX " `basename $$f`; + +fix2_verbose = $(fix2_verbose_@AM_V@) +fix2_verbose_ = $(fix2_verbose_@AM_DEFAULT_V@) +fix2_verbose_0 = echo " FIX " `basename $<`; + +# D2C_BIN = +# D2C_OUTDIR = +# D2C_ARCH = +# D2C_HEADER = +# D2C_ENCODINGS = +# D2C_MACROS = + +SUFFIXES = .g + +.d.g: + $(d2c_verbose)$(D2C_BIN) -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS) < $< + @touch $@ + +# Merci http://www.commandlinefu.com/commands/view/10276/grep-tab-t +untabify_disass: + find $(D2C_OUTDIR)/opcodes -name '*c' -exec grep -q $$'\t' {} \; -exec sed -i 's/\t/ /g' {} \; diff --git a/tools/d2c/d2c_gram.y b/tools/d2c/d2c_gram.y new file mode 100644 index 0000000..5deb053 --- /dev/null +++ b/tools/d2c/d2c_gram.y @@ -0,0 +1,442 @@ + +%{ + +#include +#include +#include +#include +#include + + +#include "coder.h" +#include "d2c_tok.h" + + +extern int yylex(); + +extern void free_flex_memory(void); + + +/* Affiche un message d'erreur suite à l'analyse en échec. */ +static int d2c_error(rented_coder *, char *); + +/* Affiche des indications sur l'utilisation du programme. */ +static void show_usage(const char *); + + +%} + + +%code requires { + +/* Pour la définition des expressions conditionnelles... */ +#include "coder.h" + +#include "conv.h" + +struct action_tmp +{ + CondActionType action; + const char *details; +}; + + + + +#define register_named_field_in_coder(c, n, l) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + register_named_field_in_bits(__bits, n, l); \ + }) + +#define register_bit_in_coder(c, v) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + register_bit_in_bits(__bits, v); \ + }) + +#define count_coder_bits(c) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + count_coded_bits(__bits); \ + }) + +#define register_syntax_item_in_coder(c, n, i) \ + ({ \ + encoding_spec *__spec; \ + asm_syntax *__syntax; \ + __spec = get_current_encoding_spec(c); \ + __syntax = get_syntax_in_encoding_spec(__spec); \ + register_syntax_item(__syntax, n, i); \ + }) + +#define register_conversion_in_coder(c, f) \ + ({ \ + encoding_spec *__spec; \ + conv_list *__list; \ + __spec = get_current_encoding_spec(c); \ + __list = get_conversions_in_encoding_spec(__spec); \ + register_conversion(__list, f); \ + }) + +#define add_conditional_rule_to_coder(c, e, a, d) \ + ({ \ + encoding_spec *__spec; \ + decoding_rules *__rules; \ + __spec = get_current_encoding_spec(c); \ + __rules = get_rules_in_encoding_spec(__spec); \ + register_conditional_rule(__rules, e, a, d); \ + }) + + + + + + +} + +%union { + + char *string; /* Chaîne de caractères #1 */ + const char *cstring; /* Chaîne de caractères #2 */ + + + int integer; + + conv_func *subst; /* Fonction de conversion */ + conv_arg_list_t *conv_list; /* Liste d'arguments de conv. */ + + conv_expr_t *conv; /* Expression de conversion */ + ConvUnaryOperation un_op; /* Opération unaire */ + ConvBinaryOperation bin_op; /* Opération bianire */ + + + cond_expr *expr; /* Expression de déclenchement */ + struct action_tmp tmpa; /* Transfert temporaire */ + +} + +%parse-param { rented_coder *coder } + + +%token COPYRIGHT +%token TITLE +%token INS_NAME INS_DETAILS + +%token ENCODING +%token THUMB ARCH NUMBER +%token ENC_START ENC_END + +%token WORD HALF NAME SIZE BIT + +%token SYNTAX OPERAND_INTERNAL OPERAND_VISIBLE + +%token CONV EQ OP COMMA CP NOT EOR COLON + +%token RULES IF EXPR_START EQUAL BINVAL EXPR_END AND THEN SEE + + +%type COPYRIGHT INS_NAME +%type INS_DETAILS + +%type NUMBER + +%type NAME +%type SIZE BIT + +%type OPERAND_INTERNAL OPERAND_VISIBLE + + +%type substitution +%type conv_arg_list +%type conv_expr conv_arg_composed +%type conv_expr_un_op +%type conv_expr_bin_op +%type conv_arg_field + +%type rule_cond +%type BINVAL +%type action + + +%% + + +input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; } + +name : COPYRIGHT TITLE INS_NAME { save_notes_for_coder(coder, $1, $3, NULL); } + | COPYRIGHT TITLE INS_NAME INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4); } + + + + +encodings : /* empty */ + | encoding encodings + +encoding : ENCODING THUMB NUMBER content { push_encoding_spec(coder, strdup("t"), $3); } + | ENCODING ARCH NUMBER content { push_encoding_spec(coder, strdup("a"), $3); } + + +content : /* empty */ + | bitfield content + | syntax content + | conversions content + | rules content + + +bitfield : HALF bits { + if (count_coder_bits(coder) != 16) + { + fprintf(stderr, "Unexpected word size: %u vs 16\n", count_coder_bits(coder)); + YYABORT; + } + } + | WORD bits { + if (count_coder_bits(coder) != 32) + { + fprintf(stderr, "Unexpected word size: %u vs 32\n", count_coder_bits(coder)); + YYABORT; + } + } + +bits : /* empty */ + | NAME SIZE bits { register_named_field_in_coder(coder, $1, $2); } + | BIT bits { register_bit_in_coder(coder, $1); } + + +syntax : SYNTAX operands + +operands : /* empty */ + | operands OPERAND_INTERNAL { register_syntax_item_in_coder(coder, $2, true); } + | operands OPERAND_VISIBLE { register_syntax_item_in_coder(coder, $2, false); } + + +conversions : CONV substitutions + +substitutions : /* empty */ + | substitutions substitution { register_conversion_in_coder(coder, $2); } + +substitution : NAME EQ conv_expr { $$ = make_conv_from_expr($1, $3); } + | NAME EQ NAME OP conv_arg_list CP { $$ = make_conv_from_func($1, $3, $5); } + +conv_arg_list : conv_expr { $$ = build_conv_arg_list($1); } + | conv_arg_list COMMA conv_expr { $$ = extend_conv_arg_list($1, $3); printf("extend\n"); } + +conv_expr : NAME { $$ = build_conv_expr_from_name($1); } + | NUMBER { $$ = build_conv_expr_from_number($1); } + | conv_arg_composed { $$ = $1; } + | OP conv_expr CP { $$ = $2; } + | conv_expr_un_op conv_expr { $$ = build_unary_conv_expr($2, $1); } + | OP conv_expr conv_expr_bin_op conv_expr CP { $$ = build_binary_conv_expr($2, $4, $3); } + +conv_expr_un_op : NOT { $$ = CUO_NOT; } + +conv_expr_bin_op : EOR { $$ = CBO_EOR; } + +conv_arg_composed : conv_arg_field COLON conv_arg_field { $$ = build_composed_conv_expr($1, $3); } + | conv_arg_composed COLON conv_arg_field { $$ = extend_composed_conv_expr($1, $3); } + +conv_arg_field : NAME { $$ = $1; printf(" composed::name '%s'\n", $1); } + | BINVAL { $$ = $1; printf(" composed::bin '%s'\n", $1); } + + +rules : RULES rules_list + +rules_list : /* empty */ + | rules_list rule + +rule : IF EXPR_START rule_cond EXPR_END THEN action + { add_conditional_rule_to_coder(coder, $3, $6.action, $6.details); } + +rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3); } + | EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END + { $$ = build_composed_cond_expression($2, COT_AND, $6); } + +action : SEE INS_DETAILS { $$.action = CAT_SEE; $$.details = $2; } + + +%% + + +/****************************************************************************** +* * +* Paramètres : coder = codeur impliqué dans le processus. * +* msg = message d'erreur. * +* * +* Description : Affiche un message d'erreur suite à l'analyse en échec. * +* * +* Retour : 0 * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int d2c_error(rented_coder *coder, char *msg) +{ + printf("yyerror line %d: %s\n", d2c_get_lineno(), msg); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : argv0 = nombre du programme exécuté. * +* * +* Description : Affiche des indications sur l'utilisation du programme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void show_usage(const char *argv0) +{ + printf("\n"); + + printf("Usage: %s [options] < file\n", argv0); + + printf("\n"); + + printf("Options:\n"); + + printf("\n"); + + printf("\t-h | --help\t\t\tDisplay this messsage.\n"); + printf("\t-d | --dir \t\tSpecify the main output directory.\n"); + printf("\t-a | --arch \t\tDefine the archicture to handle.\n"); + printf("\t-H | --header \t\tSet the base of the #ifndef / #define game.\n"); + printf("\t-e | --encoding \tDefine encoding prefixes for files.\n"); + printf("\t-m | --macro \t\tRegister some conversion functions.\n"); + + printf("\n"); + +} + + +/****************************************************************************** +* * +* Paramètres : argc = nombre d'arguments dans la ligne de commande. * +* argv = arguments de la ligne de commande. * +* * +* Description : Point d'entrée du programme. * +* * +* Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int main(int argc, char **argv) +{ + int result; /* Bilan à retourner */ + rented_coder *coder; /* Codeur à briffer & employer */ + int index; /* Indice de fichier à traiter */ + bool need_help; /* Affichage de l'aide ? */ + bool has_error; /* Erreur dans la ligne de cmd.*/ + int ret; /* Bilan d'une lecture d'arg. */ + char *sep; /* Caratère '=' en coupure */ + + static struct option long_options[] = { + + { "help", no_argument, NULL, 'h' }, + { "dir", required_argument, NULL, 'd' }, + { "arch", required_argument, NULL, 'a' }, + { "header", required_argument, NULL, 'H' }, + { "encoding", required_argument, NULL, 'e' }, + { "macro", required_argument, NULL, 'M' }, + { NULL, 0, NULL, 0 } + + }; + + result = EXIT_SUCCESS; + + coder = create_coder(); + + index = 0; + + need_help = false; + has_error = false; + + while (!has_error) + { + ret = getopt_long(argc, argv, "hd:a:H:e:M:", long_options, &index); + if (ret == -1) break; + + switch (ret) + { + case 'h': + need_help = true; + break; + + case 'd': + set_coder_output_directory(coder, optarg); + break; + + case 'a': + set_coder_arch(coder, optarg); + break; + + case 'H': + set_coder_header_base(coder, optarg); + break; + + case 'e': + + sep = strchr(optarg, '='); + has_error = (sep == NULL); + + if (!has_error) + { + *sep = '\0'; + register_encoding(get_coder_pre_proc(coder), optarg, sep + 1); + } + + break; + + case 'M': + + sep = strchr(optarg, '='); + has_error = (sep == NULL); + + if (!has_error) + { + *sep = '\0'; + define_macro(get_coder_pre_proc(coder), optarg, sep + 1); + } + + break; + + } + + } + + if (need_help || has_error || !do_basic_checks_with_coder(coder) || optind != argc) + { + show_usage(argv[0]); + result = (need_help ? EXIT_SUCCESS : EXIT_FAILURE); + goto exit; + } + + result = yyparse(coder); + + exit: + + free_flex_memory(); + + delete_coder(coder); + + return result; + +} diff --git a/tools/d2c/d2c_tok.l b/tools/d2c/d2c_tok.l new file mode 100644 index 0000000..50a8d8f --- /dev/null +++ b/tools/d2c/d2c_tok.l @@ -0,0 +1,187 @@ + +%{ + +typedef struct _rented_coder rented_coder; + + +#include "d2c-d2c_gram.h" + +#include +#include + + +/* Tente de libérer autant de mémoire que possible... */ +void free_flex_memory(void) ; + + +%} + +%option noyywrap +%option nounput +%option noinput +%option yylineno + + +%x comments + +%x ins_name try_details ins_details +%x encoding encoding_type encoding_content + +%x encoding_bits encoding_bits_size + +%x syntax syntax_int syntax_ext + +%x conv_begin conv_content conv_arg conv_arg_binval + +%x rules_begin rules_content rules_cond rules_cond_binval rules_action rules_actin_see + + +%% + + +[ \t\n]+ { } + +"/*" { BEGIN(comments); } +"*/" { BEGIN(INITIAL); } +[^*\n] { } +"Copyright"[^\n]* { d2c_lval.string = strdup(yytext); return COPYRIGHT; } +"*" { } +"\n" { } + + +"@title" { BEGIN(ins_name); return TITLE; } + +[ ][A-Za-z-]+ { d2c_lval.string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; } +[ ,/] { BEGIN(ins_details); } +[\n] { BEGIN(INITIAL); } + +[^\n]* { d2c_lval.cstring = yytext; return INS_DETAILS; } +[\n] { BEGIN(INITIAL); } + + + +"@encoding" { BEGIN(encoding); return ENCODING; } + +[ ] { } +"(" { BEGIN(encoding_type); } + +"T" { return THUMB; } +"A" { return ARCH; } +[0-9] { d2c_lval.integer = atoi(yytext); return NUMBER; } +")" { BEGIN(encoding); } + +"{" { BEGIN(encoding_content); } +[ \t\n]+ { } +"}" { BEGIN(INITIAL); } + + + +"@half" { BEGIN(encoding_bits); return HALF; } +"@word" { BEGIN(encoding_bits); return WORD; } + +" " { } +"\n" { BEGIN(encoding_content); } +[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; } + +"(" { BEGIN(encoding_bits_size); } +[0-9]+ { d2c_lval.integer = atoi(yytext); return SIZE; } +")" { BEGIN(encoding_bits); } + +[01] { d2c_lval.integer = atoi(yytext); return BIT; } + + + +"@syntax" { BEGIN(syntax); return SYNTAX; } + +[ ]+ { } +"\n" { BEGIN(encoding_content); } + +"{" { BEGIN(syntax_int); } +[^ \n}]+ { d2c_lval.string = strdup(yytext); return OPERAND_INTERNAL; } +"}" { BEGIN(syntax); } + +"<" { BEGIN(syntax_ext); } +[^ \n>]+ { d2c_lval.string = strdup(yytext); return OPERAND_VISIBLE; } +">" { BEGIN(syntax); } + + + +"@conv" { BEGIN(conv_begin); return CONV; } +[ ]+ { } +"{" { BEGIN(conv_content); } +"}" { BEGIN(encoding_content); } + +[ \t\n]+ { } +[A-Za-z][A-Za-z0-9]* { + if (strcmp(yytext, "NOT") == 0) return NOT; + else + { + d2c_lval.string = strdup(yytext); + return NAME; + } + } +"=" { return EQ; } +"(" { BEGIN(conv_arg); return OP; } +[A-Za-z][A-Za-z0-9]* { + if (strcmp(yytext, "NOT") == 0) return NOT; + else if (strcmp(yytext, "EOR") == 0) return EOR; + else + { + d2c_lval.string = strdup(yytext); + return NAME; + } + } +[0-9][0-9]* { d2c_lval.integer = atoi(yytext); return NUMBER; } +"'" { BEGIN(conv_arg_binval); } +[01][01]* { d2c_lval.string = strdup(yytext); return BINVAL; } +"'" { BEGIN(conv_arg); } +"," { return COMMA; } +":" { return COLON; } +[ ]+ { } +")" { BEGIN(conv_content); return CP; } + + + +"@rules" { BEGIN(rules_begin); return RULES; } +[ ]+ { } +"{" { BEGIN(rules_content); } +[ \t\n]+ { } +"}" { BEGIN(encoding_content); } + +"if" { BEGIN(rules_cond); return IF; } +[ ]+ { } +"(" { return EXPR_START; } +[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; } +"==" { return EQUAL; } +"'" { BEGIN(rules_cond_binval); } +[01][01]* { d2c_lval.string = strdup(yytext); return BINVAL; } +"'" { BEGIN(rules_cond); } +")" { return EXPR_END; } +"&&" { return AND; } + +";" { BEGIN(rules_action); return THEN; } +[ ]+ { } +"see " { BEGIN(rules_actin_see); return SEE; } +[^\n]* { d2c_lval.cstring = yytext; BEGIN(rules_content); return INS_DETAILS; } + + +%% + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Tente de libérer autant de mémoire que possible... * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void free_flex_memory(void) +{ + yy_delete_buffer(YY_CURRENT_BUFFER); + +} diff --git a/tools/d2c/helpers.c b/tools/d2c/helpers.c new file mode 100644 index 0000000..1353ba2 --- /dev/null +++ b/tools/d2c/helpers.c @@ -0,0 +1,144 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers.c - fonctionnalités d'assitance à la compilation + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "helpers.h" + + +#include +#include + + + +/* ---------------------------------------------------------------------------------- */ +/* MANIPULATIONS DE CHAINES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : str = chaîne de caractères à manipuler. [OUT] * +* * +* Description : Bascule toute une chaîne de caractères en (min|maj)uscules. * +* * +* Retour : Pointeur sur la chaîne fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *_make_string_xxx(char *str, int (* fn) (int)) +{ + size_t max; /* Empleur du parcours */ + size_t i; /* Boucle de parcours */ + + max = strlen(str); + + for (i = 0; i < max; i++) + str[i] = fn(str[i]); + + return str; + +} + + +/****************************************************************************** +* * +* Paramètres : raw = données brutes en provenance de l'analyseur. * +* details = indique la nature de la chaîne à traiter. * +* * +* Description : Traduit une chaîne en élément de fonction C. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *make_callable(const char *raw, bool details) +{ + char *result; /* Nom formaté à retourner */ + size_t max; /* Empleur du parcours */ + size_t i; /* Boucle de parcours */ + + result = strdup(raw); + + max = strlen(result); + + /* Première passe : on vire les virgules */ + + for (i = 0; i < max; i++) + if (result[i] == ',') + { + memmove(result + i, result + i + 1, max - i - 1); + max--; + } + + result[max] = '\0'; + + /* Deuxième passe : on bascule en minuscules */ + + result = make_string_lower(result); + + /* Troisième passe : on remplace les mauvais caractères */ + + for (i = 0; i < max; i++) + switch (result[i]) + { + case 'a' ... 'z': + case '0' ... '9': + break; + case '-': + result[i] = '_'; + break; + default: + result[i] = (i + 1 == max ? '\0' : '_'); + break; + } + + /** + * Dernière passe : on s'assure que le premier caractère n'est pas une lettre. + * On ajoute ici le préfixe '_' utilisé lors de la génération de prototypes ; + * en cas d'absence de détails, on ne se retrouve ainsi pas avec un '_' isolé. + */ + + if (details && result[0] != '_') + { + max = strlen(result) + 1; + result = (char *)realloc(result, max); + memmove(result + 1, result, max - 1); + result[0] = '_'; + } + + /* Ultime passe : supression des '_' groupés */ + + for (i = 0; i < max; i++) + if (result[i] == '_' && result[i + 1] == '_') + { + memmove(result + i + 1, result + i + 2, max - i - 1); + max--; + i--; + } + + return result; + +} diff --git a/tools/d2c/helpers.h b/tools/d2c/helpers.h new file mode 100644 index 0000000..8c39a85 --- /dev/null +++ b/tools/d2c/helpers.h @@ -0,0 +1,47 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * helpers.h - prototypes pour les fonctionnalités d'assitance à la compilation + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_HELPERS_H +#define _TOOLS_HELPERS_H + + +#include +#include + + + +/* ---------------------------- MANIPULATIONS DE CHAINES ---------------------------- */ + + +/* Bascule toute une chaîne de caractères en (min|maj)uscules. */ +char *_make_string_xxx(char *, int (* fn) (int)); + +#define make_string_lower(str) _make_string_xxx(str, tolower) +#define make_string_upper(str) _make_string_xxx(str, toupper) + +/* Traduit une chaîne en élément de fonction C. */ +char *make_callable(const char *raw, bool); + + + +#endif /* _TOOLS_HELPERS_H */ diff --git a/tools/d2c/macros.c b/tools/d2c/macros.c new file mode 100644 index 0000000..b1c44f0 --- /dev/null +++ b/tools/d2c/macros.c @@ -0,0 +1,167 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pproc.c - remplacements à la volée de chaînes de caractères + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "pproc.h" + + +#include + + + + + + +/* Conversion des chaînes en chaînes */ +typedef struct _string_exch +{ + const char *src; /* Chaîne à trouver */ + const char *dest; /* Chaîne de remplacement */ + +} string_exch; + + +/* Pré-processeur avec support des macros */ +struct _pre_processor +{ + string_exch *macros; /* Remplacements de chaînes */ + size_t macros_count; /* Nombre de ces remplacements */ + + + +} + + + + + + +/****************************************************************************** +* * +* 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->bits = create_coding_bits(); + result->syntax = create_asm_syntax(); + result->conversions = create_conv_list(); + 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_coding_bits(spec->bits); + delete_asm_syntax(spec->syntax); + delete_conv_list(spec->conversions); + delete_decoding_rules(spec->rules); + + free(spec); + +} + + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* src = chaîne à remplacer dans les définitions. * +* dest = chaîne de remplacement. * +* * +* Description : Constitue la matière d'un système de macros. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void define_macro_for_coder(rented_coder *coder, const char *src, const char *dest) +{ + string_exch *macro; /* Nouvelle macro à constituer */ + + coder->macros = (string_exch *)realloc(coder->macros, ++coder->macros_count * sizeof(string_exch)); + + macro = &coder->macros[coder->macros_count - 1]; + + macro->src = src; + macro->dest = dest; + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* src = chaîne à remplacer dans les définitions. * +* * +* Description : Recherche l'existence d'une macro pour un remplacement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *find_macro_in_coder(const rented_coder *coder, const char *src) +{ + const char *result; /* Trouvaille à renvoyer */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < coder->macros_count && result == NULL; i++) + if (strcmp(coder->macros[i].src, src) == 0) + result = coder->macros[i].dest; + + return result; + +} + + diff --git a/tools/d2c/macros.h b/tools/d2c/macros.h new file mode 100644 index 0000000..3755f00 --- /dev/null +++ b/tools/d2c/macros.h @@ -0,0 +1,30 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * macros.h - prototypes pour les remplacements à la volée de chaînes de caractères + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_MACROS_H +#define _TOOLS_MACROS_H + + + + +#endif /* _TOOLS_MACROS_H */ diff --git a/tools/d2c/pproc.c b/tools/d2c/pproc.c new file mode 100644 index 0000000..8644af5 --- /dev/null +++ b/tools/d2c/pproc.c @@ -0,0 +1,214 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pproc.c - remplacements à la volée de chaînes de caractères + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "pproc.h" + + +#include +#include + + + +/* Pré-processeur avec support des macros */ +struct _pre_processor +{ + string_exch *encodings; /* Traductions d'encodages */ + size_t encodings_count; /* Nombre de ces traductions */ + + string_exch *macros; /* Remplacements de chaînes */ + size_t macros_count; /* Nombre de ces remplacements */ + +}; + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau pre-processeur pour le support des macros. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +pre_processor *create_pre_processor(void) +{ + pre_processor *result; /* Définition vierge à renvoyer*/ + + result = (pre_processor *)calloc(1, sizeof(pre_processor)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur à libérer de la mémoire. * +* * +* Description : Supprime de la mémoire un pré-processeur et ses macros. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_pre_processor(pre_processor *pp) +{ + if (pp->encodings != NULL) + free(pp->encodings); + + if (pp->macros != NULL) + free(pp->macros); + + free(pp); + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur dont le contenu est à compléter. * +* src = chaîne à remplacer dans les définitions. * +* dest = chaîne de remplacement. * +* * +* Description : Enregistre une correspondance en matière d'encodage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_encoding(pre_processor *pp, const char *src, const char *dest) +{ + string_exch *encoding; /* Traduction à conserver */ + + pp->encodings = (string_exch *)realloc(pp->encodings, ++pp->encodings_count * sizeof(string_exch)); + + encoding = &pp->encodings[pp->encodings_count - 1]; + + encoding->src = src; + encoding->dest = dest; + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur dont le contenu est à consulter. * +* * +* Description : Indique le nombre de catégories d'encodages enregistrées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t count_encodings(const pre_processor *pp) +{ + return pp->encodings_count; + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur dont le contenu est à consulter. * +* index = indice de l'encodage à retourner. * +* * +* Description : Fournit une catégorie d'encodage donnée. * +* * +* Retour : Correspondance à consulter uniquement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const string_exch *find_encoding(const pre_processor *pp, size_t index) +{ + return &pp->encodings[index]; + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur dont le contenu est à compléter. * +* src = chaîne à remplacer dans les définitions. * +* dest = chaîne de remplacement. * +* * +* Description : Constitue la matière d'un système de macros. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void define_macro(pre_processor *pp, const char *src, const char *dest) +{ + string_exch *macro; /* Nouvelle macro à constituer */ + + pp->macros = (string_exch *)realloc(pp->macros, ++pp->macros_count * sizeof(string_exch)); + + macro = &pp->macros[pp->macros_count - 1]; + + macro->src = src; + macro->dest = dest; + +} + + +/****************************************************************************** +* * +* Paramètres : pp = pré-processeur dont le contenu est à consulter. * +* src = chaîne à remplacer dans les définitions. * +* * +* Description : Recherche l'existence d'une macro pour un remplacement. * +* * +* Retour : Eventuelle correspondance trouvée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *find_macro(const pre_processor *pp, const char *src) +{ + const char *result; /* Trouvaille à renvoyer */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + for (i = 0; i < pp->macros_count && result == NULL; i++) + if (strcmp(pp->macros[i].src, src) == 0) + result = pp->macros[i].dest; + + return result; + +} diff --git a/tools/d2c/pproc.h b/tools/d2c/pproc.h new file mode 100644 index 0000000..6675fa1 --- /dev/null +++ b/tools/d2c/pproc.h @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pproc.h - prototypes pour les remplacements à la volée de chaînes de caractères + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_PPROC_H +#define _TOOLS_PPROC_H + + +#include + + + +/* Conversion des chaînes en chaînes */ +typedef struct _string_exch +{ + const char *src; /* Chaîne à trouver */ + const char *dest; /* Chaîne de remplacement */ + +} string_exch; + +/* Pré-processeur avec support des macros */ +typedef struct _pre_processor pre_processor; + + +/* Crée un nouveau pre-processeur pour le support des macros. */ +pre_processor *create_pre_processor(void); + +/* Supprime de la mémoire un pré-processeur et ses macros. */ +void delete_pre_processor(pre_processor *); + +/* Enregistre une correspondance en matière d'encodage. */ +void register_encoding(pre_processor *, const char *, const char *); + +/* Indique le nombre de catégories d'encodages enregistrées. */ +size_t count_encodings(const pre_processor *); + +/* Fournit une catégorie d'encodage donnée. */ +const string_exch *find_encoding(const pre_processor *, size_t); + +/* Constitue la matière d'un système de macros. */ +void define_macro(pre_processor *, const char *, const char *); + +/* Recherche l'existence d'une macro pour un remplacement. */ +const char *find_macro(const pre_processor *, const char *); + + + +#endif /* _TOOLS_PPROC_H */ diff --git a/tools/d2c/rules.c b/tools/d2c/rules.c new file mode 100644 index 0000000..25ba76c --- /dev/null +++ b/tools/d2c/rules.c @@ -0,0 +1,439 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rules.h - prototypes pour les variations de décodage selon certaines conditions + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "rules.h" + + +#include +#include +#include + + +#include "helpers.h" + + + +/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */ + + +/* Expression d'une condition */ +struct _cond_expr +{ + bool is_simple; /* Sélection de champ */ + + union + { + struct + { + char *variable; /* Variable manipulée */ + CondCompType comp; /* Type de comparaison */ + char *bvalue; /* Valeur binaire comparée */ + + } simple; + + struct + { + cond_expr *a; /* Première sous-expression */ + CondOpType operator; /* Relation entre expressions */ + cond_expr *b; /* Seconde sous-expression */ + + } composed; + + }; + +}; + + +/* Libère de la mémoire une expression conditionnelle. */ +static void delete_cond_expr(cond_expr *); + +/* Traduit en code une expression de condition. */ +static bool write_cond_expr(const cond_expr *, int, const coding_bits *); + + + +/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */ + + +/* Règle particulière */ +typedef struct _extra_rule +{ + cond_expr *expr; /* Expression de déclenchement */ + CondActionType action; /* Conséquence d'une validation*/ + char *details; /* Eventuel complément d'info. */ + +} extra_rule; + +/* Règles de décodage supplémentaires */ +struct _decoding_rules +{ + extra_rule *extra; /* Règles conditionnelles */ + size_t extra_count; /* Nombre de ces règles */ + +}; + + + +/* ---------------------------------------------------------------------------------- */ +/* CONDITIONS DE DECLENCHEMENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : variable = désignation de la variable à manipuler. * +* comp = type de comparaison à utiliser. * +* bvalue = valeur binaire à comparer. * +* * +* Description : Crée une expression conditionnelle simple. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *bvalue) +{ + cond_expr *result; /* Structure à retourner */ + + result = (cond_expr *)calloc(1, sizeof(cond_expr)); + + result->is_simple = true; + + result->simple.variable = make_string_lower(variable); + result->simple.comp = comp; + result->simple.bvalue = bvalue; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = première expression à intégrer. * +* operator = type de comparaison à utiliser. * +* b = second expression à intégrer. * +* * +* Description : Crée une expression conditionnelle composée. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, cond_expr *b) +{ + cond_expr *result; /* Structure à retourner */ + + result = (cond_expr *)calloc(1, sizeof(cond_expr)); + + result->is_simple = false; + + result->composed.a = a; + result->composed.operator = operator; + result->composed.b = b; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : expr = représentation d'expression à traiter. * +* * +* Description : Libère de la mémoire une expression conditionnelle. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void delete_cond_expr(cond_expr *expr) +{ + if (expr->is_simple) + { + free(expr->simple.variable); + free(expr->simple.bvalue); + } + else + { + delete_cond_expr(expr->composed.a); + delete_cond_expr(expr->composed.b); + } + + free(expr); + +} + + +/****************************************************************************** +* * +* Paramètres : expr = expression simple ou composée à transposer. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* * +* Description : Traduit en code une expression de condition. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits) +{ + bool result; /* Bilan à renvoyer */ + const raw_bitfield *bf; /* Champ de bits de définition */ + + result = true; + + dprintf(fd, "("); + + if (expr->is_simple) + { + bf = find_named_field_in_bits(bits, expr->simple.variable); + if (bf == NULL) + { + fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable); + result = false; + goto wce_exit; + } + + if (get_raw_bitfield_length(bf) != strlen(expr->simple.bvalue)) + { + fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %zu).\n", + expr->simple.variable, get_raw_bitfield_length(bf), strlen(expr->simple.bvalue)); + result = false; + goto wce_exit; + } + + dprintf(fd, "raw_%s", expr->simple.variable); + + switch (expr->simple.comp) + { + case CCT_EQUAL: + dprintf(fd, " == "); + break; + case CCT_DIFF: + dprintf(fd, " != "); + break; + } + + dprintf(fd, "b%s", expr->simple.bvalue); + + } + else + { + result = write_cond_expr(expr->composed.a, fd, bits); + if (!result) goto wce_exit; + + switch (expr->composed.operator) + { + case COT_AND: + dprintf(fd, " && "); + break; + case COT_OR: + dprintf(fd, " || "); + break; + } + + result = write_cond_expr(expr->composed.b, fd, bits); + if (!result) goto wce_exit; + + } + + dprintf(fd, ")"); + + wce_exit: + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* REGLES ET ACTIONS CONSEQUENTES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau rassemblement de règles de décodage. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +decoding_rules *create_decoding_rules(void) +{ + decoding_rules *result; /* Définition vierge à renvoyer*/ + + result = (decoding_rules *)calloc(1, sizeof(decoding_rules)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : rules = ensemble de règles de décodage à supprimer. * +* * +* Description : Supprime de la mémoire un ensemble de règles supplémentaires.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_decoding_rules(decoding_rules *rules) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < rules->extra_count; i++) + { + delete_cond_expr(rules->extra[i].expr); + if (rules->extra[i].details) + free(rules->extra[i].details); + } + + if (rules->extra != NULL) + free(rules->extra); + + free(rules); + +} + + +/****************************************************************************** +* * +* Paramètres : rules = ensemble de règles à compléter. * +* expr = représentation d'expression à conserver. * +* action = conséquence associée à la règle. * +* details = éventuel complément d'informations. * +* * +* Description : Ajoute une règle complète à la définition d'un codage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_conditional_rule(decoding_rules *rules, cond_expr *expr, CondActionType action, const char *details) +{ + extra_rule *rule; /* Nouvelle prise en compte */ + + rules->extra = (extra_rule *)realloc(rules->extra, ++rules->extra_count * sizeof(extra_rule)); + + rule = &rules->extra[rules->extra_count - 1]; + + rule->expr = expr; + rule->action = action; + rule->details = (details != NULL ? make_callable(details, false) : NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : rules = ensemble de règles à consulter. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* exit = exprime le besoin d'une voie de sortie. [OUT] * +* * +* Description : Traduit en code les éventuelles règles présentes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_decoding_rules(decoding_rules *rules, int fd, const coding_bits *bits, bool *exit) +{ + bool result; /* Bilan à remonter */ + const extra_rule *rule; /* Règle en cours d'écriture */ + size_t i; /* Boucle de parcours */ + + result = true; + + *exit = false; + + for (i = 0; i < rules->extra_count; i++) + { + rule = &rules->extra[i]; + + dprintf(fd, "\t\tif "); + + result = write_cond_expr(rule->expr, fd, bits); + if (!result) break; + + dprintf(fd, "\n"); + dprintf(fd, "\t\t{\n"); + + switch (rule->action) + { + case CAT_SEE: + + if (rule->details == NULL) + { + fprintf(stderr, "Error: directive 'see' must provide additional details.\n"); + result = false; + goto wcsr_exit; + } + + dprintf(fd, "\t\t\tinstr = armv7_read_instr_%s", rule->details); + + /* TODO : adapter les paramètres d'appel selon le 'coder' */ + dprintf(fd, "(_raw);\n"); + + dprintf(fd, "\t\t\tgoto quick_exit;\n"); + + *exit = true; + break; + + } + + dprintf(fd, "\t\t}\n"); + + dprintf(fd, "\n"); + + } + + wcsr_exit: + + return result; + +} diff --git a/tools/d2c/rules.h b/tools/d2c/rules.h new file mode 100644 index 0000000..a4a9bb4 --- /dev/null +++ b/tools/d2c/rules.h @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * rules.h - prototypes pour les variations de décodage selon certaines conditions + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_RULES_H +#define _TOOLS_RULES_H + + +#include "bits.h" + + + +/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */ + + +/* Types de comparaison */ +typedef enum _CondCompType +{ + CCT_EQUAL, /* Egalité '==' */ + CCT_DIFF /* Différence '!=' */ + +} CondCompType; + +/* Types de combinaison d'expressions */ +typedef enum _CondOpType +{ + COT_AND, /* Combinaison ET ('&&') */ + COT_OR /* Combinaison OU ('||') */ + +} CondOpType; + +/* Expression d'une condition */ +typedef struct _cond_expr cond_expr; + + +/* Crée une expression conditionnelle simple. */ +cond_expr *build_simple_cond_expression(char *, CondCompType, char *); + +/* Crée une expression conditionnelle composée. */ +cond_expr *build_composed_cond_expression(cond_expr *, CondOpType, cond_expr *); + + + +/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */ + + +/* Conséquence en cas de condition remplie */ +typedef enum _CondActionType +{ + CAT_SEE /* Renvoi vers une instruction */ + +} CondActionType; + +/* Règles de décodage supplémentaires */ +typedef struct _decoding_rules decoding_rules; + + +/* Crée un nouveau rassemblement de règles de décodage. */ +decoding_rules *create_decoding_rules(void); + +/* Supprime de la mémoire un ensemble de règles supplémentaires. */ +void delete_decoding_rules(decoding_rules *); + +/* Ajoute une règle complète à la définition d'un codage. */ +void register_conditional_rule(decoding_rules *, cond_expr *, CondActionType, const char *); + +/* Traduit en code les éventuelles règles présentes. */ +bool write_decoding_rules(decoding_rules *, int, const coding_bits *, bool *); + + + +#endif /* _TOOLS_RULES_H */ diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c new file mode 100644 index 0000000..a957587 --- /dev/null +++ b/tools/d2c/spec.c @@ -0,0 +1,349 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * spec.c - représentation complète d'un encodage + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "spec.h" + + +#include +#include +#include + + +#include "helpers.h" + + + + + +#define get_raw_bitfield_name(bf) "" + + + + + +#define get_syntax_item_name(si) "" + + + + + + + +/* Mémorisation d'un encodage complet */ +struct _encoding_spec +{ + char *prefix; /* Distinction principale */ + unsigned int index; /* Distinction secondaire */ + + coding_bits *bits; /* Encodage des bits associés */ + asm_syntax *syntax; /* Calligraphe d'assemblage */ + conv_list *conversions; /* Conversions des données */ + 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->bits = create_coding_bits(); + result->syntax = create_asm_syntax(); + result->conversions = create_conv_list(); + 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_coding_bits(spec->bits); + delete_asm_syntax(spec->syntax); + delete_conv_list(spec->conversions); + 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->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) +{ + return (strcmp(spec->prefix, prefix) == 0); + +} + + +/****************************************************************************** +* * +* 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 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. * +* ins = désignation première de l'instruction manipulée. * +* details = particularités de l'instruction. * +* keyword = nom clef de l'instruction utilisable dans du code. * +* 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 *ins, const char *details, unsigned int wide, const pre_processor *pp) +{ + bool result; /* Bilan à retourner */ + char *keyword; /* Mot clef appelable en code */ + bool exit; /* Inclusion de sortie rapide ?*/ + + result = true; + + keyword = make_callable(ins, false); + + dprintf(fd, "\tGArchInstruction *%s_decode_%s%s_%s%u(uint%u_t _raw)\n", + arch, keyword, details, spec->prefix, 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 &= declare_used_bits_fields(spec->bits, fd, wide); + + result &= declare_syntax_items(spec->syntax, fd, spec->bits, spec->conversions, wide); + + dprintf(fd, "\n"); + + /* 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); + + dprintf(fd, "\n"); + + /* Inclusion des éventuelles règles */ + + result &= write_decoding_rules(spec->rules, fd, spec->bits, &exit); + + /* Création de l'instruction en elle-même */ + + dprintf(fd, "\t\tinstr = g_%s_instruction_new(\"%s\");\n", arch, ins); + + dprintf(fd, "\n"); + + /* Création des opérandes */ + + result &= define_syntax_items(spec->syntax, fd, arch, spec->bits, spec->conversions, pp); + + /* Conclusion de la procédure */ + + if (exit) + { + dprintf(fd, "\t quick_exit:\n"); + dprintf(fd, "\n"); + } + + dprintf(fd, "\t\treturn instr;\n"); + + dprintf(fd, "\n"); + + 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->prefix, spec->index); + + dprintf(fd, "\n"); + + free(keyword); + + return result; + +} diff --git a/tools/d2c/spec.h b/tools/d2c/spec.h new file mode 100644 index 0000000..46d922b --- /dev/null +++ b/tools/d2c/spec.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * spec.h - prototypes pour la représentation complète d'un encodage + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_SPEC_H +#define _TOOLS_SPEC_H + + +#include + + +#include "bits.h" +#include "conv.h" +#include "pproc.h" +#include "rules.h" +#include "syntax.h" + + + +/* Mémorisation d'un encodage complet */ +typedef struct _encoding_spec encoding_spec; + + +/* Crée un nouveau suivi de l'encodage d'une instruction. */ +encoding_spec *create_encoding_spec(void); + +/* Supprime de la mémoire un suivi d'encodage d'une instruction. */ +void delete_encoding_spec(encoding_spec *); + +/* Définit le nom de code d'une spécification d'encodage. */ +void define_encoding_spec_code_name(encoding_spec *, char *, unsigned int); + +/* Indique si une spécification se range dans une catégorie. */ +bool has_encoding_spec_prefix(const encoding_spec *, const char *); + +/* Fournit le gestionnaire des bits d'un encodage d'instruction. */ +coding_bits *get_bits_in_encoding_spec(const encoding_spec *); + +/* Fournit l'indicateur des écritures correctes d'assembleur. */ +asm_syntax *get_syntax_in_encoding_spec(const encoding_spec *); + +/* Fournit la liste des fonctions de conversion. */ +conv_list *get_conversions_in_encoding_spec(const encoding_spec *); + +/* Fournit un ensemble de règles supplémentaires éventuel. */ +decoding_rules *get_rules_in_encoding_spec(const encoding_spec *); + +/* Traduit en code une sous-fonction de désassemblage. */ +bool write_encoding_spec_disass(const encoding_spec *, int, const char *, const char *, const char *, unsigned int, const pre_processor *); + + + +#endif /* _TOOLS_SPEC_H */ diff --git a/tools/d2c/syntax.c b/tools/d2c/syntax.c new file mode 100644 index 0000000..5fec1a6 --- /dev/null +++ b/tools/d2c/syntax.c @@ -0,0 +1,321 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * syntax.c - prise en compte d'une syntaxe du langage d'assemblage + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#include "syntax.h" + + +#include +#include + + +#include "helpers.h" + + + +/* Propriétés particulières pour les opérandes */ +typedef enum _SyntaxItemFlags +{ + SIF_NONE = (0 << 0), /* Aucune propriété */ + SIF_DECIMAL = (1 << 0) /* Affichage en décimal */ + +} SyntaxItemFlags; + +/* Elément défini dans une syntaxe */ +typedef struct _syntax_item +{ + char *name; /* Désignation humaine */ + bool internal; /* Enregistrement générique ? */ + SyntaxItemFlags flags; /* Propriétés supplémentaires */ + +} syntax_item; + +/* Syntaxe d'une ligne d'assembleur */ +struct _asm_syntax +{ + syntax_item *items; /* Eléments de la syntaxe */ + size_t items_count; /* Nombre de ces éléments */ + +}; + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouvel indicateur pour l'écriture d'une instruction. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_syntax *create_asm_syntax(void) +{ + asm_syntax *result; /* Définition vierge à renvoyer*/ + + result = (asm_syntax *)calloc(1, sizeof(asm_syntax)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * +* * +* Description : Supprime de la mémoire un indicateur d'écriture ASM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_asm_syntax(asm_syntax *syntax) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < syntax->items_count; i++) + free(syntax->items[i].name); + + if (syntax->items != NULL) + free(syntax->items); + + free(syntax); + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * +* name = désignation de l'opérande dans la spécification. * +* internal = précise si l'opérand est non générique ou non. * +* * +* Description : Enregistre la présence d'un nouvel opérande dans la syntaxe. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_syntax_item(asm_syntax *syntax, char *name, bool internal) +{ + syntax_item *item; /* Nouvelle prise en compte */ + size_t len; /* Taille du nom fourni */ + + syntax->items = (syntax_item *)realloc(syntax->items, ++syntax->items_count * sizeof(syntax_item)); + + item = &syntax->items[syntax->items_count - 1]; + + /* Récupération des drapeaux */ + + item->flags = SIF_NONE; + + for (len = strlen(name); len > 0; len--) + switch (name[0]) + { + case '#': + item->flags |= SIF_DECIMAL; + memmove(name, name + 1, len); + break; + + default: + len = 1; + break; + + } + + item->name = make_string_lower(name); + item->internal = internal; + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Marque les champs de bits effectivement utilisés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool mark_syntax_items(const asm_syntax *syntax, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + syntax_item *item; /* Lien vers un opérande */ + conv_func *func; /* Fonction de conversion */ + + result = true; + + for (i = 0; i < syntax->items_count && result; i++) + { + item = &syntax->items[i]; + + func = find_named_conv_in_list(list, item->name); + if (func == NULL) + { + fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); + result = false; + } + + result = mark_conv_func(func, bits, list); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* wide = taille des mots décodés. * +* * +* Description : Déclare les variables C associées aux opérandes de syntaxe. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) +{ + bool result; /* Bilan à retourner */ + bool has_operand; /* Présence d'un opérande */ + size_t i; /* Boucle de parcours */ + syntax_item *item; /* Lien vers un opérande */ + conv_func *func; /* Fonction de conversion */ + + result = true; + + has_operand = false; + + for (i = 0; i < syntax->items_count && result; i++) + { + item = &syntax->items[i]; + + has_operand |= !item->internal; + + func = find_named_conv_in_list(list, item->name); + if (func == NULL) + { + fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); + result = false; + } + + result &= declare_conv_func(func, fd, bits, list, wide); + + } + + if (has_operand) + dprintf(fd, "\t\tGArchOperand *op;\n"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* pp = pré-processeur pour les échanges de chaînes. * +* * +* Description : Définit les variables C associées aux opérandes de syntaxe. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + syntax_item *item; /* Lien vers un opérande */ + conv_func *func; /* Fonction de conversion */ + + result = true; + + for (i = 0; i < syntax->items_count && result; i++) + { + item = &syntax->items[i]; + + func = find_named_conv_in_list(list, item->name); + if (func == NULL) + { + fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); + result = false; + } + + /* Appel proprement dit */ + + result &= define_conv_func(func, true, item->internal, fd, arch, bits, list, pp); + if (!result) break; + + /* Raccordement : propriété ou opérande ? */ + + if (item->internal) + dprintf(fd, "\t\t\tgoto bad_exit;\n"); + + else + { + dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n"); + + dprintf(fd, "\n"); + + if (item->flags & SIF_DECIMAL) + dprintf(fd, "\t\tg_imm_operand_set_display(G_IMM_OPERAND(op), IOD_DEC);\n"); + + dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n"); + + } + + dprintf(fd, "\n"); + + } + + return result; + +} diff --git a/tools/d2c/syntax.h b/tools/d2c/syntax.h new file mode 100644 index 0000000..0cd9210 --- /dev/null +++ b/tools/d2c/syntax.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * syntax.h - prototypes pour la prise en compte d'une syntaxe du langage d'assemblage + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 . + */ + + +#ifndef _TOOLS_SYNTAX_H +#define _TOOLS_SYNTAX_H + + +#include + + +#include "bits.h" +#include "conv.h" +#include "pproc.h" + + + +/* Syntaxe d'une ligne d'assembleur */ +typedef struct _asm_syntax asm_syntax; + + +/* Crée un nouvel indicateur pour l'écriture d'une instruction. */ +asm_syntax *create_asm_syntax(void); + +/* Supprime de la mémoire un indicateur d'écriture ASM. */ +void delete_asm_syntax(asm_syntax *); + +/* Enregistre la présence d'un nouvel opérande dans la syntaxe. */ +void register_syntax_item(asm_syntax *, char *, bool); + +/* Marque les champs de bits effectivement utilisés. */ +bool mark_syntax_items(const asm_syntax *, const coding_bits *, const conv_list *); + +/* Déclare les variables C associées aux opérandes de syntaxe. */ +bool declare_syntax_items(const asm_syntax *, int, const coding_bits *, const conv_list *, unsigned int); + +/* Définit les variables C associées aux opérandes de syntaxe. */ +bool define_syntax_items(const asm_syntax *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); + + + +#endif /* _TOOLS_SYNTAX_H */ diff --git a/tools/d2c_gram.y b/tools/d2c_gram.y deleted file mode 100644 index 5deb053..0000000 --- a/tools/d2c_gram.y +++ /dev/null @@ -1,442 +0,0 @@ - -%{ - -#include -#include -#include -#include -#include - - -#include "coder.h" -#include "d2c_tok.h" - - -extern int yylex(); - -extern void free_flex_memory(void); - - -/* Affiche un message d'erreur suite à l'analyse en échec. */ -static int d2c_error(rented_coder *, char *); - -/* Affiche des indications sur l'utilisation du programme. */ -static void show_usage(const char *); - - -%} - - -%code requires { - -/* Pour la définition des expressions conditionnelles... */ -#include "coder.h" - -#include "conv.h" - -struct action_tmp -{ - CondActionType action; - const char *details; -}; - - - - -#define register_named_field_in_coder(c, n, l) \ - ({ \ - encoding_spec *__spec; \ - coding_bits *__bits; \ - __spec = get_current_encoding_spec(c); \ - __bits = get_bits_in_encoding_spec(__spec); \ - register_named_field_in_bits(__bits, n, l); \ - }) - -#define register_bit_in_coder(c, v) \ - ({ \ - encoding_spec *__spec; \ - coding_bits *__bits; \ - __spec = get_current_encoding_spec(c); \ - __bits = get_bits_in_encoding_spec(__spec); \ - register_bit_in_bits(__bits, v); \ - }) - -#define count_coder_bits(c) \ - ({ \ - encoding_spec *__spec; \ - coding_bits *__bits; \ - __spec = get_current_encoding_spec(c); \ - __bits = get_bits_in_encoding_spec(__spec); \ - count_coded_bits(__bits); \ - }) - -#define register_syntax_item_in_coder(c, n, i) \ - ({ \ - encoding_spec *__spec; \ - asm_syntax *__syntax; \ - __spec = get_current_encoding_spec(c); \ - __syntax = get_syntax_in_encoding_spec(__spec); \ - register_syntax_item(__syntax, n, i); \ - }) - -#define register_conversion_in_coder(c, f) \ - ({ \ - encoding_spec *__spec; \ - conv_list *__list; \ - __spec = get_current_encoding_spec(c); \ - __list = get_conversions_in_encoding_spec(__spec); \ - register_conversion(__list, f); \ - }) - -#define add_conditional_rule_to_coder(c, e, a, d) \ - ({ \ - encoding_spec *__spec; \ - decoding_rules *__rules; \ - __spec = get_current_encoding_spec(c); \ - __rules = get_rules_in_encoding_spec(__spec); \ - register_conditional_rule(__rules, e, a, d); \ - }) - - - - - - -} - -%union { - - char *string; /* Chaîne de caractères #1 */ - const char *cstring; /* Chaîne de caractères #2 */ - - - int integer; - - conv_func *subst; /* Fonction de conversion */ - conv_arg_list_t *conv_list; /* Liste d'arguments de conv. */ - - conv_expr_t *conv; /* Expression de conversion */ - ConvUnaryOperation un_op; /* Opération unaire */ - ConvBinaryOperation bin_op; /* Opération bianire */ - - - cond_expr *expr; /* Expression de déclenchement */ - struct action_tmp tmpa; /* Transfert temporaire */ - -} - -%parse-param { rented_coder *coder } - - -%token COPYRIGHT -%token TITLE -%token INS_NAME INS_DETAILS - -%token ENCODING -%token THUMB ARCH NUMBER -%token ENC_START ENC_END - -%token WORD HALF NAME SIZE BIT - -%token SYNTAX OPERAND_INTERNAL OPERAND_VISIBLE - -%token CONV EQ OP COMMA CP NOT EOR COLON - -%token RULES IF EXPR_START EQUAL BINVAL EXPR_END AND THEN SEE - - -%type COPYRIGHT INS_NAME -%type INS_DETAILS - -%type NUMBER - -%type NAME -%type SIZE BIT - -%type OPERAND_INTERNAL OPERAND_VISIBLE - - -%type substitution -%type conv_arg_list -%type conv_expr conv_arg_composed -%type conv_expr_un_op -%type conv_expr_bin_op -%type conv_arg_field - -%type rule_cond -%type BINVAL -%type action - - -%% - - -input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; } - -name : COPYRIGHT TITLE INS_NAME { save_notes_for_coder(coder, $1, $3, NULL); } - | COPYRIGHT TITLE INS_NAME INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4); } - - - - -encodings : /* empty */ - | encoding encodings - -encoding : ENCODING THUMB NUMBER content { push_encoding_spec(coder, strdup("t"), $3); } - | ENCODING ARCH NUMBER content { push_encoding_spec(coder, strdup("a"), $3); } - - -content : /* empty */ - | bitfield content - | syntax content - | conversions content - | rules content - - -bitfield : HALF bits { - if (count_coder_bits(coder) != 16) - { - fprintf(stderr, "Unexpected word size: %u vs 16\n", count_coder_bits(coder)); - YYABORT; - } - } - | WORD bits { - if (count_coder_bits(coder) != 32) - { - fprintf(stderr, "Unexpected word size: %u vs 32\n", count_coder_bits(coder)); - YYABORT; - } - } - -bits : /* empty */ - | NAME SIZE bits { register_named_field_in_coder(coder, $1, $2); } - | BIT bits { register_bit_in_coder(coder, $1); } - - -syntax : SYNTAX operands - -operands : /* empty */ - | operands OPERAND_INTERNAL { register_syntax_item_in_coder(coder, $2, true); } - | operands OPERAND_VISIBLE { register_syntax_item_in_coder(coder, $2, false); } - - -conversions : CONV substitutions - -substitutions : /* empty */ - | substitutions substitution { register_conversion_in_coder(coder, $2); } - -substitution : NAME EQ conv_expr { $$ = make_conv_from_expr($1, $3); } - | NAME EQ NAME OP conv_arg_list CP { $$ = make_conv_from_func($1, $3, $5); } - -conv_arg_list : conv_expr { $$ = build_conv_arg_list($1); } - | conv_arg_list COMMA conv_expr { $$ = extend_conv_arg_list($1, $3); printf("extend\n"); } - -conv_expr : NAME { $$ = build_conv_expr_from_name($1); } - | NUMBER { $$ = build_conv_expr_from_number($1); } - | conv_arg_composed { $$ = $1; } - | OP conv_expr CP { $$ = $2; } - | conv_expr_un_op conv_expr { $$ = build_unary_conv_expr($2, $1); } - | OP conv_expr conv_expr_bin_op conv_expr CP { $$ = build_binary_conv_expr($2, $4, $3); } - -conv_expr_un_op : NOT { $$ = CUO_NOT; } - -conv_expr_bin_op : EOR { $$ = CBO_EOR; } - -conv_arg_composed : conv_arg_field COLON conv_arg_field { $$ = build_composed_conv_expr($1, $3); } - | conv_arg_composed COLON conv_arg_field { $$ = extend_composed_conv_expr($1, $3); } - -conv_arg_field : NAME { $$ = $1; printf(" composed::name '%s'\n", $1); } - | BINVAL { $$ = $1; printf(" composed::bin '%s'\n", $1); } - - -rules : RULES rules_list - -rules_list : /* empty */ - | rules_list rule - -rule : IF EXPR_START rule_cond EXPR_END THEN action - { add_conditional_rule_to_coder(coder, $3, $6.action, $6.details); } - -rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3); } - | EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END - { $$ = build_composed_cond_expression($2, COT_AND, $6); } - -action : SEE INS_DETAILS { $$.action = CAT_SEE; $$.details = $2; } - - -%% - - -/****************************************************************************** -* * -* Paramètres : coder = codeur impliqué dans le processus. * -* msg = message d'erreur. * -* * -* Description : Affiche un message d'erreur suite à l'analyse en échec. * -* * -* Retour : 0 * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int d2c_error(rented_coder *coder, char *msg) -{ - printf("yyerror line %d: %s\n", d2c_get_lineno(), msg); - - return 0; - -} - - -/****************************************************************************** -* * -* Paramètres : argv0 = nombre du programme exécuté. * -* * -* Description : Affiche des indications sur l'utilisation du programme. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void show_usage(const char *argv0) -{ - printf("\n"); - - printf("Usage: %s [options] < file\n", argv0); - - printf("\n"); - - printf("Options:\n"); - - printf("\n"); - - printf("\t-h | --help\t\t\tDisplay this messsage.\n"); - printf("\t-d | --dir \t\tSpecify the main output directory.\n"); - printf("\t-a | --arch \t\tDefine the archicture to handle.\n"); - printf("\t-H | --header \t\tSet the base of the #ifndef / #define game.\n"); - printf("\t-e | --encoding \tDefine encoding prefixes for files.\n"); - printf("\t-m | --macro \t\tRegister some conversion functions.\n"); - - printf("\n"); - -} - - -/****************************************************************************** -* * -* Paramètres : argc = nombre d'arguments dans la ligne de commande. * -* argv = arguments de la ligne de commande. * -* * -* Description : Point d'entrée du programme. * -* * -* Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int main(int argc, char **argv) -{ - int result; /* Bilan à retourner */ - rented_coder *coder; /* Codeur à briffer & employer */ - int index; /* Indice de fichier à traiter */ - bool need_help; /* Affichage de l'aide ? */ - bool has_error; /* Erreur dans la ligne de cmd.*/ - int ret; /* Bilan d'une lecture d'arg. */ - char *sep; /* Caratère '=' en coupure */ - - static struct option long_options[] = { - - { "help", no_argument, NULL, 'h' }, - { "dir", required_argument, NULL, 'd' }, - { "arch", required_argument, NULL, 'a' }, - { "header", required_argument, NULL, 'H' }, - { "encoding", required_argument, NULL, 'e' }, - { "macro", required_argument, NULL, 'M' }, - { NULL, 0, NULL, 0 } - - }; - - result = EXIT_SUCCESS; - - coder = create_coder(); - - index = 0; - - need_help = false; - has_error = false; - - while (!has_error) - { - ret = getopt_long(argc, argv, "hd:a:H:e:M:", long_options, &index); - if (ret == -1) break; - - switch (ret) - { - case 'h': - need_help = true; - break; - - case 'd': - set_coder_output_directory(coder, optarg); - break; - - case 'a': - set_coder_arch(coder, optarg); - break; - - case 'H': - set_coder_header_base(coder, optarg); - break; - - case 'e': - - sep = strchr(optarg, '='); - has_error = (sep == NULL); - - if (!has_error) - { - *sep = '\0'; - register_encoding(get_coder_pre_proc(coder), optarg, sep + 1); - } - - break; - - case 'M': - - sep = strchr(optarg, '='); - has_error = (sep == NULL); - - if (!has_error) - { - *sep = '\0'; - define_macro(get_coder_pre_proc(coder), optarg, sep + 1); - } - - break; - - } - - } - - if (need_help || has_error || !do_basic_checks_with_coder(coder) || optind != argc) - { - show_usage(argv[0]); - result = (need_help ? EXIT_SUCCESS : EXIT_FAILURE); - goto exit; - } - - result = yyparse(coder); - - exit: - - free_flex_memory(); - - delete_coder(coder); - - return result; - -} diff --git a/tools/d2c_tok.l b/tools/d2c_tok.l deleted file mode 100644 index 50a8d8f..0000000 --- a/tools/d2c_tok.l +++ /dev/null @@ -1,187 +0,0 @@ - -%{ - -typedef struct _rented_coder rented_coder; - - -#include "d2c-d2c_gram.h" - -#include -#include - - -/* Tente de libérer autant de mémoire que possible... */ -void free_flex_memory(void) ; - - -%} - -%option noyywrap -%option nounput -%option noinput -%option yylineno - - -%x comments - -%x ins_name try_details ins_details -%x encoding encoding_type encoding_content - -%x encoding_bits encoding_bits_size - -%x syntax syntax_int syntax_ext - -%x conv_begin conv_content conv_arg conv_arg_binval - -%x rules_begin rules_content rules_cond rules_cond_binval rules_action rules_actin_see - - -%% - - -[ \t\n]+ { } - -"/*" { BEGIN(comments); } -"*/" { BEGIN(INITIAL); } -[^*\n] { } -"Copyright"[^\n]* { d2c_lval.string = strdup(yytext); return COPYRIGHT; } -"*" { } -"\n" { } - - -"@title" { BEGIN(ins_name); return TITLE; } - -[ ][A-Za-z-]+ { d2c_lval.string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; } -[ ,/] { BEGIN(ins_details); } -[\n] { BEGIN(INITIAL); } - -[^\n]* { d2c_lval.cstring = yytext; return INS_DETAILS; } -[\n] { BEGIN(INITIAL); } - - - -"@encoding" { BEGIN(encoding); return ENCODING; } - -[ ] { } -"(" { BEGIN(encoding_type); } - -"T" { return THUMB; } -"A" { return ARCH; } -[0-9] { d2c_lval.integer = atoi(yytext); return NUMBER; } -")" { BEGIN(encoding); } - -"{" { BEGIN(encoding_content); } -[ \t\n]+ { } -"}" { BEGIN(INITIAL); } - - - -"@half" { BEGIN(encoding_bits); return HALF; } -"@word" { BEGIN(encoding_bits); return WORD; } - -" " { } -"\n" { BEGIN(encoding_content); } -[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; } - -"(" { BEGIN(encoding_bits_size); } -[0-9]+ { d2c_lval.integer = atoi(yytext); return SIZE; } -")" { BEGIN(encoding_bits); } - -[01] { d2c_lval.integer = atoi(yytext); return BIT; } - - - -"@syntax" { BEGIN(syntax); return SYNTAX; } - -[ ]+ { } -"\n" { BEGIN(encoding_content); } - -"{" { BEGIN(syntax_int); } -[^ \n}]+ { d2c_lval.string = strdup(yytext); return OPERAND_INTERNAL; } -"}" { BEGIN(syntax); } - -"<" { BEGIN(syntax_ext); } -[^ \n>]+ { d2c_lval.string = strdup(yytext); return OPERAND_VISIBLE; } -">" { BEGIN(syntax); } - - - -"@conv" { BEGIN(conv_begin); return CONV; } -[ ]+ { } -"{" { BEGIN(conv_content); } -"}" { BEGIN(encoding_content); } - -[ \t\n]+ { } -[A-Za-z][A-Za-z0-9]* { - if (strcmp(yytext, "NOT") == 0) return NOT; - else - { - d2c_lval.string = strdup(yytext); - return NAME; - } - } -"=" { return EQ; } -"(" { BEGIN(conv_arg); return OP; } -[A-Za-z][A-Za-z0-9]* { - if (strcmp(yytext, "NOT") == 0) return NOT; - else if (strcmp(yytext, "EOR") == 0) return EOR; - else - { - d2c_lval.string = strdup(yytext); - return NAME; - } - } -[0-9][0-9]* { d2c_lval.integer = atoi(yytext); return NUMBER; } -"'" { BEGIN(conv_arg_binval); } -[01][01]* { d2c_lval.string = strdup(yytext); return BINVAL; } -"'" { BEGIN(conv_arg); } -"," { return COMMA; } -":" { return COLON; } -[ ]+ { } -")" { BEGIN(conv_content); return CP; } - - - -"@rules" { BEGIN(rules_begin); return RULES; } -[ ]+ { } -"{" { BEGIN(rules_content); } -[ \t\n]+ { } -"}" { BEGIN(encoding_content); } - -"if" { BEGIN(rules_cond); return IF; } -[ ]+ { } -"(" { return EXPR_START; } -[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; } -"==" { return EQUAL; } -"'" { BEGIN(rules_cond_binval); } -[01][01]* { d2c_lval.string = strdup(yytext); return BINVAL; } -"'" { BEGIN(rules_cond); } -")" { return EXPR_END; } -"&&" { return AND; } - -";" { BEGIN(rules_action); return THEN; } -[ ]+ { } -"see " { BEGIN(rules_actin_see); return SEE; } -[^\n]* { d2c_lval.cstring = yytext; BEGIN(rules_content); return INS_DETAILS; } - - -%% - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Tente de libérer autant de mémoire que possible... * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void free_flex_memory(void) -{ - yy_delete_buffer(YY_CURRENT_BUFFER); - -} diff --git a/tools/helpers.c b/tools/helpers.c deleted file mode 100644 index 1353ba2..0000000 --- a/tools/helpers.c +++ /dev/null @@ -1,144 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers.c - fonctionnalités d'assitance à la compilation - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "helpers.h" - - -#include -#include - - - -/* ---------------------------------------------------------------------------------- */ -/* MANIPULATIONS DE CHAINES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : str = chaîne de caractères à manipuler. [OUT] * -* * -* Description : Bascule toute une chaîne de caractères en (min|maj)uscules. * -* * -* Retour : Pointeur sur la chaîne fournie. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *_make_string_xxx(char *str, int (* fn) (int)) -{ - size_t max; /* Empleur du parcours */ - size_t i; /* Boucle de parcours */ - - max = strlen(str); - - for (i = 0; i < max; i++) - str[i] = fn(str[i]); - - return str; - -} - - -/****************************************************************************** -* * -* Paramètres : raw = données brutes en provenance de l'analyseur. * -* details = indique la nature de la chaîne à traiter. * -* * -* Description : Traduit une chaîne en élément de fonction C. * -* * -* Retour : Chaîne à libérer de la mémoire après usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *make_callable(const char *raw, bool details) -{ - char *result; /* Nom formaté à retourner */ - size_t max; /* Empleur du parcours */ - size_t i; /* Boucle de parcours */ - - result = strdup(raw); - - max = strlen(result); - - /* Première passe : on vire les virgules */ - - for (i = 0; i < max; i++) - if (result[i] == ',') - { - memmove(result + i, result + i + 1, max - i - 1); - max--; - } - - result[max] = '\0'; - - /* Deuxième passe : on bascule en minuscules */ - - result = make_string_lower(result); - - /* Troisième passe : on remplace les mauvais caractères */ - - for (i = 0; i < max; i++) - switch (result[i]) - { - case 'a' ... 'z': - case '0' ... '9': - break; - case '-': - result[i] = '_'; - break; - default: - result[i] = (i + 1 == max ? '\0' : '_'); - break; - } - - /** - * Dernière passe : on s'assure que le premier caractère n'est pas une lettre. - * On ajoute ici le préfixe '_' utilisé lors de la génération de prototypes ; - * en cas d'absence de détails, on ne se retrouve ainsi pas avec un '_' isolé. - */ - - if (details && result[0] != '_') - { - max = strlen(result) + 1; - result = (char *)realloc(result, max); - memmove(result + 1, result, max - 1); - result[0] = '_'; - } - - /* Ultime passe : supression des '_' groupés */ - - for (i = 0; i < max; i++) - if (result[i] == '_' && result[i + 1] == '_') - { - memmove(result + i + 1, result + i + 2, max - i - 1); - max--; - i--; - } - - return result; - -} diff --git a/tools/helpers.h b/tools/helpers.h deleted file mode 100644 index 8c39a85..0000000 --- a/tools/helpers.h +++ /dev/null @@ -1,47 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * helpers.h - prototypes pour les fonctionnalités d'assitance à la compilation - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_HELPERS_H -#define _TOOLS_HELPERS_H - - -#include -#include - - - -/* ---------------------------- MANIPULATIONS DE CHAINES ---------------------------- */ - - -/* Bascule toute une chaîne de caractères en (min|maj)uscules. */ -char *_make_string_xxx(char *, int (* fn) (int)); - -#define make_string_lower(str) _make_string_xxx(str, tolower) -#define make_string_upper(str) _make_string_xxx(str, toupper) - -/* Traduit une chaîne en élément de fonction C. */ -char *make_callable(const char *raw, bool); - - - -#endif /* _TOOLS_HELPERS_H */ diff --git a/tools/macros.c b/tools/macros.c deleted file mode 100644 index b1c44f0..0000000 --- a/tools/macros.c +++ /dev/null @@ -1,167 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pproc.c - remplacements à la volée de chaînes de caractères - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "pproc.h" - - -#include - - - - - - -/* Conversion des chaînes en chaînes */ -typedef struct _string_exch -{ - const char *src; /* Chaîne à trouver */ - const char *dest; /* Chaîne de remplacement */ - -} string_exch; - - -/* Pré-processeur avec support des macros */ -struct _pre_processor -{ - string_exch *macros; /* Remplacements de chaînes */ - size_t macros_count; /* Nombre de ces remplacements */ - - - -} - - - - - - -/****************************************************************************** -* * -* 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->bits = create_coding_bits(); - result->syntax = create_asm_syntax(); - result->conversions = create_conv_list(); - 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_coding_bits(spec->bits); - delete_asm_syntax(spec->syntax); - delete_conv_list(spec->conversions); - delete_decoding_rules(spec->rules); - - free(spec); - -} - - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* src = chaîne à remplacer dans les définitions. * -* dest = chaîne de remplacement. * -* * -* Description : Constitue la matière d'un système de macros. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void define_macro_for_coder(rented_coder *coder, const char *src, const char *dest) -{ - string_exch *macro; /* Nouvelle macro à constituer */ - - coder->macros = (string_exch *)realloc(coder->macros, ++coder->macros_count * sizeof(string_exch)); - - macro = &coder->macros[coder->macros_count - 1]; - - macro->src = src; - macro->dest = dest; - -} - - -/****************************************************************************** -* * -* Paramètres : coder = gestion par la machine en remplacement de l'humain. * -* src = chaîne à remplacer dans les définitions. * -* * -* Description : Recherche l'existence d'une macro pour un remplacement. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static const char *find_macro_in_coder(const rented_coder *coder, const char *src) -{ - const char *result; /* Trouvaille à renvoyer */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - for (i = 0; i < coder->macros_count && result == NULL; i++) - if (strcmp(coder->macros[i].src, src) == 0) - result = coder->macros[i].dest; - - return result; - -} - - diff --git a/tools/macros.h b/tools/macros.h deleted file mode 100644 index 3755f00..0000000 --- a/tools/macros.h +++ /dev/null @@ -1,30 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * macros.h - prototypes pour les remplacements à la volée de chaînes de caractères - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_MACROS_H -#define _TOOLS_MACROS_H - - - - -#endif /* _TOOLS_MACROS_H */ diff --git a/tools/pproc.c b/tools/pproc.c deleted file mode 100644 index 8644af5..0000000 --- a/tools/pproc.c +++ /dev/null @@ -1,214 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pproc.c - remplacements à la volée de chaînes de caractères - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "pproc.h" - - -#include -#include - - - -/* Pré-processeur avec support des macros */ -struct _pre_processor -{ - string_exch *encodings; /* Traductions d'encodages */ - size_t encodings_count; /* Nombre de ces traductions */ - - string_exch *macros; /* Remplacements de chaînes */ - size_t macros_count; /* Nombre de ces remplacements */ - -}; - - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau pre-processeur pour le support des macros. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -pre_processor *create_pre_processor(void) -{ - pre_processor *result; /* Définition vierge à renvoyer*/ - - result = (pre_processor *)calloc(1, sizeof(pre_processor)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur à libérer de la mémoire. * -* * -* Description : Supprime de la mémoire un pré-processeur et ses macros. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_pre_processor(pre_processor *pp) -{ - if (pp->encodings != NULL) - free(pp->encodings); - - if (pp->macros != NULL) - free(pp->macros); - - free(pp); - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur dont le contenu est à compléter. * -* src = chaîne à remplacer dans les définitions. * -* dest = chaîne de remplacement. * -* * -* Description : Enregistre une correspondance en matière d'encodage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_encoding(pre_processor *pp, const char *src, const char *dest) -{ - string_exch *encoding; /* Traduction à conserver */ - - pp->encodings = (string_exch *)realloc(pp->encodings, ++pp->encodings_count * sizeof(string_exch)); - - encoding = &pp->encodings[pp->encodings_count - 1]; - - encoding->src = src; - encoding->dest = dest; - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur dont le contenu est à consulter. * -* * -* Description : Indique le nombre de catégories d'encodages enregistrées. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t count_encodings(const pre_processor *pp) -{ - return pp->encodings_count; - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur dont le contenu est à consulter. * -* index = indice de l'encodage à retourner. * -* * -* Description : Fournit une catégorie d'encodage donnée. * -* * -* Retour : Correspondance à consulter uniquement. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const string_exch *find_encoding(const pre_processor *pp, size_t index) -{ - return &pp->encodings[index]; - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur dont le contenu est à compléter. * -* src = chaîne à remplacer dans les définitions. * -* dest = chaîne de remplacement. * -* * -* Description : Constitue la matière d'un système de macros. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void define_macro(pre_processor *pp, const char *src, const char *dest) -{ - string_exch *macro; /* Nouvelle macro à constituer */ - - pp->macros = (string_exch *)realloc(pp->macros, ++pp->macros_count * sizeof(string_exch)); - - macro = &pp->macros[pp->macros_count - 1]; - - macro->src = src; - macro->dest = dest; - -} - - -/****************************************************************************** -* * -* Paramètres : pp = pré-processeur dont le contenu est à consulter. * -* src = chaîne à remplacer dans les définitions. * -* * -* Description : Recherche l'existence d'une macro pour un remplacement. * -* * -* Retour : Eventuelle correspondance trouvée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *find_macro(const pre_processor *pp, const char *src) -{ - const char *result; /* Trouvaille à renvoyer */ - size_t i; /* Boucle de parcours */ - - result = NULL; - - for (i = 0; i < pp->macros_count && result == NULL; i++) - if (strcmp(pp->macros[i].src, src) == 0) - result = pp->macros[i].dest; - - return result; - -} diff --git a/tools/pproc.h b/tools/pproc.h deleted file mode 100644 index 6675fa1..0000000 --- a/tools/pproc.h +++ /dev/null @@ -1,67 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * pproc.h - prototypes pour les remplacements à la volée de chaînes de caractères - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_PPROC_H -#define _TOOLS_PPROC_H - - -#include - - - -/* Conversion des chaînes en chaînes */ -typedef struct _string_exch -{ - const char *src; /* Chaîne à trouver */ - const char *dest; /* Chaîne de remplacement */ - -} string_exch; - -/* Pré-processeur avec support des macros */ -typedef struct _pre_processor pre_processor; - - -/* Crée un nouveau pre-processeur pour le support des macros. */ -pre_processor *create_pre_processor(void); - -/* Supprime de la mémoire un pré-processeur et ses macros. */ -void delete_pre_processor(pre_processor *); - -/* Enregistre une correspondance en matière d'encodage. */ -void register_encoding(pre_processor *, const char *, const char *); - -/* Indique le nombre de catégories d'encodages enregistrées. */ -size_t count_encodings(const pre_processor *); - -/* Fournit une catégorie d'encodage donnée. */ -const string_exch *find_encoding(const pre_processor *, size_t); - -/* Constitue la matière d'un système de macros. */ -void define_macro(pre_processor *, const char *, const char *); - -/* Recherche l'existence d'une macro pour un remplacement. */ -const char *find_macro(const pre_processor *, const char *); - - - -#endif /* _TOOLS_PPROC_H */ diff --git a/tools/rules.c b/tools/rules.c deleted file mode 100644 index 25ba76c..0000000 --- a/tools/rules.c +++ /dev/null @@ -1,439 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * rules.h - prototypes pour les variations de décodage selon certaines conditions - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "rules.h" - - -#include -#include -#include - - -#include "helpers.h" - - - -/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */ - - -/* Expression d'une condition */ -struct _cond_expr -{ - bool is_simple; /* Sélection de champ */ - - union - { - struct - { - char *variable; /* Variable manipulée */ - CondCompType comp; /* Type de comparaison */ - char *bvalue; /* Valeur binaire comparée */ - - } simple; - - struct - { - cond_expr *a; /* Première sous-expression */ - CondOpType operator; /* Relation entre expressions */ - cond_expr *b; /* Seconde sous-expression */ - - } composed; - - }; - -}; - - -/* Libère de la mémoire une expression conditionnelle. */ -static void delete_cond_expr(cond_expr *); - -/* Traduit en code une expression de condition. */ -static bool write_cond_expr(const cond_expr *, int, const coding_bits *); - - - -/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */ - - -/* Règle particulière */ -typedef struct _extra_rule -{ - cond_expr *expr; /* Expression de déclenchement */ - CondActionType action; /* Conséquence d'une validation*/ - char *details; /* Eventuel complément d'info. */ - -} extra_rule; - -/* Règles de décodage supplémentaires */ -struct _decoding_rules -{ - extra_rule *extra; /* Règles conditionnelles */ - size_t extra_count; /* Nombre de ces règles */ - -}; - - - -/* ---------------------------------------------------------------------------------- */ -/* CONDITIONS DE DECLENCHEMENTS */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : variable = désignation de la variable à manipuler. * -* comp = type de comparaison à utiliser. * -* bvalue = valeur binaire à comparer. * -* * -* Description : Crée une expression conditionnelle simple. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *bvalue) -{ - cond_expr *result; /* Structure à retourner */ - - result = (cond_expr *)calloc(1, sizeof(cond_expr)); - - result->is_simple = true; - - result->simple.variable = make_string_lower(variable); - result->simple.comp = comp; - result->simple.bvalue = bvalue; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : a = première expression à intégrer. * -* operator = type de comparaison à utiliser. * -* b = second expression à intégrer. * -* * -* Description : Crée une expression conditionnelle composée. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, cond_expr *b) -{ - cond_expr *result; /* Structure à retourner */ - - result = (cond_expr *)calloc(1, sizeof(cond_expr)); - - result->is_simple = false; - - result->composed.a = a; - result->composed.operator = operator; - result->composed.b = b; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = représentation d'expression à traiter. * -* * -* Description : Libère de la mémoire une expression conditionnelle. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void delete_cond_expr(cond_expr *expr) -{ - if (expr->is_simple) - { - free(expr->simple.variable); - free(expr->simple.bvalue); - } - else - { - delete_cond_expr(expr->composed.a); - delete_cond_expr(expr->composed.b); - } - - free(expr); - -} - - -/****************************************************************************** -* * -* Paramètres : expr = expression simple ou composée à transposer. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* * -* Description : Traduit en code une expression de condition. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits) -{ - bool result; /* Bilan à renvoyer */ - const raw_bitfield *bf; /* Champ de bits de définition */ - - result = true; - - dprintf(fd, "("); - - if (expr->is_simple) - { - bf = find_named_field_in_bits(bits, expr->simple.variable); - if (bf == NULL) - { - fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable); - result = false; - goto wce_exit; - } - - if (get_raw_bitfield_length(bf) != strlen(expr->simple.bvalue)) - { - fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %zu).\n", - expr->simple.variable, get_raw_bitfield_length(bf), strlen(expr->simple.bvalue)); - result = false; - goto wce_exit; - } - - dprintf(fd, "raw_%s", expr->simple.variable); - - switch (expr->simple.comp) - { - case CCT_EQUAL: - dprintf(fd, " == "); - break; - case CCT_DIFF: - dprintf(fd, " != "); - break; - } - - dprintf(fd, "b%s", expr->simple.bvalue); - - } - else - { - result = write_cond_expr(expr->composed.a, fd, bits); - if (!result) goto wce_exit; - - switch (expr->composed.operator) - { - case COT_AND: - dprintf(fd, " && "); - break; - case COT_OR: - dprintf(fd, " || "); - break; - } - - result = write_cond_expr(expr->composed.b, fd, bits); - if (!result) goto wce_exit; - - } - - dprintf(fd, ")"); - - wce_exit: - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* REGLES ET ACTIONS CONSEQUENTES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau rassemblement de règles de décodage. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -decoding_rules *create_decoding_rules(void) -{ - decoding_rules *result; /* Définition vierge à renvoyer*/ - - result = (decoding_rules *)calloc(1, sizeof(decoding_rules)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : rules = ensemble de règles de décodage à supprimer. * -* * -* Description : Supprime de la mémoire un ensemble de règles supplémentaires.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_decoding_rules(decoding_rules *rules) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < rules->extra_count; i++) - { - delete_cond_expr(rules->extra[i].expr); - if (rules->extra[i].details) - free(rules->extra[i].details); - } - - if (rules->extra != NULL) - free(rules->extra); - - free(rules); - -} - - -/****************************************************************************** -* * -* Paramètres : rules = ensemble de règles à compléter. * -* expr = représentation d'expression à conserver. * -* action = conséquence associée à la règle. * -* details = éventuel complément d'informations. * -* * -* Description : Ajoute une règle complète à la définition d'un codage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_conditional_rule(decoding_rules *rules, cond_expr *expr, CondActionType action, const char *details) -{ - extra_rule *rule; /* Nouvelle prise en compte */ - - rules->extra = (extra_rule *)realloc(rules->extra, ++rules->extra_count * sizeof(extra_rule)); - - rule = &rules->extra[rules->extra_count - 1]; - - rule->expr = expr; - rule->action = action; - rule->details = (details != NULL ? make_callable(details, false) : NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : rules = ensemble de règles à consulter. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* exit = exprime le besoin d'une voie de sortie. [OUT] * -* * -* Description : Traduit en code les éventuelles règles présentes. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_decoding_rules(decoding_rules *rules, int fd, const coding_bits *bits, bool *exit) -{ - bool result; /* Bilan à remonter */ - const extra_rule *rule; /* Règle en cours d'écriture */ - size_t i; /* Boucle de parcours */ - - result = true; - - *exit = false; - - for (i = 0; i < rules->extra_count; i++) - { - rule = &rules->extra[i]; - - dprintf(fd, "\t\tif "); - - result = write_cond_expr(rule->expr, fd, bits); - if (!result) break; - - dprintf(fd, "\n"); - dprintf(fd, "\t\t{\n"); - - switch (rule->action) - { - case CAT_SEE: - - if (rule->details == NULL) - { - fprintf(stderr, "Error: directive 'see' must provide additional details.\n"); - result = false; - goto wcsr_exit; - } - - dprintf(fd, "\t\t\tinstr = armv7_read_instr_%s", rule->details); - - /* TODO : adapter les paramètres d'appel selon le 'coder' */ - dprintf(fd, "(_raw);\n"); - - dprintf(fd, "\t\t\tgoto quick_exit;\n"); - - *exit = true; - break; - - } - - dprintf(fd, "\t\t}\n"); - - dprintf(fd, "\n"); - - } - - wcsr_exit: - - return result; - -} diff --git a/tools/rules.h b/tools/rules.h deleted file mode 100644 index a4a9bb4..0000000 --- a/tools/rules.h +++ /dev/null @@ -1,91 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * rules.h - prototypes pour les variations de décodage selon certaines conditions - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_RULES_H -#define _TOOLS_RULES_H - - -#include "bits.h" - - - -/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */ - - -/* Types de comparaison */ -typedef enum _CondCompType -{ - CCT_EQUAL, /* Egalité '==' */ - CCT_DIFF /* Différence '!=' */ - -} CondCompType; - -/* Types de combinaison d'expressions */ -typedef enum _CondOpType -{ - COT_AND, /* Combinaison ET ('&&') */ - COT_OR /* Combinaison OU ('||') */ - -} CondOpType; - -/* Expression d'une condition */ -typedef struct _cond_expr cond_expr; - - -/* Crée une expression conditionnelle simple. */ -cond_expr *build_simple_cond_expression(char *, CondCompType, char *); - -/* Crée une expression conditionnelle composée. */ -cond_expr *build_composed_cond_expression(cond_expr *, CondOpType, cond_expr *); - - - -/* ------------------------- REGLES ET ACTIONS CONSEQUENTES ------------------------- */ - - -/* Conséquence en cas de condition remplie */ -typedef enum _CondActionType -{ - CAT_SEE /* Renvoi vers une instruction */ - -} CondActionType; - -/* Règles de décodage supplémentaires */ -typedef struct _decoding_rules decoding_rules; - - -/* Crée un nouveau rassemblement de règles de décodage. */ -decoding_rules *create_decoding_rules(void); - -/* Supprime de la mémoire un ensemble de règles supplémentaires. */ -void delete_decoding_rules(decoding_rules *); - -/* Ajoute une règle complète à la définition d'un codage. */ -void register_conditional_rule(decoding_rules *, cond_expr *, CondActionType, const char *); - -/* Traduit en code les éventuelles règles présentes. */ -bool write_decoding_rules(decoding_rules *, int, const coding_bits *, bool *); - - - -#endif /* _TOOLS_RULES_H */ diff --git a/tools/spec.c b/tools/spec.c deleted file mode 100644 index a957587..0000000 --- a/tools/spec.c +++ /dev/null @@ -1,349 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * spec.c - représentation complète d'un encodage - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "spec.h" - - -#include -#include -#include - - -#include "helpers.h" - - - - - -#define get_raw_bitfield_name(bf) "" - - - - - -#define get_syntax_item_name(si) "" - - - - - - - -/* Mémorisation d'un encodage complet */ -struct _encoding_spec -{ - char *prefix; /* Distinction principale */ - unsigned int index; /* Distinction secondaire */ - - coding_bits *bits; /* Encodage des bits associés */ - asm_syntax *syntax; /* Calligraphe d'assemblage */ - conv_list *conversions; /* Conversions des données */ - 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->bits = create_coding_bits(); - result->syntax = create_asm_syntax(); - result->conversions = create_conv_list(); - 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_coding_bits(spec->bits); - delete_asm_syntax(spec->syntax); - delete_conv_list(spec->conversions); - 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->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) -{ - return (strcmp(spec->prefix, prefix) == 0); - -} - - -/****************************************************************************** -* * -* 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 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. * -* ins = désignation première de l'instruction manipulée. * -* details = particularités de l'instruction. * -* keyword = nom clef de l'instruction utilisable dans du code. * -* 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 *ins, const char *details, unsigned int wide, const pre_processor *pp) -{ - bool result; /* Bilan à retourner */ - char *keyword; /* Mot clef appelable en code */ - bool exit; /* Inclusion de sortie rapide ?*/ - - result = true; - - keyword = make_callable(ins, false); - - dprintf(fd, "\tGArchInstruction *%s_decode_%s%s_%s%u(uint%u_t _raw)\n", - arch, keyword, details, spec->prefix, 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 &= declare_used_bits_fields(spec->bits, fd, wide); - - result &= declare_syntax_items(spec->syntax, fd, spec->bits, spec->conversions, wide); - - dprintf(fd, "\n"); - - /* 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); - - dprintf(fd, "\n"); - - /* Inclusion des éventuelles règles */ - - result &= write_decoding_rules(spec->rules, fd, spec->bits, &exit); - - /* Création de l'instruction en elle-même */ - - dprintf(fd, "\t\tinstr = g_%s_instruction_new(\"%s\");\n", arch, ins); - - dprintf(fd, "\n"); - - /* Création des opérandes */ - - result &= define_syntax_items(spec->syntax, fd, arch, spec->bits, spec->conversions, pp); - - /* Conclusion de la procédure */ - - if (exit) - { - dprintf(fd, "\t quick_exit:\n"); - dprintf(fd, "\n"); - } - - dprintf(fd, "\t\treturn instr;\n"); - - dprintf(fd, "\n"); - - 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->prefix, spec->index); - - dprintf(fd, "\n"); - - free(keyword); - - return result; - -} diff --git a/tools/spec.h b/tools/spec.h deleted file mode 100644 index 46d922b..0000000 --- a/tools/spec.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * spec.h - prototypes pour la représentation complète d'un encodage - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_SPEC_H -#define _TOOLS_SPEC_H - - -#include - - -#include "bits.h" -#include "conv.h" -#include "pproc.h" -#include "rules.h" -#include "syntax.h" - - - -/* Mémorisation d'un encodage complet */ -typedef struct _encoding_spec encoding_spec; - - -/* Crée un nouveau suivi de l'encodage d'une instruction. */ -encoding_spec *create_encoding_spec(void); - -/* Supprime de la mémoire un suivi d'encodage d'une instruction. */ -void delete_encoding_spec(encoding_spec *); - -/* Définit le nom de code d'une spécification d'encodage. */ -void define_encoding_spec_code_name(encoding_spec *, char *, unsigned int); - -/* Indique si une spécification se range dans une catégorie. */ -bool has_encoding_spec_prefix(const encoding_spec *, const char *); - -/* Fournit le gestionnaire des bits d'un encodage d'instruction. */ -coding_bits *get_bits_in_encoding_spec(const encoding_spec *); - -/* Fournit l'indicateur des écritures correctes d'assembleur. */ -asm_syntax *get_syntax_in_encoding_spec(const encoding_spec *); - -/* Fournit la liste des fonctions de conversion. */ -conv_list *get_conversions_in_encoding_spec(const encoding_spec *); - -/* Fournit un ensemble de règles supplémentaires éventuel. */ -decoding_rules *get_rules_in_encoding_spec(const encoding_spec *); - -/* Traduit en code une sous-fonction de désassemblage. */ -bool write_encoding_spec_disass(const encoding_spec *, int, const char *, const char *, const char *, unsigned int, const pre_processor *); - - - -#endif /* _TOOLS_SPEC_H */ diff --git a/tools/syntax.c b/tools/syntax.c deleted file mode 100644 index 5fec1a6..0000000 --- a/tools/syntax.c +++ /dev/null @@ -1,321 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * syntax.c - prise en compte d'une syntaxe du langage d'assemblage - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#include "syntax.h" - - -#include -#include - - -#include "helpers.h" - - - -/* Propriétés particulières pour les opérandes */ -typedef enum _SyntaxItemFlags -{ - SIF_NONE = (0 << 0), /* Aucune propriété */ - SIF_DECIMAL = (1 << 0) /* Affichage en décimal */ - -} SyntaxItemFlags; - -/* Elément défini dans une syntaxe */ -typedef struct _syntax_item -{ - char *name; /* Désignation humaine */ - bool internal; /* Enregistrement générique ? */ - SyntaxItemFlags flags; /* Propriétés supplémentaires */ - -} syntax_item; - -/* Syntaxe d'une ligne d'assembleur */ -struct _asm_syntax -{ - syntax_item *items; /* Eléments de la syntaxe */ - size_t items_count; /* Nombre de ces éléments */ - -}; - - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouvel indicateur pour l'écriture d'une instruction. * -* * -* Retour : Nouvelle structure prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -asm_syntax *create_asm_syntax(void) -{ - asm_syntax *result; /* Définition vierge à renvoyer*/ - - result = (asm_syntax *)calloc(1, sizeof(asm_syntax)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * -* * -* Description : Supprime de la mémoire un indicateur d'écriture ASM. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void delete_asm_syntax(asm_syntax *syntax) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < syntax->items_count; i++) - free(syntax->items[i].name); - - if (syntax->items != NULL) - free(syntax->items); - - free(syntax); - -} - - -/****************************************************************************** -* * -* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * -* name = désignation de l'opérande dans la spécification. * -* internal = précise si l'opérand est non générique ou non. * -* * -* Description : Enregistre la présence d'un nouvel opérande dans la syntaxe. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_syntax_item(asm_syntax *syntax, char *name, bool internal) -{ - syntax_item *item; /* Nouvelle prise en compte */ - size_t len; /* Taille du nom fourni */ - - syntax->items = (syntax_item *)realloc(syntax->items, ++syntax->items_count * sizeof(syntax_item)); - - item = &syntax->items[syntax->items_count - 1]; - - /* Récupération des drapeaux */ - - item->flags = SIF_NONE; - - for (len = strlen(name); len > 0; len--) - switch (name[0]) - { - case '#': - item->flags |= SIF_DECIMAL; - memmove(name, name + 1, len); - break; - - default: - len = 1; - break; - - } - - item->name = make_string_lower(name); - item->internal = internal; - -} - - -/****************************************************************************** -* * -* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* * -* Description : Marque les champs de bits effectivement utilisés. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool mark_syntax_items(const asm_syntax *syntax, const coding_bits *bits, const conv_list *list) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - syntax_item *item; /* Lien vers un opérande */ - conv_func *func; /* Fonction de conversion */ - - result = true; - - for (i = 0; i < syntax->items_count && result; i++) - { - item = &syntax->items[i]; - - func = find_named_conv_in_list(list, item->name); - if (func == NULL) - { - fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); - result = false; - } - - result = mark_conv_func(func, bits, list); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * -* fd = descripteur d'un flux ouvert en écriture. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* wide = taille des mots décodés. * -* * -* Description : Déclare les variables C associées aux opérandes de syntaxe. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) -{ - bool result; /* Bilan à retourner */ - bool has_operand; /* Présence d'un opérande */ - size_t i; /* Boucle de parcours */ - syntax_item *item; /* Lien vers un opérande */ - conv_func *func; /* Fonction de conversion */ - - result = true; - - has_operand = false; - - for (i = 0; i < syntax->items_count && result; i++) - { - item = &syntax->items[i]; - - has_operand |= !item->internal; - - func = find_named_conv_in_list(list, item->name); - if (func == NULL) - { - fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); - result = false; - } - - result &= declare_conv_func(func, fd, bits, list, wide); - - } - - if (has_operand) - dprintf(fd, "\t\tGArchOperand *op;\n"); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. * -* fd = descripteur d'un flux ouvert en écriture. * -* arch = architecture visée par l'opération globale. * -* bits = gestionnaire des bits d'encodage. * -* list = liste de l'ensemble des fonctions de conversion. * -* pp = pré-processeur pour les échanges de chaînes. * -* * -* Description : Définit les variables C associées aux opérandes de syntaxe. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) -{ - bool result; /* Bilan à retourner */ - size_t i; /* Boucle de parcours */ - syntax_item *item; /* Lien vers un opérande */ - conv_func *func; /* Fonction de conversion */ - - result = true; - - for (i = 0; i < syntax->items_count && result; i++) - { - item = &syntax->items[i]; - - func = find_named_conv_in_list(list, item->name); - if (func == NULL) - { - fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name); - result = false; - } - - /* Appel proprement dit */ - - result &= define_conv_func(func, true, item->internal, fd, arch, bits, list, pp); - if (!result) break; - - /* Raccordement : propriété ou opérande ? */ - - if (item->internal) - dprintf(fd, "\t\t\tgoto bad_exit;\n"); - - else - { - dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n"); - - dprintf(fd, "\n"); - - if (item->flags & SIF_DECIMAL) - dprintf(fd, "\t\tg_imm_operand_set_display(G_IMM_OPERAND(op), IOD_DEC);\n"); - - dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n"); - - } - - dprintf(fd, "\n"); - - } - - return result; - -} diff --git a/tools/syntax.h b/tools/syntax.h deleted file mode 100644 index 0cd9210..0000000 --- a/tools/syntax.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * syntax.h - prototypes pour la prise en compte d'une syntaxe du langage d'assemblage - * - * Copyright (C) 2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 . - */ - - -#ifndef _TOOLS_SYNTAX_H -#define _TOOLS_SYNTAX_H - - -#include - - -#include "bits.h" -#include "conv.h" -#include "pproc.h" - - - -/* Syntaxe d'une ligne d'assembleur */ -typedef struct _asm_syntax asm_syntax; - - -/* Crée un nouvel indicateur pour l'écriture d'une instruction. */ -asm_syntax *create_asm_syntax(void); - -/* Supprime de la mémoire un indicateur d'écriture ASM. */ -void delete_asm_syntax(asm_syntax *); - -/* Enregistre la présence d'un nouvel opérande dans la syntaxe. */ -void register_syntax_item(asm_syntax *, char *, bool); - -/* Marque les champs de bits effectivement utilisés. */ -bool mark_syntax_items(const asm_syntax *, const coding_bits *, const conv_list *); - -/* Déclare les variables C associées aux opérandes de syntaxe. */ -bool declare_syntax_items(const asm_syntax *, int, const coding_bits *, const conv_list *, unsigned int); - -/* Définit les variables C associées aux opérandes de syntaxe. */ -bool define_syntax_items(const asm_syntax *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *); - - - -#endif /* _TOOLS_SYNTAX_H */ -- cgit v0.11.2-87-g4458