/* Chrysalide - Outil d'analyse de fichiers binaires * vmpa.c - adressages virtuels ou physiques * * Copyright (C) 2014-2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "vmpa.h" #include #include #include #include #include #include /* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ /* Transforme une position physique en chaîne de caractères. */ static char *_phys_t_to_string(phys_t, MemoryDataSize, char [VMPA_MAX_LEN], size_t *); /* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ /* Compare une couverture mémoire avec une localisation simple. */ static int _cmp_mrange_with_vmpa(const mrange_t *, const vmpa2t *, bool); /* ---------------------------------------------------------------------------------- */ /* DEFINITION D'UNE POSITION EN MEMOIRE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : addr = élément à initialiser. [OUT] * * phy = position dans la mémoire physique. * * virt = adresse dans la mémoire virtuelle. * * * * Description : Initialise une localisation dans l'espace mémoire/physique. * * * * Retour : Adressage alloué en mémoire. * * * * Remarques : - * * * ******************************************************************************/ void init_vmpa(vmpa2t *addr, phys_t phy, virt_t virt) { addr->physical = phy; addr->virtual = virt; } /****************************************************************************** * * * Paramètres : phy = position dans la mémoire physique. * * virt = adresse dans la mémoire virtuelle. * * * * Description : Crée une localisation dans l'adressage mémoire. * * * * Retour : Adressage alloué en mémoire. * * * * Remarques : - * * * ******************************************************************************/ vmpa2t *make_vmpa(phys_t phy, virt_t virt) { vmpa2t *result; /* Structure à retourner */ result = (vmpa2t *)calloc(1, sizeof(vmpa2t)); init_vmpa(result, phy, virt); return result; } /****************************************************************************** * * * Paramètres : dest = structure de destination pour la copie. * * src = structure de source pour la copie. * * * * Description : Copie la définition d'un adressage dans un autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void copy_vmpa(vmpa2t *dest, const vmpa2t *src) { dest->physical = src->physical; dest->virtual = src->virtual; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare entre elles deux adresses physiques. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1. * * * * Remarques : - * * * ******************************************************************************/ int cmp_vmpa_by_phy(const vmpa2t *a, const vmpa2t *b) { int result; /* Bilan à retourner */ if (a->physical != VMPA_NO_PHYSICAL && b->physical != VMPA_NO_PHYSICAL) { if (a->physical < b->physical) result = -1; else if (a->physical > b->physical) result = 1; else result = 0; } else { if (a->physical == VMPA_NO_PHYSICAL && b->physical == VMPA_NO_PHYSICAL) result = 0; else if (a->physical == VMPA_NO_PHYSICAL) result = -1; else result = 1; } return result; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare entre elles deux adresses virtuelles. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1. * * * * Remarques : - * * * ******************************************************************************/ int cmp_vmpa_by_virt(const vmpa2t *a, const vmpa2t *b) { int result; /* Bilan à retourner */ if (a->virtual != VMPA_NO_VIRTUAL && b->virtual != VMPA_NO_VIRTUAL) { if (a->virtual < b->virtual) result = -1; else if (a->virtual > b->virtual) result = 1; else result = 0; } else { if (a->virtual == VMPA_NO_VIRTUAL && b->virtual == VMPA_NO_VIRTUAL) result = 0; else if (a->virtual == VMPA_NO_VIRTUAL) result = -1; else result = 1; } return result; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare deux localisations selon leurs parties définies. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ int cmp_vmpa(const vmpa2t *a, const vmpa2t *b) { int result; /* Bilan à retourner */ bool half; /* Comparaison débutée */ result = -1; half = false; if (a->physical != VMPA_NO_PHYSICAL && b->physical != VMPA_NO_PHYSICAL) { result = cmp_vmpa_by_phy(a, b); half = true; } if (a->virtual != VMPA_NO_VIRTUAL && b->virtual != VMPA_NO_VIRTUAL && (!half || (half && result == 0))) { result = cmp_vmpa_by_virt(a, b); } return result; } /****************************************************************************** * * * Paramètres : addr = élément à modifier. * * qty = quantité d'unités de décallage. * * * * Description : Décalle une position d'une certaine quantité. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void advance_vmpa(vmpa2t *addr, phys_t qty) { if (addr->physical != VMPA_NO_PHYSICAL) addr->physical += qty; if (addr->virtual != VMPA_NO_VIRTUAL) addr->virtual += qty; } /****************************************************************************** * * * Paramètres : addr = élément à modifier. * * qty = quantité d'unités de décallage. * * * * Description : Décalle une position d'une certaine quantité. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void deminish_vmpa(vmpa2t *addr, phys_t qty) { /* On choisit de ne pas vérifier les débordements */ if (addr->physical != VMPA_NO_PHYSICAL) addr->physical -= qty; if (addr->virtual != VMPA_NO_VIRTUAL) addr->virtual -= qty; } /****************************************************************************** * * * Paramètres : addr = élément à modifier. * * bytes = nombre d'octets sur lequel aligner la position. * * * * Description : Aligne une localisation sur un nombre d'octets donné. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void align_vmpa(vmpa2t *addr, phys_t bytes) { if (bytes > 1) { if (addr->physical != VMPA_NO_PHYSICAL) addr->physical = (addr->physical + bytes - 1) & ~(bytes - 1); if (addr->virtual != VMPA_NO_VIRTUAL) addr->virtual = (addr->virtual + bytes - 1) & ~(bytes - 1); } } /****************************************************************************** * * * Paramètres : a = première élément à venir consulter. * * b = second élément à traiter en parallèle. * * * * Description : Calcule au mieux la distance entre deux coordonnées. * * * * Retour : Distance absolue entre deux localisations. * * * * Remarques : - * * * ******************************************************************************/ phys_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) { phys_t result; /* Valeur à retourner */ result = VMPA_NO_PHYSICAL; if (a->physical != VMPA_NO_PHYSICAL && b->physical != VMPA_NO_PHYSICAL) result = (b->physical > a->physical ? b->physical - a->physical : a->physical - b->physical); else if (a->virtual != VMPA_NO_VIRTUAL && b->virtual != VMPA_NO_VIRTUAL) result = (phys_t)(b->virtual > a->virtual ? b->virtual - a->virtual : a->virtual - b->virtual); return result; } /****************************************************************************** * * * Paramètres : addr = élément à venir lire. [OUT] * * pbuf = paquet de données où venir puiser les infos. * * * * Description : Lit la définition d'une adresse depuis un flux réseau. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool unpack_vmpa(vmpa2t *addr, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ result = extract_packed_buffer(pbuf, (uint64_t *)&addr->physical, sizeof(uint64_t), true); if (result) result = extract_packed_buffer(pbuf, (uint64_t *)&addr->virtual, sizeof(uint64_t), true); return result; } /****************************************************************************** * * * Paramètres : addr = élément à venir écrire. * * pbuf = paquet de données où venir inscrire les infos. * * * * Description : Ecrit la définition d'une adresse dans un flux réseau. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool pack_vmpa(const vmpa2t *addr, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ result = extend_packed_buffer(pbuf, (uint64_t *)&addr->physical, sizeof(uint64_t), true); if (result) result = extend_packed_buffer(pbuf, (uint64_t *)&addr->virtual, sizeof(uint64_t), true); return result; } /****************************************************************************** * * * Paramètres : phys = position physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une position physique en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ static char *_phys_t_to_string(phys_t phys, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) { size_t ret; /* Retour de l'impression */ if (phys == VMPA_NO_PHYSICAL) ret = snprintf(buffer, VMPA_MAX_LEN, _("(none)")); else switch (msize) { case MDS_8_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%02" PRIx64, phys); break; case MDS_16_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%04" PRIx64, phys); break; case MDS_32_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%08" PRIx64, phys); break; case MDS_64_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%016" PRIx64, phys); break; default: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%" PRIx64, phys); break; } if (length != NULL) *length = ret; return buffer; } /****************************************************************************** * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une adresse physique en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *vmpa2_phys_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) { return _phys_t_to_string(addr->physical, msize, buffer, length); } /****************************************************************************** * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une adresse virtuelle en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) { size_t ret; /* Retour de l'impression */ if (addr->virtual == VMPA_NO_VIRTUAL) ret = snprintf(buffer, VMPA_MAX_LEN, _("(none)")); else switch (msize) { case MDS_8_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%02" PRIx64, addr->virtual); break; case MDS_16_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%04" PRIx64, addr->virtual); break; case MDS_32_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%08" PRIx64, addr->virtual); break; case MDS_64_BITS: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%016" PRIx64, addr->virtual); break; default: ret = snprintf(buffer, VMPA_MAX_LEN, "0x%" PRIx64, addr->virtual); break; } if (length != NULL) *length = ret; return buffer; } /****************************************************************************** * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une localisation en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *vmpa2_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) { char *result; /* Résultat à retourner */ if (has_virt_addr(addr)) result = vmpa2_virt_to_string(addr, msize, buffer, length); else result = vmpa2_phys_to_string(addr, msize, buffer, length); return result; } /****************************************************************************** * * * Paramètres : buffer = chaîne de caractères à consulter. * * * * Description : Transforme une chaîne de caractères en position physique. * * * * Retour : Adresse obtenue. * * * * Remarques : - * * * ******************************************************************************/ vmpa2t *string_to_vmpa_phy(const char *buffer) { phys_t physical; /* Position à retrouver */ physical = strtoull(buffer, NULL, 16); return make_vmpa(physical, VMPA_NO_VIRTUAL); } /****************************************************************************** * * * Paramètres : buffer = chaîne de caractères à consulter. * * * * Description : Transforme une chaîne de caractères en adresse virtuelle. * * * * Retour : Adresse obtenue. * * * * Remarques : - * * * ******************************************************************************/ vmpa2t *string_to_vmpa_virt(const char *buffer) { virt_t virtual; /* Adresse à retrouver */ virtual = strtoull(buffer, NULL, 16); return make_vmpa(VMPA_NO_PHYSICAL, virtual); } /****************************************************************************** * * * Paramètres : addr = localisation dont la définition est à consulter. * * base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à compléter. [OUT] * * count = nombre de descriptions renseignées. [OUT] * * * * Description : Décrit les colonnes utiles à un chargement de données. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool setup_load_for_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ (*count) += 2; *values = (bound_value *)realloc(*values, (*count) * sizeof(bound_value)); value = &(*values)[*count - 2]; asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; value->type = SQLITE_NATIVE; value = &(*values)[*count - 1]; asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; value->type = SQLITE_NATIVE; return true; } /****************************************************************************** * * * Paramètres : addr = localisation dont la définition est à définir. * * base = tronc commun pour les champs de la base de données. * * values = tableau d'éléments à consulter. * * count = nombre de descriptions renseignées. * * * * Description : Charge les valeurs utiles pour une localisation. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool load_vmpa(vmpa2t *addr, const char *base, const bound_value *values, size_t count) { char *name; /* Désignation complète */ const bound_value *value; /* Valeur à intégrer */ asprintf(&name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); value = find_bound_value(values, count, name); free(name); if (value == NULL) return false; switch (value->type) { case SQLITE_INT64: addr->physical = value->integer64; break; case SQLITE_NULL: addr->physical = VMPA_NO_PHYSICAL; break; default: return false; break; } asprintf(&name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); value = find_bound_value(values, count, name); free(name); if (value == NULL) return false; switch (value->type) { case SQLITE_INT64: addr->virtual = value->integer64; break; case SQLITE_NULL: addr->virtual = VMPA_NO_VIRTUAL; break; default: return false; break; } return true; } /****************************************************************************** * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * base = tronc commun pour les champs de la base de données. * * values = couples de champs et de valeurs à lier. [OUT] * * count = nombre de ces couples. [OUT] * * * * Description : Constitue les champs destinés à une insertion / modification.* * * * Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ bool prepare_vmpa_db_statement(const vmpa2t *addr, const char *base, bound_value **values, size_t *count) { bound_value *value; /* Valeur à éditer / définir */ *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; asprintf(&value->name, "%s%sphys", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; if (addr->physical != VMPA_NO_PHYSICAL) { value->type = SQLITE_INT64; value->integer64 = addr->physical; } else { value->type = SQLITE_NULL; } *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; asprintf(&value->name, "%s%svirt", base != NULL ? base : "", base != NULL ? "_" : ""); value->built_name = true; if (addr->virtual != VMPA_NO_VIRTUAL) { value->type = SQLITE_INT64; value->integer64 = addr->virtual; } else { value->type = SQLITE_NULL; } return true; } /* ---------------------------------------------------------------------------------- */ /* AIDES FONCTIONNELLES AUXILIAIRES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : label = désignation humaine d'unn symbole de base. * * offset = décalage déterminé à faie apparaître au besoin. * * * * Description : Construit une désignation de symbole avec décalage. * * * * Retour : Chaîne de caractères constituée à libérer après usage. * * * * Remarques : - * * * ******************************************************************************/ char *make_symbol_offset(const char *label, phys_t offset) { char *result; /* Construction à retourner */ size_t length; /* Taille de désignation créée */ if (offset == 0) result = strdup(label); else { length = strlen(label) + 1 + VMPA_MAX_LEN + 1; result = (char *)calloc(length, sizeof(char)); snprintf(result, length, "%s+0x%llx", label, (unsigned long long)offset); } return result; } /* ---------------------------------------------------------------------------------- */ /* DEFINITION D'UNE ZONE EN MEMOIRE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : range = plage à initialiser. [OUT] * * addr = position de départ dans la mémoire. * * length = taille de la plage à constituer. * * * * Description : Initialise une plage dans l'espace mémoire/physique. * * * * Retour : Place définie en mémoire. * * * * Remarques : - * * * ******************************************************************************/ void init_mrange(mrange_t *range, const vmpa2t *addr, phys_t length) { copy_vmpa(&range->addr, addr); range->length = length; } /****************************************************************************** * * * Paramètres : dest = structure de destination pour la copie. * * src = structure de source pour la copie. * * * * Description : Copie la définition d'une plage mémoire dans une autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void copy_mrange(mrange_t *dest, const mrange_t *src) { copy_vmpa(&dest->addr, &src->addr); dest->length = src->length; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare deux couvertures mémoire selon leurs propriétés. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ int cmp_mrange(const mrange_t *a, const mrange_t *b) { int result; /* Bilan à retourner */ result = cmp_vmpa(&a->addr, &b->addr); if (result == 0) { if (a->length < b->length) result = -1; else if (a->length > b->length) result = 1; else result = 0; } return result; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * inc = indique si l'adresse peut être une fin de zone. * * * * Description : Compare une couverture mémoire avec une localisation simple. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ static int _cmp_mrange_with_vmpa(const mrange_t *a, const vmpa2t *b, bool inclusive) { int result; /* Bilan à retourner */ phys_t diff; /* Espace entre deux adresses */ result = cmp_vmpa(b, &a->addr); if (result >= 0) { diff = compute_vmpa_diff(&a->addr, b); /** * On prend en compte le cas très particulier des couvertures vides. * * C'est typiquement le cas avec les espaces de symboles pendant la * phase de désassemblage, après laquelle ces espaces deviennent bornés. * */ if (diff == 0 && a->length == 0) result = 0; /** * Sinon on regarde simplement si l'adresse est contenue. */ else if (diff < a->length) result = 0; else if (diff == a->length && inclusive) result = 0; else result = 1; } return result; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare une couverture mémoire avec une localisation simple. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ int cmp_mrange_with_vmpa(const mrange_t *a, const vmpa2t *b) { int result; /* Bilan à retourner */ result = _cmp_mrange_with_vmpa(a, b, false); return result; } /****************************************************************************** * * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * * Description : Compare une couverture mémoire avec une localisation simple. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ int cmp_mrange_with_vmpa_inclusive(const mrange_t *a, const vmpa2t *b) { int result; /* Bilan à retourner */ result = _cmp_mrange_with_vmpa(a, b, true); return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * sub = éventuelle sous-région à valider. * * * * Description : Indique si une zone en contient une autre ou non. * * * * Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * * * * Remarques : - * * * ******************************************************************************/ int mrange_includes_mrange(const mrange_t *range, const mrange_t *sub) { int result; /* Bilan à retourner */ vmpa2t end; /* Seconde extrémité */ result = cmp_mrange_with_vmpa(range, get_mrange_addr(sub)); if (result == 0) { compute_mrange_end_addr(sub, &end); result = cmp_mrange_with_vmpa_inclusive(range, &end); } return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * sub = éventuelle sous-région à valider. * * * * Description : Indique si une zone en contient une autre ou non. * * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool mrange_contains_mrange(const mrange_t *range, const mrange_t *sub) { bool result; /* Bilan à retourner */ phys_t start; /* Point de départ */ result = mrange_contains_addr(range, get_mrange_addr(sub)); if (result) { start = compute_vmpa_diff(get_mrange_addr(range), get_mrange_addr(sub)); result = (start + get_mrange_length(sub) <= get_mrange_length(range)); } return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * addr = localisation mémoire à analyser. * * * * Description : Indique si une localisation est incluse dans une zone ou non.* * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) { bool result; /* Bilan à retourner */ int ret; /* Bilan d'une comparaison */ phys_t diff; /* Espace entre deux adresses */ ret = cmp_vmpa(&range->addr, addr); if (ret < 0) { diff = compute_vmpa_diff(&range->addr, addr); if (diff != VMPA_NO_PHYSICAL) result = (diff < range->length); else result = false; } else if (ret == 0) result = true; else result = false; return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * addr = localisation mémoire à analyser. * * * * Description : Indique si une localisation est incluse dans une zone ou non.* * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool mrange_contains_addr_inclusive(const mrange_t *range, const vmpa2t *addr) { bool result; /* Bilan à retourner */ int ret; /* Bilan d'une comparaison */ phys_t diff; /* Espace entre deux adresses */ ret = cmp_vmpa(&range->addr, addr); if (ret <= -1) { diff = compute_vmpa_diff(&range->addr, addr); if (diff != VMPA_NO_PHYSICAL) result = (diff <= range->length); else result = false; } else if (ret == 0) result = true; else result = false; return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * other = autre zone mémoire à manipuler. * * * * Description : Détermine si deux zones mémoire se chevauchent ou non. * * * * Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ bool mrange_intersects_mrange(const mrange_t *range, const mrange_t *other) { bool result; /* Bilan à retourner */ vmpa2t end; /* Fin d'une zone mémoire */ result = false; result |= mrange_contains_addr(range, &other->addr); result |= mrange_contains_addr(other, &range->addr); if (get_mrange_length(other) > 0) { compute_mrange_end_addr(other, &end); deminish_vmpa(&end, 1); result |= mrange_contains_addr(range, &end); } if (get_mrange_length(range) > 0) { compute_mrange_end_addr(range, &end); deminish_vmpa(&end, 1); result |= mrange_contains_addr(other, &end); } return result; } /****************************************************************************** * * * Paramètres : range = zone mémoire à consulter. * * addr = localisation mémoire à déterminer. * * * * Description : Calcule la position extérieure finale d'une couverture. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void compute_mrange_end_addr(const mrange_t *range, vmpa2t *addr) { copy_vmpa(addr, &range->addr); advance_vmpa(addr, range->length); } /****************************************************************************** * * * Paramètres : rane = emplacement virtuel ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * start = indique si le début ou la fin est à imprimer. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme un emplacement physique en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *mrange_phys_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) { vmpa2t tmp; if (start) vmpa2_phys_to_string(&range->addr, msize, buffer, length); else { copy_vmpa(&tmp, &range->addr); advance_vmpa(&tmp, range->length); vmpa2_phys_to_string(&tmp, msize, buffer, length); } return buffer; } /****************************************************************************** * * * Paramètres : rane = emplacement virtuel ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * start = indique si le début ou la fin est à imprimer. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme un emplacement virtuel en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *mrange_virt_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) { vmpa2t tmp; if (start) vmpa2_virt_to_string(&range->addr, msize, buffer, length); else { copy_vmpa(&tmp, &range->addr); advance_vmpa(&tmp, range->length); vmpa2_virt_to_string(&tmp, msize, buffer, length); } return buffer; } /****************************************************************************** * * * Paramètres : rane = emplacement virtuel ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * * buffer = tampon de sortie utilisé à constituer. [OUT] * * length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une taille d'emplacement en chaîne de caractères. * * * * Retour : Chaîne de caractères constituée. * * * * Remarques : - * * * ******************************************************************************/ char *mrange_length_to_string(const mrange_t *range, MemoryDataSize msize, char buffer[VMPA_MAX_LEN], size_t *length) { return _phys_t_to_string(range->length, msize, buffer, length); }