summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-01-06 04:12:24 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-01-06 04:12:24 (GMT)
commit6db53b26e6c3d973295df51bb1934d5b42fb6ebe (patch)
tree401358c8b10a879daa23336d06d7f14f273ee764 /src/format
parent73308548c2be7f6480f3c898ceb6d01ae4e3f64c (diff)
Checked if a symbol exists right before adding it to the symbol list.
Diffstat (limited to 'src/format')
-rw-r--r--src/format/format.c51
-rw-r--r--src/format/format.h2
-rw-r--r--src/format/symbol.h28
3 files changed, 52 insertions, 29 deletions
diff --git a/src/format/format.c b/src/format/format.c
index 6f2c03e..be522cb 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -286,12 +286,14 @@ void g_binary_format_setup_disassembling_context(GBinFormat *format, GProcContex
* *
******************************************************************************/
-void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
+bool g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
{
+ bool result; /* Statut d'ajout à retourner */
#ifndef NDEBUG
const mrange_t *range; /* Couverture du symbole */
const vmpa2t *addr; /* Emplacement du symbole */
#endif
+ size_t index; /* Indice du point d'insertion */
GBinRoutine *routine; /* Nouvelle routine à insérer */
/**
@@ -309,33 +311,54 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
range = g_binary_symbol_get_range(symbol);
addr = get_mrange_addr(range);
- assert(get_phy_addr(addr) != VMPA_NO_PHYSICAL && get_virt_addr(addr) != VMPA_NO_VIRTUAL);
+ assert(!is_invalid_vmpa(addr));
#endif
g_rw_lock_writer_lock(&format->syms_lock);
- format->symbols = qinsert(format->symbols, &format->symbols_count,
- sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, &symbol);
+ /**
+ * Avec tous les traitements parallèles, il est possible que plusieurs chemins d'exécution
+ * amènent à la création d'un même symbole.
+ *
+ * Plutôt que de verrouiller la liste des symboles en amont (et donc assez longtemps)
+ * pour faire une vérification avant construction puis ajout, on préfère limiter
+ * l'état figé à cette seule fonction, quitte à annuler le travail fourni pour la
+ * construction du symbole dans les cas peu fréquents où le symbole était déjà en place.
+ */
- switch (g_binary_symbol_get_target_type(symbol))
+ result = bsearch_index(&symbol, format->symbols, format->symbols_count,
+ sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp, &index);
+
+ if (!result)
{
- case STP_ROUTINE:
- case STP_ENTRY_POINT:
+ format->symbols = _qinsert(format->symbols, &format->symbols_count,
+ sizeof(GBinSymbol *), &symbol, index);
- routine = g_binary_symbol_get_routine(symbol);
+ switch (g_binary_symbol_get_target_type(symbol))
+ {
+ case STP_ROUTINE:
+ case STP_ENTRY_POINT:
- format->routines = qinsert(format->routines, &format->routines_count,
- sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare,
- &routine);
- break;
+ routine = g_binary_symbol_get_routine(symbol);
- default:
- break;
+ format->routines = qinsert(format->routines, &format->routines_count,
+ sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare,
+ &routine);
+ break;
+
+ default:
+ break;
+
+ }
}
+ else
+ g_object_unref(G_OBJECT(symbol));
g_rw_lock_writer_unlock(&format->syms_lock);
+ return result;
+
}
diff --git a/src/format/format.h b/src/format/format.h
index 81f1776..d97f542 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -68,7 +68,7 @@ void g_binary_format_register_code_point(GBinFormat *, virt_t, bool);
void g_binary_format_setup_disassembling_context(GBinFormat *, GProcContext *);
/* Ajoute un symbole à la collection du format binaire. */
-void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
+bool g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
/* Retire un symbole de la collection du format binaire. */
void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 67696f4..4a48cf8 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -144,8 +144,8 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
while (0)
#define ADD_RAW_AS_SYM(_fmt, _sym, _ins, _cmt, _txt) \
- do \
- { \
+ ({ \
+ bool __result; \
const vmpa2t *__addr; \
__addr = get_mrange_addr(g_arch_instruction_get_range(_ins)); \
_cmt = g_db_comment_new_inlined(__addr, BLF_HAS_CODE, _txt, false); \
@@ -153,18 +153,18 @@ GDbComment *g_binary_symbol_get_comment(const GBinSymbol *);
_sym = g_binary_symbol_new(STP_DATA); \
g_binary_symbol_attach_instruction(_sym, _ins); \
g_binary_symbol_set_comment(_sym, _cmt); \
- g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym); \
- } \
- while (0)
-
-#define ADD_STR_AS_SYM(_fmt, _sym, _ins) \
- do \
- { \
- _sym = g_binary_symbol_new(STP_RO_STRING); \
- g_binary_symbol_attach_instruction(_sym, _ins); \
- g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym); \
- } \
- while (0)
+ __result = g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym); \
+ __result; \
+ })
+
+#define ADD_STR_AS_SYM(_fmt, _sym, _ins) \
+ ({ \
+ bool __result; \
+ _sym = g_binary_symbol_new(STP_RO_STRING); \
+ g_binary_symbol_attach_instruction(_sym, _ins); \
+ __result = g_binary_format_add_symbol(G_BIN_FORMAT(_fmt), _sym); \
+ __result; \
+ })