/* Chrysalide - Outil d'analyse de fichiers binaires
* syntax.c - représentation complète d'une syntaxe
*
* Copyright (C) 2017 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Chrysalide is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chrysalide. If not, see .
*/
#include "syntax.h"
#include
#include
/* Mémorisation d'une définition de syntaxe */
struct _encoding_syntax
{
instr_id *subid; /* Gestionnaire d'identifiant */
disass_assert *assertions; /* Conditions de désassemblage */
conv_list *conversions; /* Conversions des données */
asm_pattern *pattern; /* Calligraphe d'assemblage */
decoding_rules *rules; /* Règles supplémentaires */
};
/******************************************************************************
* *
* Paramètres : - *
* *
* Description : Crée un nouveau suivi d'une définition de syntaxe. *
* *
* Retour : Nouvelle structure prête à emploi. *
* *
* Remarques : - *
* *
******************************************************************************/
encoding_syntax *create_encoding_syntax(void)
{
encoding_syntax *result; /* Définition vierge à renvoyer*/
result = (encoding_syntax *)calloc(1, sizeof(encoding_syntax));
result->subid = create_instruction_id();
result->assertions = create_disass_assert();
result->conversions = create_conv_list();
result->pattern = create_asm_pattern();
result->rules = create_decoding_rules();
return result;
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à libérer de la mémoire. *
* *
* Description : Supprime de la mémoire le suivi d'une définition de syntaxe. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void delete_encoding_syntax(encoding_syntax *syntax)
{
delete_instruction_id(syntax->subid);
delete_disass_assert(syntax->assertions);
delete_conv_list(syntax->conversions);
delete_asm_pattern(syntax->pattern);
delete_decoding_rules(syntax->rules);
free(syntax);
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à consulter. *
* *
* Description : Fournit le gestionnaire des définitions d'identifiant. *
* *
* Retour : Structure assurant la définition d'identifiant. *
* *
* Remarques : - *
* *
******************************************************************************/
instr_id *get_encoding_syntax_subid(const encoding_syntax *syntax)
{
return syntax->subid;
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à consulter. *
* *
* Description : Fournit la liste de conditions préalables. *
* *
* Retour : Structure assurant la gestion de conditions de désassemblage.*
* *
* Remarques : - *
* *
******************************************************************************/
disass_assert *get_assertions_for_encoding_syntax(const encoding_syntax *syntax)
{
return syntax->assertions;
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à 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_syntax(const encoding_syntax *syntax)
{
return syntax->conversions;
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à consulter. *
* *
* Description : Fournit l'indicateur des écritures correctes d'assembleur. *
* *
* Retour : Structure assurant la gestion des éléments de syntaxe. *
* *
* Remarques : - *
* *
******************************************************************************/
asm_pattern *get_asm_pattern_in_encoding_syntax(const encoding_syntax *syntax)
{
return syntax->pattern;
}
/******************************************************************************
* *
* Paramètres : syntax = définition de syntaxe à 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_syntax(const encoding_syntax *syntax)
{
return syntax->rules;
}
/******************************************************************************
* *
* Paramètres : syntax = gestionnaire d'un ensemble d'éléments de syntaxe. *
* bits = gestionnaire des bits d'encodage. *
* *
* Description : Marque les éléments de syntaxe effectivement utilisés. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool mark_syntax_items(const encoding_syntax *syntax, const coding_bits *bits)
{
bool result; /* Bilan à retourner */
result = mark_disass_assert(syntax->assertions, bits);
if (result)
result = mark_asm_pattern_items(syntax->pattern, bits, syntax->conversions);
if (result)
result = mark_decoding_rules(syntax->rules, bits, syntax->conversions);
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. *
* *
* Description : Déclare les éléments d'une syntaxe isolée. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool declare_encoding_syntax(const encoding_syntax *syntax, int fd, const coding_bits *bits)
{
bool result; /* Bilan à retourner */
bool imm_decl; /* Suivi des déclaration */
imm_decl = false;
result = declare_asm_pattern(syntax->pattern, fd, bits, syntax->conversions, "", &imm_decl);
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. *
* openbar = peut-on se placer en zone principale ? *
* pp = pré-processeur pour les échanges de chaînes. *
* id = identifiant unique attribué à l'instruction. *
* sid = base d'identifiant unique attribué à l'encodage. *
* index = indice de la syntaxe ou NULL si syntaxe unique. *
* exit = exprime le besoin d'une voie de sortie. [OUT] *
* *
* Description : Amorce la construction des éléments d'une syntaxe. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool write_encoding_syntax(const encoding_syntax *syntax, int fd, const char *arch, const coding_bits *bits, bool openbar, const char *id, const char *sid, const size_t *index, bool *exit)
{
bool result; /* Bilan à retourner */
bool conditional; /* Définition sous condition ? */
const char *tab; /* Décalage supplémentaire ? */
bool imm_decl; /* Suivi des déclaration */
conditional = !is_disass_assert_empty(syntax->assertions);
assert((conditional && !openbar) || (!conditional && openbar));
if (conditional)
{
dprintf(fd, "\tif (");
result = define_disass_assert(syntax->assertions, fd, bits);
if (!result) goto wes_exit;
dprintf(fd, ")\n");
dprintf(fd, "\t{\n");
tab = "\t";
}
else
tab = (openbar ? "" : "\t");
if (!openbar)
{
imm_decl = false;
result = declare_asm_pattern(syntax->pattern, fd, bits, syntax->conversions, "\t", &imm_decl);
if (!result) goto wes_exit;
dprintf(fd, "\n");
}
if (!openbar)
{
dprintf(fd, "\t%sassert(result == NULL);\n", tab);
dprintf(fd, "\n");
}
if (index == NULL)
dprintf(fd, "\t%sresult = g_%s_instruction_new(%s, %s);\n", tab, arch, id, sid);
else
dprintf(fd, "\t%sresult = g_%s_instruction_new(%s, %s_%zu);\n", tab, arch, id, sid, *index);
dprintf(fd, "\n");
result = define_asm_pattern(syntax->pattern, fd, arch, bits, syntax->conversions, tab, exit);
if (!result) goto wes_exit;
result = write_decoding_rules(syntax->rules, CAT_CHECKED_CALL, fd, arch, bits, syntax->conversions, tab, exit);
if (!result) goto wes_exit;
result = write_decoding_rules(syntax->rules, CAT_CALL, fd, arch, bits, syntax->conversions, tab, exit);
if (!result) goto wes_exit;
if (conditional)
{
dprintf(fd, "\t}\n");
dprintf(fd, "\n");
}
wes_exit:
return result;
}