diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-01-30 20:53:24 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-01-30 20:53:24 (GMT) |
commit | 4132223466dcabc19a1b6f0178adf1c1a35b07ad (patch) | |
tree | ad5ef2262e8e1855c9c7f23a0f11f560039d54c6 /src/mangling/itanium/context.c | |
parent | 896b31fbbef2fba442566a422fa4d409771b61dd (diff) |
Moved the mangling related code.
Diffstat (limited to 'src/mangling/itanium/context.c')
-rw-r--r-- | src/mangling/itanium/context.c | 571 |
1 files changed, 571 insertions, 0 deletions
diff --git a/src/mangling/itanium/context.c b/src/mangling/itanium/context.c new file mode 100644 index 0000000..d0a0664 --- /dev/null +++ b/src/mangling/itanium/context.c @@ -0,0 +1,571 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * context.c - contexte de décodage à la sauce ABI C++ Itanium + * + * Copyright (C) 2013-2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "context.h" + + +#include <malloc.h> +#include <string.h> + + +#include "abi.h" +#include "component-int.h" +#include "../context-int.h" + + + +/* Taille des extensions d'allocation */ +#define ITCOMP_ALLOC_BULK 200 + +/* Marqueur de fin pour les disponibilités */ +#define ITCOMP_INVALID ((size_t)-1) + + +/* Contexte de décodage Itanium (instance) */ +struct _GItaniumDContext +{ + GDemanglingContext parent; /* A laisser en premier */ + + char *mangled; /* Caractères à traiter */ + size_t len; /* Quantité de caractères */ + size_t pos; /* Position d'analyse */ + + itanium_component *components; /* Tableaux des composants */ + size_t *next_links; /* Chemins d'allocation */ + size_t length; /* Taille allouée */ + size_t last_used; /* Lien vers la disponibilité */ + + itanium_component **substitutions; /* Table de substitutions */ + size_t subst_count; /* Quantité utilisée */ + +}; + +/* Contexte de décodage Itanium (classe) */ +struct _GItaniumDContextClass +{ + GDemanglingContextClass parent; /* A laisser en premier */ + +}; + + + +/* Indique le type défini pour un contexte de décodage. */ +G_DEFINE_TYPE(GItaniumDContext, g_itanium_dcontext, G_TYPE_DEMANGLING_CONTEXT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des contextes de décodage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_itanium_dcontext_class_init(GItaniumDContextClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : context = instance à initialiser. * +* * +* Description : Initialise une instance de contexte pour décodage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_itanium_dcontext_init(GItaniumDContext *context) +{ + context->last_used = ITCOMP_INVALID; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Prépare de quoi effectuer un décodage Itanium. * +* * +* Retour : Instance du contexte mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDemanglingContext *g_itanium_dcontext_new(void) +{ + GDemanglingContext *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ITANIUM_DCONTEXT, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage sur lequel s'appuyer. * +* desc = chaîne de caractères à décoder. * +* * +* Description : Tente de décoder une chaîne de caractères donnée. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void /*GBinRoutine **/g_itanium_dcontext_demangle_routine(GItaniumDContext *context, const char *desc) +{ + itanium_component *comp; + + char *str; + + printf("<<== %s\n", desc); + + context->mangled = strdup(desc); + context->len = strlen(desc); + context->pos = 0; + + + /** + * On part du principe qu'il n'y aura jamais plus de substitutions + * à enregistrer que de caractères dans la chaîne à traiter. + * Du coup, on peut tout allouer d'un coup ! + */ + context->substitutions = (itanium_component **)calloc(context->len, sizeof(itanium_component *)); + + + comp = itd_mangled_name(context); + + + printf("Got :: %p\n", comp); + + str = itd_translate_component(context, comp, NULL); + + printf("==>> %s\n", str); + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* state = état courant à sauvegarder. [OUT] * +* * +* Description : Fournit l'état courant à une fin de retour en arrière. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_itanium_dcontext_push_state(const GItaniumDContext *context, itd_state *state) +{ + state->pos = context->pos; + state->subst_count = context->subst_count; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* state = état courant à restaurer. * +* * +* Description : Définit l'état courant suite à un retour en arrière. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_itanium_dcontext_pop_state(GItaniumDContext *context, const itd_state *state) +{ + size_t i; /* Boucle de parcours */ + + /* + printf("--deleting subst-- from %zu to %zu\n", + state->subst_count, context->subst_count); + */ + + for (i = state->subst_count; i < context->subst_count; i++) + itd_unref_comp(context->substitutions[i]); + + context->pos = state->pos; + context->subst_count = state->subst_count; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à utiliser. * +* * +* Description : Fournit la valeur du caractère courant. * +* * +* Retour : Caractère courant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char g_itanium_dcontext_peek_char(const GItaniumDContext *context) +{ + return *(context->mangled + context->pos); + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à utiliser. * +* quantity = quantié de caractères à marquer comme traités. * +* * +* Description : Avance la tête de lecture courante. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_itanium_dcontext_advance(GItaniumDContext *context, size_t quantity) +{ + context->pos += quantity; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à utiliser. * +* * +* Description : Fournit et avance la tête de lecture courante. * +* * +* Retour : Caractère courant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char g_itanium_dcontext_next_char(GItaniumDContext *context) +{ + return *(context->mangled + context->pos++); + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à utiliser. * +* c = caractère à retrouver. * +* * +* Description : Vérifie la nature du caractère courant. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_itanium_dcontext_check_char(GItaniumDContext *context, char c) +{ + bool result; /* Validation à retourner */ + + if (g_itanium_dcontext_peek_char(context) == c) + { + result = true; + g_itanium_dcontext_advance(context, 1); + } + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à utiliser. * +* remaining = taille de la chaîne retournée. [OUT] * +* * +* Description : Fournit la chaîne de caractère restant à traiter. * +* * +* Retour : Pointeur vers les données courantes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_itanium_dcontext_get_string(const GItaniumDContext *context, size_t *remaining) +{ + const char *result; /* Données à renvoyer */ + + *remaining = context->len - context->pos; + + result = &context->mangled[context->pos]; + + return result; + +} + + + + + +/* + +################define d_peek_char(di) (*((di)->n)) +#define d_peek_next_char(di) ((di)->n[1]) +################define d_advance(di, i) ((di)->n += (i)) +################define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) +#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) +################define d_str(di) ((di)->n) + + +*/ + + + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* * +* Description : Fournit un nouveau composant vierge. * +* * +* Retour : Composant prêt à être défini. * +* * +* Remarques : - * +* * +******************************************************************************/ + +itanium_component *g_itanium_dcontext_get_empty_component(GItaniumDContext *context) +{ + itanium_component *result; /* Disponibilité à retourner */ + size_t i; /* Boucle de parcours */ + size_t next; /* Indice de disponibilité */ + + if (context->last_used == ITCOMP_INVALID + || context->next_links[context->last_used] == ITCOMP_INVALID) + { + /* Création d'extensions */ + + context->components = (itanium_component *) + realloc(context->components, + (context->length + ITCOMP_ALLOC_BULK) * sizeof(itanium_component)); + + context->next_links = (size_t *) + realloc(context->next_links, (context->length + ITCOMP_ALLOC_BULK) * sizeof(size_t)); + + /* Inscription des liens d'allocation */ + + for (i = context->length; i < (context->length + ITCOMP_ALLOC_BULK - 1); i++) + context->next_links[i] = i + 1; + + context->next_links[context->length + ITCOMP_ALLOC_BULK - 1] = ITCOMP_INVALID; + + if (context->last_used != ITCOMP_INVALID) + context->next_links[context->last_used] = context->length; + + /* Mise à jour globale */ + + context->length += ITCOMP_ALLOC_BULK; + + } + + /* Extraction d'un composant disponible */ + + if (context->last_used == ITCOMP_INVALID) + next = 0; + else + next = context->next_links[context->last_used]; + + result = &context->components[next]; + context->last_used = next; + + memset(result, 0, sizeof(itanium_component)); + + result->context = context; + g_object_ref(G_OBJECT(result->context)); + result->refcount = 1; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* comp = composant à libérer. * +* * +* Description : Marque un composant comme étant disponible pour un usage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_itanium_dcontext_mark_component_as_free(GItaniumDContext *context, itanium_component *comp) +{ + size_t index; /* Indice du composant concerné*/ + + /*BUG_ON(comp->refcount != 0);*/ + + g_object_unref(G_OBJECT(comp->context)); + + index = comp - context->components; + + context->next_links[index] = context->next_links[context->last_used]; + context->next_links[context->last_used] = index; + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* comp = composant à conserver en mémoire. * +* * +* Description : Indexe un composant comme future substitution potentielle. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_itanium_dcontext_add_substitution(GItaniumDContext *context, itanium_component *comp) +{ + fnv64_t hash; /* Empreinte du candidat */ + size_t i; /* Boucle de parcours */ + + hash = itd_hash_comp(comp); + + for (i = 0; i < context->subst_count; i++) + if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash) == 0) + break; + + if (i == context->subst_count) + { + + printf("[ADDING SUBST] [%zu] '%s'\n", + context->subst_count, + itd_translate_component(context, comp, NULL)); + + + context->substitutions[context->subst_count++] = comp; + itd_ref_comp(comp); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : context = contexte de décodage à manipuler. * +* index = indice de la substitution visée. * +* * +* Description : Fournit un composant en place pour une substitution. * +* * +* Retour : Composant déjà extrait et conservé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +itanium_component *g_itanium_dcontext_get_substitution(GItaniumDContext *context, size_t index) +{ + itanium_component *result; /* Composant à retourner */ + + if (index < context->subst_count) + { + result = context->substitutions[index]; + itd_ref_comp(result); + } + else + result = NULL; + + return result; + +} + + + + + + + + + + + + + + + +void test_itanium(void) +{ + + + + +#define TEST_DEMANG(v) \ + do \ + { \ + GDemanglingContext *ctx; \ + /*char *str;*/ \ + ctx = g_itanium_dcontext_new(); \ + /*str = */g_itanium_dcontext_demangle_routine(G_ITANIUM_DCONTEXT(ctx), v); \ + /*printf("==> %s\n", str);*/ \ + } \ + while (0) + + + TEST_DEMANG("_Z3fooILi2EEvRAplT_Li1E_i"); + + exit(0); + + TEST_DEMANG("_Z1fv"); + TEST_DEMANG("_Z3foo3bar"); + + +} |