summaryrefslogtreecommitdiff
path: root/src/format/format.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-01-13 22:37:31 (GMT)
commit23b9c6e68bbe5f0531f9a9408c2deb9f897701dc (patch)
tree3804d6c21c9cd5e291cb8c7853607cdda992d125 /src/format/format.c
parenta6975c1d754a1ba5bfb9e23f0b26692c746e6f9c (diff)
Created a real iterator for symbols.
Diffstat (limited to 'src/format/format.c')
-rw-r--r--src/format/format.c239
1 files changed, 192 insertions, 47 deletions
diff --git a/src/format/format.c b/src/format/format.c
index 1ab7efa..a188204 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -50,6 +50,11 @@ static void g_binary_format_dispose(GBinFormat *);
/* Procède à la libération totale de la mémoire. */
static void g_binary_format_finalize(GBinFormat *);
+
+
+/* ---------------------- RASSEMBLEMENT ET GESTION DE SYMBOLES ---------------------- */
+
+
/* Retire un symbole de la collection du format binaire. */
static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
@@ -108,6 +113,9 @@ static void g_binary_format_init(GBinFormat *format)
format->info = g_preload_info_new();
g_rw_lock_init(&format->syms_lock);
+#ifndef DEBUG
+ g_atomic_int_set(&format->sym_locked, 0);
+#endif
format->errors = NULL;
format->error_count = 0;
@@ -361,6 +369,161 @@ void g_binary_format_activate_disassembling_context(GBinFormat *format, GProcCon
}
+
+/* ---------------------------------------------------------------------------------- */
+/* RASSEMBLEMENT ET GESTION DE SYMBOLES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : format = architecture à manipuler. *
+* state = nouvel état de l'accès aux symboles. *
+* *
+* Description : Protège ou lève la protection de l'accès aux symboles. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_lock_unlock_symbols_rd(GBinFormat *format, bool state)
+{
+#ifndef NDEBUG
+ gint test; /* Test de valeur courante */
+#endif
+
+ if (state)
+ {
+ g_rw_lock_reader_lock(&format->syms_lock);
+#ifndef NDEBUG
+ g_atomic_int_inc(&format->sym_locked);
+#endif
+ }
+ else
+ {
+#ifndef NDEBUG
+ test = g_atomic_int_add(&format->sym_locked, -1);
+ assert(test > 0);
+#endif
+ g_rw_lock_reader_unlock(&format->syms_lock);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = architecture à manipuler. *
+* state = nouvel état de l'accès aux symboles. *
+* *
+* Description : Protège ou lève la protection de l'accès aux symboles. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_lock_unlock_symbols_wr(GBinFormat *format, bool state)
+{
+ if (state)
+ {
+ g_rw_lock_writer_lock(&format->syms_lock);
+#ifndef NDEBUG
+ g_atomic_int_set(&format->sym_locked, 1);
+#endif
+ }
+ else
+ {
+#ifndef NDEBUG
+ g_atomic_int_set(&format->sym_locked, 0);
+#endif
+ g_rw_lock_writer_unlock(&format->syms_lock);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = architecture à consulter via la procédure. *
+* *
+* Description : Fournit la marque de dernière modification des symboles. *
+* *
+* Retour : Marque de la dernière modification de la liste de symboles. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+unsigned int g_binary_format_get_symbols_stamp(const GBinFormat *format)
+{
+ return format->sym_stamp;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format visé par la procédure. *
+* *
+* Description : Compte le nombre de symboles représentés. *
+* *
+* Retour : Nombre de symboles présents. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+size_t g_binary_format_count_symbols(const GBinFormat *format)
+{
+ assert(g_atomic_int_get(&format->sym_locked) > 0);
+
+ return format->sym_count;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = format visé par la procédure. *
+* index = indice du symbole visé. *
+* *
+* Description : Fournit un symbole lié à un format. *
+* *
+* Retour : Symbole conservé trouvé ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinSymbol *g_binary_format_get_symbol(const GBinFormat *format, size_t index)
+{
+ GBinSymbol *result; /* Symbole à retourner */
+
+ assert(g_atomic_int_get(&format->sym_locked) > 0);
+
+ if (format->sym_count == 0)
+ result = NULL;
+
+ else
+ {
+ assert(index < format->sym_count);
+
+ result = format->symbols[index];
+ assert(result != NULL);
+
+ g_object_ref(G_OBJECT(result));
+
+ }
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : format = informations chargées à compléter. *
@@ -409,7 +572,7 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
assert(has_phys_addr(addr) || g_binary_symbol_get_status(symbol) == SSS_IMPORTED);
#endif
- g_rw_lock_writer_lock(&format->syms_lock);
+ g_binary_format_lock_unlock_symbols_wr(format, true);
/**
* Avec tous les traitements parallèles, il est possible que plusieurs chemins d'exécution
@@ -421,21 +584,22 @@ bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
* construction du symbole dans les cas peu fréquents où le symbole était déjà en place.
*/
- result = bsearch_index(&symbol, format->symbols, format->symbols_count,
+ result = bsearch_index(&symbol, format->symbols, format->sym_count,
sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, &index);
if (!result)
{
- format->symbols = _qinsert(format->symbols, &format->symbols_count,
+ format->symbols = _qinsert(format->symbols, &format->sym_count,
sizeof(GBinSymbol *), &symbol, index);
+ format->sym_stamp++;
result = true;
}
else
g_object_unref(G_OBJECT(symbol));
- g_rw_lock_writer_unlock(&format->syms_lock);
+ g_binary_format_lock_unlock_symbols_wr(format, false);
return result;
@@ -459,17 +623,18 @@ static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index)
{
/**
* TODO : envoyer un signal pour avertir les opérandes concernées.
- * TODO : vérifier les conditions d'accès (verrou).
*/
- assert(index < format->symbols_count);
+ assert(g_atomic_int_get(&format->sym_locked) == 1);
+
+ assert(index < format->sym_count);
- if ((index + 1) < format->symbols_count)
+ if ((index + 1) < format->sym_count)
memmove(&format->symbols[index], &format->symbols[index + 1],
- (format->symbols_count - index - 1) * sizeof(GBinSymbol *));
+ (format->sym_count - index - 1) * sizeof(GBinSymbol *));
format->symbols = (GBinSymbol **)realloc(format->symbols,
- --format->symbols_count * sizeof(GBinSymbol *));
+ --format->sym_count * sizeof(GBinSymbol *));
}
@@ -493,7 +658,7 @@ void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol)
// FIXME : dicho
- for (i = 0; i < format->symbols_count; i++)
+ for (i = 0; i < format->sym_count; i++)
if (format->symbols[i] == symbol)
break;
@@ -521,15 +686,15 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
mrange_t last; /* Dernière localisation vue */
size_t index; /* Indice de suppression */
- g_rw_lock_writer_lock(&format->syms_lock);
+ g_binary_format_lock_unlock_symbols_wr(format, true);
- if (format->symbols_count > 1)
+ if (format->sym_count > 1)
{
range = g_binary_symbol_get_range(format->symbols[0]);
copy_mrange(&last, range);
}
- for (i = 1; i < format->symbols_count; i++)
+ for (i = 1; i < format->sym_count; i++)
{
range = g_binary_symbol_get_range(format->symbols[i]);
@@ -554,29 +719,7 @@ static void g_binary_format_delete_duplicated_symbols(GBinFormat *format)
}
- g_rw_lock_writer_unlock(&format->syms_lock);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = informations chargées à consulter. *
-* count = taille du tableau créé. [OUT] *
-* *
-* Description : Fournit la liste de tous les symboles détectés. *
-* *
-* Retour : Tableau créé ou NULL si aucun symbole trouvé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBinSymbol **g_binary_format_get_symbols(const GBinFormat *format, size_t *count)
-{
- *count = format->symbols_count;
-
- return format->symbols;
+ g_binary_format_lock_unlock_symbols_wr(format, false);
}
@@ -693,9 +836,9 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
result = false;
- g_rw_lock_reader_lock(&format->syms_lock);
+ g_binary_format_lock_symbols_rd(format);
- for (i = 0; i < format->symbols_count && !result; i++)
+ for (i = 0; i < format->sym_count && !result; i++)
{
cur_lbl = g_binary_symbol_get_label(format->symbols[i]);
if (cur_lbl == NULL) continue;
@@ -711,7 +854,7 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
}
- g_rw_lock_reader_unlock(&format->syms_lock);
+ g_binary_format_unlock_symbols_rd(format);
return result;
@@ -739,6 +882,8 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
bool result; /* Bilan à retourner */
void *found; /* Résultat de recherches */
+ assert(g_atomic_int_get(&format->sym_locked) > 0);
+
/**
* Pour ce qui est des justifications quant à la vérification suivante,
* se référer aux commentaires placés dans g_binary_format_add_symbol().
@@ -746,7 +891,7 @@ static bool _g_binary_format_find_symbol(const GBinFormat *format, const vmpa2t
assert(has_phys_addr(addr));
- found = bsearch(addr, format->symbols, format->symbols_count, sizeof(GBinSymbol *), fn);
+ found = bsearch(addr, format->symbols, format->sym_count, sizeof(GBinSymbol *), fn);
if (found != NULL)
{
@@ -802,11 +947,11 @@ bool g_binary_format_find_symbol_at(GBinFormat *format, const vmpa2t *addr, GBin
}
- g_rw_lock_reader_lock(&format->syms_lock);
+ g_binary_format_lock_symbols_rd(format);
result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol);
- g_rw_lock_reader_unlock(&format->syms_lock);
+ g_binary_format_unlock_symbols_rd(format);
return result;
@@ -841,11 +986,11 @@ bool g_binary_format_find_symbol_for(GBinFormat *format, const vmpa2t *addr, GBi
}
- g_rw_lock_reader_lock(&format->syms_lock);
+ g_binary_format_lock_symbols_rd(format);
result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, NULL, symbol);
- g_rw_lock_reader_unlock(&format->syms_lock);
+ g_binary_format_unlock_symbols_rd(format);
return result;
@@ -881,11 +1026,11 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
}
- g_rw_lock_reader_lock(&format->syms_lock);
+ g_binary_format_lock_symbols_rd(format);
result = _g_binary_format_find_symbol(format, addr, (__compar_fn_t)find_symbol, &index, NULL);
- if (result && (index + 1) < format->symbols_count)
+ if (result && (index + 1) < format->sym_count)
{
*symbol = format->symbols[index + 1];
g_object_ref(G_OBJECT(*symbol));
@@ -898,7 +1043,7 @@ bool g_binary_format_find_next_symbol_at(GBinFormat *format, const vmpa2t *addr,
result = false;
}
- g_rw_lock_reader_unlock(&format->syms_lock);
+ g_binary_format_unlock_symbols_rd(format);
return result;