diff options
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/gbinportion.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 790614a..abdec60 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -898,14 +898,61 @@ void g_portion_layer_attach_sub(GPortionLayer *layer, GPortionLayer *sub) void g_portion_layer_include(GPortionLayer *layer, GBinPortion *portion) { - layer->portions = (GBinPortion **)realloc(layer->portions, - ++layer->count * sizeof(GBinPortion *)); + GPortionLayer *sub; /* Sous couche indispensable */ + bool conflict; /* Conflit dû aux débordements */ + const mrange_t *range; /* Emplacement de la portion */ + size_t i; /* Boucle de parcours */ + const mrange_t *other; /* Emplacements déjà occupés */ + + /** + * On prend ici en compte le genre de situations suivantes : + * + * [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 + * + * Pendant le désassemblage, la procédure n'aime pas trop les intersections + * de zones mémoire. + */ + + conflict = false; + + range = g_binary_portion_get_range(portion); + + for (i = 0; i < layer->count && !conflict; i++) + { + other = g_binary_portion_get_range(layer->portions[i]); - layer->portions[layer->count - 1] = portion; + conflict = mrange_intersects_mrange(range, other); - g_binary_portion_set_level(portion, &layer->level); + } + + /* La portion recouvre-t-elle une portion déjà existante ? */ + if (conflict) + { + if (layer->sub_layer == NULL) + { + sub = g_portion_layer_new(layer->length, layer->name); + g_portion_layer_attach_sub(layer, sub); + } - qsort(layer->portions, layer->count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare); + g_portion_layer_include(layer->sub_layer, portion); + + } + + /* Sinon on l'intègre dans la couche courante */ + else + { + layer->portions = (GBinPortion **)realloc(layer->portions, + ++layer->count * sizeof(GBinPortion *)); + + layer->portions[layer->count - 1] = portion; + + g_binary_portion_set_level(portion, &layer->level); + + qsort(layer->portions, layer->count, sizeof(GBinPortion *), (__compar_fn_t)g_binary_portion_compare); + + } } |