diff options
Diffstat (limited to 'src/glibext/portion.c')
-rw-r--r-- | src/glibext/portion.c | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/src/glibext/portion.c b/src/glibext/portion.c new file mode 100644 index 0000000..096a39d --- /dev/null +++ b/src/glibext/portion.c @@ -0,0 +1,974 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * portion.c - représentation graphique de portions de binaire + * + * Copyright (C) 2013-2024 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 <http://www.gnu.org/licenses/>. + */ + + +#include "portion.h" + + +#include <assert.h> +#include <malloc.h> +//#include <stdio.h> +//#include <stdlib.h> +#include <string.h> + + +#include <i18n.h> + + +#include "portion-int.h" +//#include "../analysis/human/asm/lang.h" +#include "../common/extstr.h" +#include "../common/sort.h" +//#include "../core/columns.h" +//#include "../glibext/gbinarycursor.h" +//#include "../glibext/linegen-int.h" + + + +/* ------------------------------- PORTION DE BINAIRE ------------------------------- */ + + +/* Initialise la classe des portions de données binaires. */ +static void g_binary_portion_class_init(GBinaryPortionClass *); + +/* Initialise une instance de portion de données binaires. */ +static void g_binary_portion_init(GBinaryPortion *); + +/* Supprime toutes les références externes. */ +static void g_binary_portion_dispose(GBinaryPortion *); + +/* Procède à la libération totale de la mémoire. */ +static void g_binary_portion_finalize(GBinaryPortion *); + + + +/* ------------------------ PARCOURS D'ENSEMBLES DE PORTIONS ------------------------ */ + + +/* Détermine si une portion contient une adresse donnée. */ +static bool g_binary_portion_contains_vmpa(const GBinaryPortion *, const vmpa2t *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PORTION DE BINAIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les portions de données binaires. */ +G_DEFINE_TYPE(GBinaryPortion, g_binary_portion, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des portions de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_class_init(GBinaryPortionClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_binary_portion_dispose; + object->finalize = (GObjectFinalizeFunc)g_binary_portion_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance à initialiser. * +* * +* Description : Initialise une instance de portion de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_init(GBinaryPortion *portion) +{ + vmpa2t dummy; /* Coquille presque vide */ + + portion->desc = NULL; + + init_vmpa(&dummy, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); + init_mrange(&portion->range, &dummy, VMPA_NO_VIRTUAL); + + portion->continued = false; + + portion->rights = PAC_NONE; + + portion->subs = NULL; + portion->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_dispose(GBinaryPortion *portion) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < portion->count; i++) + g_clear_object(&portion->subs[i]); + + G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion)); + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_portion_finalize(GBinaryPortion *portion) +{ + if (portion->desc != NULL) + free(portion->desc); + + if (portion->subs != NULL) + free(portion->subs); + + G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion)); + +} + + +/****************************************************************************** +* * +* Paramètres : addr = emplacement de la section à conserver. * +* size = taille de la section à conserver. * +* * +* Description : Crée une description de partie de code vierge. * +* * +* Retour : Instance mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryPortion *g_binary_portion_new(const vmpa2t *addr, phys_t size) +{ + GBinaryPortion *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_BINARY_PORTION, NULL); + + if (!g_binary_portion_create(result, addr, size)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = instance à initialiser pleinement. * +* addr = emplacement de la section à conserver. * +* size = taille de la section à conserver. * +* * +* Description : Met en place une description de partie de code vierge. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_create(GBinaryPortion *portion, const vmpa2t *addr, phys_t size) +{ + bool result; /* Bilan à retourner */ + + result = true; + + init_mrange(&portion->range, addr, size); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premières informations à consulter. * +* b = secondes informations à consulter. * +* * +* Description : Etablit la comparaison ascendante entre deux portions. * +* * +* Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_binary_portion_compare(const GBinaryPortion **a, const GBinaryPortion **b) +{ + int result; /* Bilan à retourner */ + const vmpa2t *addr_a; /* Adresse de la portion 'a' */ + const vmpa2t *addr_b; /* Adresse de la portion 'b' */ + + addr_a = get_mrange_addr(&(*a)->range); + addr_b = get_mrange_addr(&(*b)->range); + + result = cmp_vmpa(addr_a, addr_b); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* desc = nom à donner à la partie. * +* * +* Description : Attribue une description humaine à une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_set_desc(GBinaryPortion *portion, const char *desc) +{ + if (portion->desc != NULL) + free(portion->desc); + + if (desc == NULL) + portion->desc = NULL; + + else + { + portion->desc = strdup(desc); + + if (portion->continued) + portion->desc = stradd(portion->desc, _(" (continued)")); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à consulter. * +* * +* Description : Fournit la description attribuée à une partie de code. * +* * +* Retour : Nom donné à la partie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_portion_get_desc(const GBinaryPortion *portion) +{ + return portion->desc; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* * +* Description : Fournit l'emplacement d'une partie de code binaire. * +* * +* Retour : Espace de couverture associé à la portion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const mrange_t *g_binary_portion_get_range(const GBinaryPortion *portion) +{ + return &portion->range; + +} + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* max = taille maximale accordée à la portion. * +* * +* Description : Assure qu'une portion ne dépasse pas une position donnée. * +* * +* Retour : true si la portion a été modifiée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_limit_range(GBinaryPortion *portion, phys_t max) +{ + bool result; /* Bilan à retourner */ + phys_t current; /* Taille courante */ + + current = get_mrange_length(&portion->range); + + result = (current > max); + + if (result) + set_mrange_length(&portion->range, max); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion dont la définition est à metre à jour. * +* * +* Description : Définit la nature de la portion en terme d'originalité. * +* * +* Retour : - * +* * +* Remarques : L'action ne modifie aucunement la description courante. * +* C'est le changement de description qui s'appuie sur la * +* notée ici. * +* * +******************************************************************************/ + +void g_binary_portion_mark_as_continued(GBinaryPortion *portion, bool continued) +{ + portion->continued = continued; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion dont la définition est à consulter. * +* * +* Description : Indique la nature de la portion en terme d'originalité. * +* * +* Retour : true si la portion est la suite d'une portion découpée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_is_continuation(const GBinaryPortion *portion) +{ + return portion->continued; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à mettre à jour. * +* rights = droits d'accès de la partie. * +* * +* Description : Définit les droits associés à une partie de code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_binary_portion_set_rights(GBinaryPortion *portion, PortionAccessRights rights) +{ + portion->rights = rights; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = description de partie à consulter. * +* * +* Description : Fournit les droits associés à une partie de code. * +* * +* Retour : Droits d'accès de la partie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PortionAccessRights g_binary_portion_get_rights(const GBinaryPortion *portion) +{ + return portion->rights; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion principale à compléter. * +* sub = portion à inclure dans la définition courante. * +* * +* Description : Procède à l'inclusion d'une portion dans une autre. * +* * +* Retour : Bilan de l'opération : true si inclusion, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_include(GBinaryPortion *portion, GBinaryPortion *sub) +{ + bool result; /* Bilan à retourner */ + bool found; /* Zone d'accueil trouvée ? */ + size_t best; /* Meilleur point d'insertion */ + size_t missed; /* Indice de zone à déplacer */ + const mrange_t *brange; /* Raccourci de confort d'usage*/ + vmpa2t end; /* Fin de la zone commune */ + phys_t overlapping; /* Taille de la zone commune */ + bool continued; /* Suite d'une découpe ? */ + GBinaryPortion *left_part; /* Partie intégrable */ + vmpa2t start; /* Départ de la seconde partie */ + GBinaryPortion *right_part; /* Partie restante */ + + int g_binary_portion_is_included(const GBinaryPortion **a, const GBinaryPortion **b) + { + int result; /* Bilan à retourner */ + + result = mrange_includes_mrange(&(*b)->range, &(*a)->range); + + return result; + + } + + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), + (__compar_fn_t)g_binary_portion_is_included, &best); + + if (!found) + { + /** + * On se prépare à réaliser une insertion au niveau courant. Mais des + * portions précédentes sont peut-être à déplacer dans la nouvelle zone : + * + * EXIDX 0x001178 0x00009178 0x00009178 0x00008 0x00008 R 0x4 + * PHDR 0x000034 0x00008034 0x00008034 0x00120 0x00120 R E 0x4 + * INTERP 0x000154 0x00008154 0x00008154 0x00019 0x00019 R 0x1 + * LOAD 0x000000 0x00008000 0x00008000 0x01184 0x01184 R E 0x8000 + * + * On refait donc une passe sur toutes les sous-portions du niveau. + * + * Cette approche a le mérite de traiter également et naturellement les + * sections définies dans le désordre : + * + * [21] .bss NOBITS 00088240 07823c 0018c8 00 WA 0 0 8 + * [22] __libc_freeres_ptrs NOBITS 00089b08 07823c 000018 00 WA 0 0 4 + * [23] .comment PROGBITS 00000000 07823c 000022 01 MS 0 0 1 + * + * Quant aux cas de figure où les portions sont identiques, l'ordre d'appel + * induit l'ordre d'inclusion. + * + * Cela concerne par exemple les zones de données : + * + * En-têtes de section: + * [Nr] Nom Type Adr Décala.Taille ES Fan LN Inf Al + * ... + * [ 2] .data PROGBITS 00010098 000098 00000c 00 WA 0 0 1 + * + * En-têtes de programme: + * Type Décalage Adr. vir. Adr.phys. T.Fich. T.Mém. Fan Alignement + * ... + * LOAD 0x000098 0x00010098 0x00010098 0x0000c 0x0000c RW 0x8000 + * + */ + + int g_binary_portion_track_missed_inclusion(const GBinaryPortion **a, const GBinaryPortion **b) + { + int result; /* Bilan à retourner */ + + result = mrange_includes_mrange(&(*a)->range, &(*b)->range); + + return result; + + } + + do + { + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), + (__compar_fn_t)g_binary_portion_track_missed_inclusion, &missed); + + if (found) + { + result = g_binary_portion_include(sub, portion->subs[missed]); + assert(result); + + portion->subs = _qdelete(portion->subs, &portion->count, sizeof(GBinaryPortion *), missed); + + } + + } + while (found); + + /** + * Il peut arriver que certaines portions débordent de leur zone d'inclusion : + * + * [24] .bss NOBITS 00012088 002084 000044 00 WA 0 0 8 + * [25] .ARM.attributes ARM_ATTRIBUTES 00000000 002084 000037 00 0 0 1 + * [26] .shstrtab STRTAB 00000000 0020bb 0000ed 00 0 0 1 + * + * Afin de respecter une certaine cohérence dans l'arbre des portions, on choisit + * de découper la portion qui déborde. + */ + + int g_binary_portion_track_partial_inclusion(const GBinaryPortion **a, const GBinaryPortion **b) + { + int result; /* Bilan à retourner */ + + result = cmp_mrange_with_vmpa(&(*b)->range, get_mrange_addr(&(*a)->range)); + + return result; + + } + + found = bsearch_index(&sub, portion->subs, portion->count, sizeof(GBinaryPortion *), + (__compar_fn_t)g_binary_portion_track_partial_inclusion, &best); + + if (found) + { + brange = &portion->subs[best]->range; + + compute_mrange_end_addr(brange, &end); + overlapping = compute_vmpa_diff(get_mrange_addr(&sub->range), &end); + + continued = g_binary_portion_is_continuation(sub); + + /* Partie contenue */ + + left_part = g_binary_portion_new(get_mrange_addr(&sub->range), overlapping); + + g_binary_portion_set_desc(left_part, sub->desc); + g_binary_portion_mark_as_continued(left_part, continued); + g_binary_portion_set_rights(left_part, sub->rights); + + /* Partie qui déborde... */ + + /** + * Comme la portion incluante peut avoir une définition d'adresse + * virtuelle différente de celle de la portion incluse, on recalcule + * la position de départ de la seconde partie de la portion découpée + * à partir des données d'origine. + */ + + copy_vmpa(&start, get_mrange_addr(&sub->range)); + advance_vmpa(&start, overlapping); + + right_part = g_binary_portion_new(&start, get_mrange_length(&sub->range) - overlapping); + + if (!continued) + g_binary_portion_mark_as_continued(right_part, true); + + g_binary_portion_set_desc(right_part, sub->desc); + + if (continued) + g_binary_portion_mark_as_continued(right_part, true); + + g_binary_portion_set_rights(right_part, sub->rights); + + /* Inclusions des parties */ + + result = g_binary_portion_include(portion, left_part); + + if (result) + result = g_binary_portion_include(portion, right_part); + + unref_object(left_part); + unref_object(right_part); + + } + + else + { + ref_object(sub); + + portion->subs = qinsert(portion->subs, &portion->count, sizeof(GBinaryPortion *), + (__compar_fn_t)g_binary_portion_compare, &sub); + + result = true; + + } + + } + + /* Poursuite de l'inclusion dans la sous-portion adaptée... */ + else + result = g_binary_portion_include(portion->subs[best], sub); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = première couche amorçant la visite. * +* visitor = fonction à appeler à chaque étape de la descente. * +* data = adresse pointant vers des données de l'utilisateur.* +* * +* Description : Parcourt un ensemble de portions binaires. * +* * +* Retour : true si la visite a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_visit(GBinaryPortion *portion, visit_portion_fc visitor, void *data) +{ + bool result; /* Etat à retourner */ + + bool visit_portion(GBinaryPortion *p, GBinaryPortion *pp) + { + bool ret; /* Etat à retourner */ + size_t i; /* Boucle de parcours */ + + if (p->count == 0) + ret = visitor(p, pp, BPV_SHOW, data); + + else + { + ret = visitor(p, pp, BPV_ENTER, data); + + for (i = 0; i < p->count && ret; i++) + ret = visit_portion(p->subs[i], p); + + if (ret) + ret = visitor(p, pp, BPV_EXIT, data); + + } + + return ret; + + } + + result = visit_portion(portion, NULL); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* PARCOURS D'ENSEMBLES DE PORTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : portion = portion mère à consulter. * +* addr = adresse du point de recherche. * +* * +* Description : Détermine si une portion contient une adresse donnée. * +* * +* Retour : true ou false selon le résultat. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_portion_contains_vmpa(const GBinaryPortion *portion, const vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + const mrange_t *range; /* Emplacement de portion */ + + result = false; + + range = g_binary_portion_get_range(portion); + + /* Portion non allouée en mémoire : on écarte */ + if (!has_virt_addr(get_mrange_addr(range))) + goto not_found; + + result = mrange_contains_addr(range, addr); + + not_found: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = couche de portions à parcourir pour les recherches.* +* addr = adresse du point de recherche. * +* * +* Description : Recherche la portion présente à une adresse donnée. * +* * +* Retour : Portion trouvée à l'endroit indiqué. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinaryPortion *g_binary_portion_find_at_addr(GBinaryPortion *portion, const vmpa2t *addr) +{ + GBinaryPortion *result; /* Portion à retourner */ + size_t i; /* Boucle de parcours */ + GBinaryPortion *sub; /* Portion incluse à traiter */ + + result = NULL; + + if (!g_binary_portion_contains_vmpa(portion, addr)) + goto done; + + for (i = 0; i < portion->count && result == NULL; i++) + { + sub = portion->subs[i]; + + if (!g_binary_portion_contains_vmpa(sub, addr)) + continue; + + result = g_binary_portion_find_at_addr(sub, addr); + + } + + if (result == NULL) + { + result = portion; + ref_object(result); + } + + done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion mère à consulter. * +* off = position physique du point de recherche. * +* * +* Description : Détermine si une portion contient une position donnée. * +* * +* Retour : true ou false selon le résultat. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_portion_contains_physical(const GBinaryPortion *portion, phys_t off) +{ + bool result; /* Bilan à retourner */ + const mrange_t *range; /* Emplacement de portion */ + const vmpa2t *addr; /* Départ de la portion */ + + range = g_binary_portion_get_range(portion); + addr = get_mrange_addr(range); + + if (!has_phys_addr(addr)) + result = false; + + else + result = (addr->physical <= off && off < (addr->physical + range->length)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = couche de portions à parcourir pour les recherches.* +* off = position physique à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une position physique. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_translate_offset_into_vmpa(const GBinaryPortion *portion, phys_t off, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours #1 */ + GBinaryPortion *sub; /* Portion incluse à traiter */ + const mrange_t *range; /* Emplacement de portion */ + const vmpa2t *addr; /* Départ de la portion */ + + result = false; + + for (i = 0; i < portion->count; i++) + { + sub = portion->subs[i]; + + if (!g_binary_portion_contains_physical(sub, off)) + continue; + + result = g_binary_portion_translate_offset_into_vmpa(sub, off, pos); + + break; + + } + + if (i == portion->count) + { + result = g_binary_portion_contains_physical(portion, off); + + if (result) + { + range = g_binary_portion_get_range(portion); + addr = get_mrange_addr(range); + + if (has_virt_addr(get_mrange_addr(range))) + init_vmpa(pos, off, addr->virtual + off - addr->physical); + + else + init_vmpa(pos, off, VMPA_NO_VIRTUAL); + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = portion mère à consulter. * +* virt = adresse virtuelle du point de recherche. * +* * +* Description : Détermine si une portion contient une adresse donnée. * +* * +* Retour : true ou false selon le résultat. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_binary_portion_contains_virtual(const GBinaryPortion *portion, virt_t virt) +{ + bool result; /* Bilan à retourner */ + const mrange_t *range; /* Emplacement de portion */ + const vmpa2t *addr; /* Départ de la portion */ + + range = g_binary_portion_get_range(portion); + addr = get_mrange_addr(range); + + if (!has_virt_addr(addr)) + result = false; + + else + result = (addr->virtual <= virt && virt < (addr->virtual + range->length)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : portion = couche de portions à parcourir pour les recherches.* +* virt = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit l'emplacement correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_portion_translate_address_into_vmpa(const GBinaryPortion *portion, virt_t virt, vmpa2t *pos) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours #1 */ + GBinaryPortion *sub; /* Portion incluse à traiter */ + const mrange_t *range; /* Emplacement de portion */ + const vmpa2t *addr; /* Départ de la portion */ + + result = false; + + for (i = 0; i < portion->count; i++) + { + sub = portion->subs[i]; + + if (!g_binary_portion_contains_virtual(sub, virt)) + continue; + + result = g_binary_portion_translate_address_into_vmpa(sub, virt, pos); + + break; + + } + + if (i == portion->count) + { + result = g_binary_portion_contains_virtual(portion, virt); + + if (result) + { + range = g_binary_portion_get_range(portion); + addr = get_mrange_addr(range); + + if (has_phys_addr(addr) && has_virt_addr(addr)) + init_vmpa(pos, addr->physical + virt - addr->virtual, virt); + + else + init_vmpa(pos, VMPA_NO_PHYSICAL, virt); + + } + + } + + return result; + +} |