diff options
Diffstat (limited to 'tools/d2c/coder.c')
-rw-r--r-- | tools/d2c/coder.c | 248 |
1 files changed, 232 insertions, 16 deletions
diff --git a/tools/d2c/coder.c b/tools/d2c/coder.c index 83910aa..869461f 100644 --- a/tools/d2c/coder.c +++ b/tools/d2c/coder.c @@ -47,14 +47,18 @@ struct _rented_coder { const char *input; /* Fichier de définitions */ + InputOutputType type; /* Type des définitions (E/S) */ const char *outdir; /* Lieu d'enregistrement */ const char *arch; /* Architecture à traiter */ const char *header; /* En-tête pour les en-têtes */ + const char *const_prefix; /* Préfixe pour les opérandes */ pre_processor *pp; /* Pré-processeur avec macros */ char *copyright; /* Récupération des droits */ char *ins; /* Désignation humaine */ + char separator; /* Caractère de séparation */ + char *raw_details; /* Eventuels compléments bruts */ char *details; /* Eventuels compléments */ encoding_spec **specs; /* Définitions déjà en place */ @@ -89,6 +93,9 @@ static int create_code_file(const rented_coder *, const char *, const char *, co /* 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); +/* Ecrit une partie des fonctions issues des spécifications. */ +static bool dump_all_matching_specs_from_format(const rented_coder *, const string_exch *, int, int); + /* ---------------------------------------------------------------------------------- */ @@ -144,8 +151,11 @@ void delete_coder(rented_coder *coder) if (coder->ins != NULL) free(coder->ins); - if (coder->details != NULL) + if (coder->raw_details != NULL) + { + free(coder->raw_details); free(coder->details); + } for (i = 0; i < coder->specs_count; i++) delete_encoding_spec(coder->specs[i]); @@ -174,7 +184,15 @@ void delete_coder(rented_coder *coder) bool do_basic_checks_with_coder(const rented_coder *coder) { - return (coder->outdir != NULL && coder->arch != NULL && coder->header != NULL); + bool result; /* Validité à retourner */ + + result = coder->type != IOT_UNDEFINED && coder->outdir != NULL; + result &= coder->arch != NULL && coder->header != NULL; + + if (coder->type == IOT_FORMAT) + result &= (coder->const_prefix != NULL); + + return result; } @@ -220,6 +238,26 @@ void set_coder_input_file(rented_coder *coder, const char *input) /****************************************************************************** * * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* type = type de définition à attendre. * +* * +* Description : Spécifie le type de format à prendre en compte (E/S). * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_coder_input_type(rented_coder *coder, InputOutputType type) +{ + coder->type = type; + +} + + +/****************************************************************************** +* * * Paramètres : coder = gestion par la machine en remplacement de l'humain. * * outdir = répertoire de génération des fichiers. * * * @@ -280,6 +318,26 @@ void set_coder_header_base(rented_coder *coder, const char *header) /****************************************************************************** * * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* prefix = préfixe pour les types d'opérandes. * +* * +* Description : Définit le préfixe pour les opérandes chargées par format. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_coder_const_prefix(rented_coder *coder, const char *prefix) +{ + coder->const_prefix = prefix; + +} + + +/****************************************************************************** +* * * Paramètres : coder = gestion par la machine en remplacement de l'humain. * * * * Description : Fournit le pré-processeur du compilateur. * @@ -302,6 +360,7 @@ pre_processor *get_coder_pre_proc(const rented_coder *coder) * 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. * +* sep = caractère de séparation avant les détails. * * details = compléments d'informations éventuels ou NULL. * * * * Description : Enregistre les contours d'une instruction d'assemblage. * @@ -312,11 +371,23 @@ pre_processor *get_coder_pre_proc(const rented_coder *coder) * * ******************************************************************************/ -void save_notes_for_coder(rented_coder *coder, char *copy, char *ins, const char *details) +void save_notes_for_coder(rented_coder *coder, char *copy, char *ins, char sep, const char *details) { coder->copyright = copy; coder->ins = make_string_lower(ins); - coder->details = (details != NULL ? make_callable(details, true) : strdup("")); + + coder->separator = sep; + + if (details != NULL) + { + coder->raw_details = strdup(details); + coder->details = make_callable(details, true); + } + else + { + coder->raw_details = strdup(""); + coder->details = strdup(""); + } } @@ -366,7 +437,8 @@ void push_encoding_spec(rented_coder *coder, char *prefix, unsigned int index) spec = coder->cur_spec; - define_encoding_spec_code_name(spec, prefix, index); + if (prefix != NULL) + 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; @@ -494,9 +566,18 @@ static char *build_template_filename(const rented_coder *coder, const char *pref char *result; /* Chaîne construite à renvoyer*/ size_t length; /* Taille du nom de fichier */ - length = strlen(".gen") + 1 + strlen("template") + 1 + strlen(prefix) + 1 + strlen(name) + 3; - result = (char *)calloc(length, sizeof(char)); - snprintf(result, length, ".gen/%s.%s.tmpl.%c", prefix, name, ext); + if (prefix == NULL) + { + length = strlen(".gen") + 1 + strlen("template") + 1 + strlen(name) + 3; + result = (char *)calloc(length, sizeof(char)); + snprintf(result, length, ".gen/%s.tmpl.%c", name, ext); + } + else + { + length = strlen(".gen") + 1 + strlen("template") + 1 + strlen(prefix) + 1 + strlen(name) + 3; + result = (char *)calloc(length, sizeof(char)); + snprintf(result, length, ".gen/%s.%s.tmpl.%c", prefix, name, ext); + } return result; @@ -523,6 +604,7 @@ static bool create_template_file(const rented_coder *coder, const char *prefix, char *pathname; /* Chemin d'accès à constituer */ bool exist; /* Note une présence établie */ int fd; /* Flux ouvert pour création */ + const char *valid_prefix; /* Prefix vide au besoin */ char *uprefix; /* Préfixe en majuscule */ char *uname; /* Nom en majuscule */ @@ -545,11 +627,13 @@ static bool create_template_file(const rented_coder *coder, const char *prefix, if (fd != -1) { - write_owner_comments(coder, fd, prefix, name, ext); + valid_prefix = prefix != NULL ? prefix : ""; + + write_owner_comments(coder, fd, valid_prefix, name, ext); if (ext == 'h') { - uprefix = make_string_upper(strdup(prefix)); + uprefix = make_string_upper(strdup(valid_prefix)); uname = make_string_upper(strdup(name)); dprintf(fd, "#ifndef %s_%s%s_H\n", coder->header, uprefix, uname); @@ -568,7 +652,7 @@ static bool create_template_file(const rented_coder *coder, const char *prefix, } else { - dprintf(fd, "#include \"%sopcodes.h\"\n", prefix); + dprintf(fd, "#include \"%sopcodes.h\"\n", valid_prefix); dprintf(fd, "\n"); dprintf(fd, "##INCLUDES##\n"); @@ -611,9 +695,18 @@ static char *build_code_filename(const rented_coder *coder, const char *input, c point = strstr(orig, "."); if (point != NULL) *point = '\0'; - length = strlen(".gen") + 1 + strlen(orig) + 1 + strlen(prefix) + 1 + strlen(name) + 3; - result = (char *)calloc(length, sizeof(char)); - snprintf(result, length, ".gen/%s.%s.%s.%c", orig, prefix, name, ext); + if (prefix == NULL) + { + length = strlen(".gen") + 1 + strlen(orig) + 1 + strlen(name) + 3; + result = (char *)calloc(length, sizeof(char)); + snprintf(result, length, ".gen/%s.%s.%c", orig, name, ext); + } + else + { + length = strlen(".gen") + 1 + strlen(orig) + 1 + strlen(prefix) + 1 + strlen(name) + 3; + result = (char *)calloc(length, sizeof(char)); + snprintf(result, length, ".gen/%s.%s.%s.%c", orig, prefix, name, ext); + } free(orig); @@ -807,7 +900,22 @@ bool dump_all_routines_using_coder(const rented_coder *coder) /* Production de code... */ - result = dump_all_matching_specs_in_coder(coder, encoding, header_fd, code_fd); + switch (coder->type) + { + case IOT_UNDEFINED: + assert(false); + result = false; + break; + + case IOT_RAW: + result = dump_all_matching_specs_in_coder(coder, encoding, header_fd, code_fd); + break; + + case IOT_FORMAT: + result = dump_all_matching_specs_from_format(coder, encoding, header_fd, code_fd); + break; + + } close(header_fd); close(code_fd); @@ -899,7 +1007,7 @@ static bool dump_all_matching_specs_in_coder(const rented_coder *coder, const st dprintf(cfd, "*\n"); dprintf(cfd, " *\n"); - dprintf(cfd, "* Retour : Bilan de l'opération. *\n"); + dprintf(cfd, "* Retour : Instruction mise en place ou NULL en cas d'échec. *\n"); dprintf(cfd, "* *\n"); dprintf(cfd, "* Remarques : - *\n"); dprintf(cfd, "* *\n"); @@ -942,3 +1050,111 @@ static bool dump_all_matching_specs_in_coder(const rented_coder *coder, const st 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_from_format(const rented_coder *coder, const string_exch *encoding, int hfd, int cfd) +{ + bool result; /* Bilan à retourner */ + char *keyword; /* Mot clef appelable en code */ + size_t maxlen; /* Taille à compléter */ + encoding_spec *spec; /* Définition à traiter */ + + keyword = make_callable(coder->ins, false); + + /* Désassemblage : déclaration */ + + dprintf(hfd, "/* Décode une instruction de type '%s'. */\n", coder->ins); + + if (encoding->dest == NULL) + dprintf(hfd, "GArchInstruction *%s_read_instr_%s%s", + coder->arch, keyword, coder->details); + else + dprintf(hfd, "GArchInstruction *%s_read_%sinstr_%s%s", + coder->arch, encoding->dest, keyword, coder->details); + + dprintf(hfd, "("); + dprintf(hfd, "const GArchProcessor *, GProcContext *, const GBinContent *, "); + dprintf(hfd, "vmpa2t *, GExeFormat *"); + dprintf(hfd, ");\n"); + + dprintf(hfd, "\n"); + + /* Désassemblage : définitions */ + + dprintf(cfd, "\n"); + + dprintf(cfd, "/******************************************************************************\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "* Paramètres : proc = processeur de l'architecture d'exécution. *\n"); + dprintf(cfd, "* ctx = contexte associé à la phase de désassemblage. *\n"); + dprintf(cfd, "* content = flux de données à analyser. *\n"); + dprintf(cfd, "* pos = position courante dans ce flux. [OUT] *\n"); + dprintf(cfd, "* format = format du fichier contenant le code. *\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 : Instruction mise en place ou NULL en cas d'échec. *\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "* Remarques : - *\n"); + dprintf(cfd, "* *\n"); + dprintf(cfd, "******************************************************************************/\n"); + + dprintf(cfd, "\n"); + + if (encoding->dest == NULL) + dprintf(cfd, "GArchInstruction *%s_read_instr_%s%s", + coder->arch, keyword, coder->details); + else + dprintf(cfd, "GArchInstruction *%s_read_%sinstr_%s%s", + coder->arch, encoding->dest, keyword, coder->details); + + dprintf(cfd, "("); + dprintf(cfd, "const GArchProcessor *proc, GProcContext *ctx, const GBinContent *content, "); + dprintf(cfd, "vmpa2t *pos, GExeFormat *format"); + dprintf(cfd, ")"); + + dprintf(cfd, "\n"); + dprintf(cfd, "{"); + dprintf(cfd, "\n"); + + assert(coder->specs_count == 1); + + spec = coder->specs[0]; + + assert(has_encoding_spec_prefix(spec, encoding->src)); + + result = write_encoding_spec_format_disass(spec, cfd, coder->arch, encoding->dest, + coder->ins, coder->separator, coder->raw_details, + coder->pp, coder->const_prefix); + + dprintf(cfd, "}\n"); + dprintf(cfd, "\n"); + + free(keyword); + + return result; + +} |