summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-12-29 15:08:17 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-12-29 15:08:17 (GMT)
commit5cad06b6a52e17d5649e0152c15745a96f7c0efa (patch)
treee26b0857ed6cddd70bce33f983a97e5245fae3fe /src/glibext
parent73fb6dd90282dd10a6c3febe7348ad698c0336a8 (diff)
Handled ELF overlapping program and section headers.
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/gbinportion.c57
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);
+
+ }
}