summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-07-12 22:47:38 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-07-12 22:47:38 (GMT)
commitd7f78fe9a75d96b6f3d441335dcf50a5c026d8ea (patch)
tree632744c467641825441b866c4f988c03d9c20cf1 /src
parentbdda063b67d8c1d402f6dc17726fed0c800d3d1c (diff)
Taken into account that raw immediate values can be used more than once.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/db/items/comment.c2
-rw-r--r--src/arch/arm/v7/fetch.c38
-rw-r--r--src/common/array.c66
-rw-r--r--src/common/array.h3
-rw-r--r--src/format/preload.c134
-rw-r--r--src/format/preload.h12
-rw-r--r--src/glibext/gbuffercache.c31
7 files changed, 268 insertions, 18 deletions
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 9368291..cad2d64 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -1129,7 +1129,7 @@ char *g_db_comment_get_text(GDbComment *comment)
for (i = 0; i < count; i++)
{
- string = get_flat_array_item(comment->text, 0, sizeof(rle_string));
+ string = get_flat_array_item(comment->text, i, sizeof(rle_string));
assert(!is_rle_string_empty(string));
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index 929c877..42788af 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -367,6 +367,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
uint32_t target; /* Adresse virtuelle visée */
vmpa2t pos; /* Tête de lecture de valeur */
VMPA_BUFFER(loc); /* Adresse au format texte */
+ GPreloadInfo *info; /* Informations préchargées */
GArchInstruction *loaded; /* Instruction de valeur */
char *desc; /* Description d'accompagnement*/
GDbComment *comment; /* Définition de commentaire */
@@ -439,18 +440,43 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
copy_vmpa(&pos, &loaded_addr);
- loaded = g_raw_instruction_new_from_value(&pos, MDS_32_BITS_UNSIGNED, target);
+ info = G_PRELOAD_INFO(context);
- g_preload_info_add_instruction(G_PRELOAD_INFO(context), loaded);
+ g_preload_info_lock_instructions(info);
+
+ if (!_g_preload_info_has_instruction_at(info, &loaded_addr))
+ {
+ loaded = g_raw_instruction_new_from_value(&pos, MDS_32_BITS_UNSIGNED, target);
+ _g_preload_info_add_instruction(info, loaded);
+ }
+
+ g_preload_info_unlock_instructions(info);
vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL);
asprintf(&desc, _("Value used @ %s"), loc);
- comment = g_db_comment_new_inlined(&loaded_addr, BLF_HAS_CODE, false);
- g_db_comment_add_static_text(comment, desc);
- g_db_item_set_volatile(G_DB_ITEM(comment), true);
+ g_preload_info_lock_comments(info);
+
+ comment = _g_preload_info_find_comment_at(info, &loaded_addr);
+
+ if (comment != NULL)
+ {
+ g_db_comment_add_static_text(comment, "\n");
+ g_db_comment_add_dynamic_text(comment, desc);
+ }
+
+ else
+ {
+ comment = g_db_comment_new_inlined(&loaded_addr, BLF_HAS_CODE, false);
+ g_db_item_set_volatile(G_DB_ITEM(comment), true);
+
+ g_db_comment_add_dynamic_text(comment, desc);
+
+ _g_preload_info_add_comment(info, comment);
+
+ }
- g_preload_info_add_comment(G_PRELOAD_INFO(context), comment);
+ g_preload_info_unlock_comments(info);
/* Mise à jour de l'affichage et conclusion */
diff --git a/src/common/array.c b/src/common/array.c
index dcb9344..36c30a1 100644
--- a/src/common/array.c
+++ b/src/common/array.c
@@ -632,3 +632,69 @@ void *get_flat_array_item(flat_array_t *array, size_t index, size_t size)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : array = tableau compressé à consulter. *
+* size = taille de ce nouvel élément. *
+* compar = méthode de comparaison entre éléments. *
+* key = élément de comparaison fourni. *
+* *
+* Description : Recherche un élément dans un tableau trié. *
+* *
+* Retour : Eventuel élément trouvé ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void *find_item_in_flat_array(flat_array_t *array, size_t size, __compar_fn_t compar, const void *key)
+{
+ void *result; /* Trouvaille à retourner */
+ size_t count; /* Nombre d'éléments présents */
+ void *item; /* Elément isolé présent */
+ ext_flat_array_t *extended; /* Version de tableau étendue */
+ size_t index; /* Indice de l'élément trouvé */
+
+ assert(FLAT_ARRAY_IS_LOCKED(array));
+
+ count = count_flat_array_items(array);
+
+ switch (count)
+ {
+ case 0:
+ result = NULL;
+ break;
+
+ case 1:
+
+ assert(FLAT_ARRAY_HAS_NO_INDEX(array));
+
+ item = GET_LONELY_ITEM(array);
+
+ if (compar(key, item) == 0)
+ result = item;
+ else
+ result = NULL;
+
+ break;
+
+ default:
+
+ assert(!FLAT_ARRAY_HAS_NO_INDEX(array));
+
+ extended = EXTENDED_ARRAY(array);
+
+ if (bsearch_index(key, extended->items, extended->count, size, compar, &index))
+ result = (void *)(((char *)extended->items) + index * size);
+ else
+ result = NULL;
+
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/common/array.h b/src/common/array.h
index 546de1a..5ddc9ba 100644
--- a/src/common/array.h
+++ b/src/common/array.h
@@ -67,6 +67,9 @@ void rem_item_from_flat_array(flat_array_t **, size_t, size_t);
/* Fournit un élément présent dans un tableau compressé. */
void *get_flat_array_item(flat_array_t *, size_t, size_t);
+/* Recherche un élément dans un tableau trié. */
+void *find_item_in_flat_array(flat_array_t *, size_t, __compar_fn_t, const void *);
+
#endif /* _COMMON_ARRAY_H */
diff --git a/src/format/preload.c b/src/format/preload.c
index 2eec92e..7f7a435 100644
--- a/src/format/preload.c
+++ b/src/format/preload.c
@@ -261,6 +261,30 @@ void g_preload_info_unlock_instructions(GPreloadInfo *info)
void g_preload_info_add_instruction(GPreloadInfo *info, GArchInstruction *instr)
{
+ g_preload_info_lock_instructions(info);
+
+ _g_preload_info_add_instruction(info, instr);
+
+ g_preload_info_unlock_instructions(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* instr = instruction à venir associer. *
+* *
+* Description : Ajoute une instruction supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void _g_preload_info_add_instruction(GPreloadInfo *info, GArchInstruction *instr)
+{
int cmp_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
{
const mrange_t *range_a; /* Emplacement pour l'instr. A */
@@ -273,12 +297,46 @@ void g_preload_info_add_instruction(GPreloadInfo *info, GArchInstruction *instr)
}
- g_preload_info_lock_instructions(info);
-
insert_item_into_flat_array(&info->instructions, &instr, sizeof(GArchInstruction *),
(__compar_fn_t)cmp_instr_by_addr);
- g_preload_info_unlock_instructions(info);
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* addr = localisation du commentaire recherché. *
+* *
+* Description : Détermine si une instruction est présente à un point donné. *
+* *
+* Retour : true si une instruction existe à l'emplacement indiqué. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool _g_preload_info_has_instruction_at(GPreloadInfo *info, const vmpa2t *addr)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstruction **ptr; /* Adresse dans le tableau */
+
+ int cmp_instr_by_addr(const vmpa2t *key, const GArchInstruction **i)
+ {
+ const mrange_t *range; /* Emplacement pour l'instr. */
+
+ range = g_arch_instruction_get_range(*i);
+
+ return cmp_vmpa(key, get_mrange_addr(range));
+
+ }
+
+ ptr = find_item_in_flat_array(info->instructions, sizeof(GArchInstruction *),
+ (__compar_fn_t)cmp_instr_by_addr, addr);
+
+ result = (ptr != NULL);
+
+ return result;
}
@@ -457,6 +515,30 @@ void g_preload_info_unlock_comments(GPreloadInfo *info)
void g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
{
+ g_preload_info_lock_comments(info);
+
+ _g_preload_info_add_comment(info, comment);
+
+ g_preload_info_unlock_comments(info);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à jour. *
+* comment = commentaire à venir associer. *
+* *
+* Description : Ajoute un commentaire supplémentaire aux préchargements. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void _g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
+{
int cmp_comment_by_addr(const GDbComment * const *a, const GDbComment * const *b)
{
const vmpa2t *addr_a; /* Position du commentaire A */
@@ -469,12 +551,52 @@ void g_preload_info_add_comment(GPreloadInfo *info, GDbComment *comment)
}
- g_preload_info_lock_comments(info);
-
insert_item_into_flat_array(&info->comments, &comment, sizeof(GDbComment *),
(__compar_fn_t)cmp_comment_by_addr);
- g_preload_info_unlock_comments(info);
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = instance à mettre à consulter. *
+* addr = localisation du commentaire recherché. *
+* *
+* Description : Recherche un commentaire dans des préchargements. *
+* *
+* Retour : Eventuel commenaire retrouvé ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *info, const vmpa2t *addr)
+{
+ GDbComment *result; /* Trouvaille à retourner */
+ GDbComment **ptr; /* Adresse dans le tableau */
+
+ int cmp_comment_by_addr(const vmpa2t *key, const GDbComment * const *comment)
+ {
+ const vmpa2t *caddr; /* Position du commentaire */
+
+ caddr = g_db_comment_get_address(*comment);
+
+ return cmp_vmpa(key, caddr);
+
+ }
+
+ ptr = find_item_in_flat_array(info->comments, sizeof(GDbComment *),
+ (__compar_fn_t)cmp_comment_by_addr, addr);
+
+ if (ptr != NULL)
+ {
+ result = *ptr;
+ g_object_ref(G_OBJECT(result));
+ }
+ else
+ result = NULL;
+
+ return result;
}
diff --git a/src/format/preload.h b/src/format/preload.h
index 59c81b7..1e28222 100644
--- a/src/format/preload.h
+++ b/src/format/preload.h
@@ -66,6 +66,12 @@ void g_preload_info_unlock_instructions(GPreloadInfo *);
/* Ajoute une instruction supplémentaire aux préchargements. */
void g_preload_info_add_instruction(GPreloadInfo *, GArchInstruction *);
+/* Ajoute une instruction supplémentaire aux préchargements. */
+void _g_preload_info_add_instruction(GPreloadInfo *, GArchInstruction *);
+
+/* Détermine si une instruction est présente à un point donné. */
+bool _g_preload_info_has_instruction_at(GPreloadInfo *, const vmpa2t *);
+
/* Indique la quantité d'instructions préchargées disponibles. */
size_t _g_preload_info_count_instructions(const GPreloadInfo *);
@@ -87,6 +93,12 @@ void g_preload_info_unlock_comments(GPreloadInfo *);
/* Ajoute un commentaire supplémentaire aux préchargements. */
void g_preload_info_add_comment(GPreloadInfo *, GDbComment *);
+/* Ajoute un commentaire supplémentaire aux préchargements. */
+void _g_preload_info_add_comment(GPreloadInfo *, GDbComment *);
+
+/* Recherche un commentaire dans des préchargements. */
+GDbComment *_g_preload_info_find_comment_at(GPreloadInfo *, const vmpa2t *);
+
/* Indique la quantité de commentaires préchargés disponibles. */
size_t _g_preload_info_count_comments(const GPreloadInfo *);
diff --git a/src/glibext/gbuffercache.c b/src/glibext/gbuffercache.c
index fd7c987..f7dc49f 100644
--- a/src/glibext/gbuffercache.c
+++ b/src/glibext/gbuffercache.c
@@ -903,10 +903,15 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
}
}
-#ifndef NDEBUG
- else
- assert(needed == 1);
-#endif
+
+ else if (needed > 1)
+ {
+ if ((cache->used + needed - 1) >= cache->count)
+ {
+ cache->count += needed - 1 + LINE_ALLOC_BULK;
+ cache->lines = (cache_info *)realloc(cache->lines, cache->count * sizeof(cache_info));
+ }
+ }
/* Insertion du générateur */
@@ -934,7 +939,23 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator
g_width_tracker_update(cache->tracker, index);
- g_signal_emit_by_name(cache, "size-changed", true, index, 1);
+ if (needed > 1)
+ {
+ /* On déborde sur les lignes suivantes, donc on crée de l'espace ! */
+
+ memmove(&cache->lines[index + 1],
+ &cache->lines[index + 1 + needed - 1], (cache->used - index - 1) * sizeof(cache_info));
+
+ for (i = 1; i < needed; i++)
+ init_cache_info(&cache->lines[index + i], generator, i, BLF_NONE);
+
+ cache->used += needed - 1;
+
+ g_width_tracker_update_added(cache->tracker, index + 1, needed - 1);
+
+ }
+
+ g_signal_emit_by_name(cache, "size-changed", true, index, needed - 1);
}