summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-06-12 23:46:47 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-06-12 23:46:47 (GMT)
commit04d108111fe7ddd01713b4ca22f8d96961ec2486 (patch)
tree72ca086e0db2568bc93acb865b84e29c7d206897
parent64aee7b4301e720a7420ab8942ef88f72d7a2c99 (diff)
Improved loading speed with binary search of sorted arrays.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@538 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog39
-rw-r--r--Makefile.am2
-rw-r--r--src/analysis/blocks/flow.c24
-rw-r--r--src/analysis/blocks/flow.h8
-rw-r--r--src/analysis/db/cdb.c33
-rw-r--r--src/analysis/decomp/il.c2
-rw-r--r--src/analysis/disass/area.c21
-rw-r--r--src/analysis/disass/disassembler.c2
-rw-r--r--src/analysis/disass/macro.c96
-rw-r--r--src/analysis/disass/macro.h2
-rw-r--r--src/arch/processor.c54
-rw-r--r--src/format/elf/symbols.c6
-rw-r--r--src/format/format-int.h3
-rw-r--r--src/format/format.c121
-rw-r--r--src/format/format.h7
-rw-r--r--src/format/symbol.c4
16 files changed, 258 insertions, 166 deletions
diff --git a/ChangeLog b/ChangeLog
index c269fa0..42e21d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+15-06-13 Cyrille Bagard <nocbos@gmail.com>
+
+ * Makefile.am:
+ Do not require an Internet connection to build 'revision.h' anymore.
+
+ * src/analysis/blocks/flow.c:
+ * src/analysis/blocks/flow.h:
+ Update code.
+
+ * src/analysis/db/cdb.c:
+ Remove an active wait loop.
+
+ * src/analysis/decomp/il.c:
+ Update code.
+
+ * src/analysis/disass/area.c:
+ Improve loading speed with binary search of sorted arrays.
+
+ * src/analysis/disass/disassembler.c:
+ Update code.
+
+ * src/analysis/disass/macro.c:
+ * src/analysis/disass/macro.h:
+ Update code.
+
+ * src/arch/processor.c:
+ Improve loading speed with binary search of sorted arrays.
+
+ * src/format/elf/symbols.c:
+ Update code.
+
+ * src/format/format.c:
+ * src/format/format.h:
+ * src/format/format-int.h:
+ Improve loading speed with binary search of sorted arrays.
+
+ * src/format/symbol.c:
+ Sort symbols using right values.
+
15-05-15 Cyrille Bagard <nocbos@gmail.com>
* src/gtkext/graph/nodes/flow.c:
diff --git a/Makefile.am b/Makefile.am
index 7357b00..34a6b88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@ BUILT_SOURCES = revision.h
@[ -d $@ ] || touch $@
revision.h: .svn
- @nb=`svn log ChangeLog -l 1 -q | grep r | cut -d ' ' -f 1 | tr -d 'r'` ; \
+ @nb=`LANG=C svn info | grep 'Revision:' | cut -d ' ' -f 2 | tr -d 'r'` ; \
cat $@.in | sed "s/#define REVISION .*$$/#define REVISION $$nb/" > $@ ; \
[ -f $< ] && rm $< || true
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c
index 99d4553..85edad6 100644
--- a/src/analysis/blocks/flow.c
+++ b/src/analysis/blocks/flow.c
@@ -40,7 +40,7 @@ struct _GFlowBlock
unsigned int rank; /* Rang dans l'exécution */
unsigned int next_rank; /* Rang suivant de l'exécution */
- GArchInstruction *instrs; /* Liste complète d'instruct° */
+ GArchProcessor *proc; /* Liste complète d'instruct° */
GArchInstruction *first; /* Première instruction */
GArchInstruction *last; /* Dernière instruction */
@@ -164,7 +164,7 @@ static void g_flow_block_init(GFlowBlock *block)
static void g_flow_block_dispose(GFlowBlock *block)
{
- g_object_unref(G_OBJECT(block->instrs));
+ g_object_unref(G_OBJECT(block->proc));
g_object_unref(G_OBJECT(block->first));
g_object_unref(G_OBJECT(block->last));
@@ -197,9 +197,9 @@ static void g_flow_block_finalize(GFlowBlock *block)
/******************************************************************************
* *
-* Paramètres : instrs = liste de toutes les instructions. *
-* first = première instruction du bloc. *
-* last = dernière instruction du bloc. *
+* Paramètres : proc = liste de toutes les instructions. *
+* first = première instruction du bloc. *
+* last = dernière instruction du bloc. *
* *
* Description : Crée un bloc d'exécution d'instructions. *
* *
@@ -209,17 +209,17 @@ static void g_flow_block_finalize(GFlowBlock *block)
* *
******************************************************************************/
-GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first, GArchInstruction *last)
+GInstrBlock *g_flow_block_new(GArchProcessor *proc, GArchInstruction *first, GArchInstruction *last)
{
GFlowBlock *result; /* Structure à retourner */
result = g_object_new(G_TYPE_FLOW_BLOCK, NULL);
- result->instrs = instrs;
+ result->proc = proc;
result->first = first;
result->last = last;
- g_object_ref(G_OBJECT(result->instrs));
+ g_object_ref(G_OBJECT(result->proc));
g_object_ref(G_OBJECT(result->first));
g_object_ref(G_OBJECT(result->last));
@@ -443,7 +443,7 @@ static void g_flow_block_compute_regs_access(GFlowBlock *block)
for (iter = block->first;
iter != NULL;
- iter = g_arch_instruction_get_next_iter(block->instrs, iter, max))
+ iter = NULL/* FIXME g_arch_instruction_get_next_iter(block->instrs, iter, max)*/)
{
g_arch_instruction_get_location(iter, NULL, NULL, &addr);
@@ -473,7 +473,7 @@ static void g_flow_block_compute_regs_access(GFlowBlock *block)
* *
* Paramètres : block = bloc d'instructions à consulter. *
* *
-* Description : Fournit la liste d'appartenance des instructions du bloc. *
+* Description : Donne le processeur d'appartenance des instructions du bloc. *
* *
* Retour : Liste de l'ensemble des instructions. *
* *
@@ -481,9 +481,9 @@ static void g_flow_block_compute_regs_access(GFlowBlock *block)
* *
******************************************************************************/
-GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *block)
+GArchProcessor *g_flow_block_get_processor(const GFlowBlock *block)
{
- return block->instrs;
+ return block->proc;
}
diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h
index cf8797b..be9c38f 100644
--- a/src/analysis/blocks/flow.h
+++ b/src/analysis/blocks/flow.h
@@ -31,7 +31,7 @@
#include "raccess.h"
#include "../block.h"
-#include "../../arch/instruction.h"
+#include "../../arch/processor.h"
@@ -68,7 +68,7 @@ typedef bool (* flow_block_follow_cb) (GFlowBlock *, BlockFollowPosition, void *
GType g_flow_block_get_type(void);
/* Crée un bloc d'exécution d'instructions. */
-GInstrBlock *g_flow_block_new(GArchInstruction *, GArchInstruction *, GArchInstruction *);
+GInstrBlock *g_flow_block_new(GArchProcessor *, GArchInstruction *, GArchInstruction *);
/* Fournit le rang du bloc dans le flot d'exécution. */
unsigned int g_flow_block_get_rank(const GFlowBlock *);
@@ -76,8 +76,8 @@ unsigned int g_flow_block_get_rank(const GFlowBlock *);
/* Définit le rang du bloc dans le flot d'exécution. */
void g_flow_block_set_rank(GFlowBlock *, unsigned int);
-/* Fournit la liste d'appartenance des instructions du bloc. */
-GArchInstruction *g_flow_block_get_all_instructions_list(const GFlowBlock *);
+/* Donne le processeur d'appartenance des instructions du bloc. */
+GArchProcessor *g_flow_block_get_processor(const GFlowBlock *);
/* Fournit les instructions limites d'un bloc d'exécution. */
void g_flow_block_get_boundary(const GFlowBlock *, GArchInstruction **, GArchInstruction **);
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index b96e0fe..46cfc23 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -96,6 +96,8 @@ struct _GCdbArchive
GMutex clients_access; /* Verrou pour l'accès */
GThread *process; /* Procédure de traitement */
+ GMutex id_access; /* Accès à l'identifiant */
+ GCond id_cond; /* Condition d'attente */
pthread_t process_id; /* Identifiant de la procédure */
};
@@ -201,6 +203,9 @@ static void g_cdb_archive_init(GCdbArchive *archive)
{
g_mutex_init(&archive->clients_access);
+ g_mutex_init(&archive->id_access);
+ g_cond_init(&archive->id_cond);
+
}
@@ -218,6 +223,11 @@ static void g_cdb_archive_init(GCdbArchive *archive)
static void g_cdb_archive_dispose(GCdbArchive *archive)
{
+ g_cond_clear(&archive->id_cond);
+ g_mutex_clear(&archive->id_access);
+
+ g_mutex_clear(&archive->clients_access);
+
G_OBJECT_CLASS(g_cdb_archive_parent_class)->dispose(G_OBJECT(archive));
}
@@ -805,7 +815,10 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
signal(SIGUSR1, interrupt_poll_with_sigusr1);
+ g_mutex_lock(&archive->id_access);
archive->process_id = pthread_self();
+ g_cond_signal(&archive->id_cond);
+ g_mutex_unlock(&archive->id_access);
fds = NULL;
@@ -824,11 +837,11 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
fds[i].events = POLLIN | POLLPRI;
}
+ g_mutex_unlock(&archive->clients_access);
+
if (nfds == 0)
goto gcap_no_more_clients;
- g_mutex_unlock(&archive->clients_access);
-
/* Lancement d'une phase de surveillance */
printf("(%p) POLL %d\n", archive, nfds);
@@ -918,14 +931,14 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
/* On disparaît des écrans... */
- g_mutex_lock(&archive->clients_access);
-
gcap_no_more_clients:
archive->process = NULL;
- archive->process_id = 0;
- g_mutex_unlock(&archive->clients_access);
+ g_mutex_lock(&archive->id_access);
+ archive->process_id = 0;
+ g_cond_signal(&archive->id_cond);
+ g_mutex_unlock(&archive->id_access);
if (fds != NULL)
free(fds);
@@ -980,7 +993,13 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string
archive->process = g_thread_new("cdb_process", (GThreadFunc)g_cdb_archive_process, archive);
/* On attend que le processus parallèle soit prêt */
- for (process_id = &archive->process_id; *process_id == 0; );
+
+ process_id = &archive->process_id;
+
+ g_mutex_lock(&archive->id_access);
+ while (process_id == 0)
+ g_cond_wait(&archive->id_cond, &archive->id_access);
+ g_mutex_unlock(&archive->id_access);
}
else
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c
index 192b0aa..37110f2 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -350,7 +350,7 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
GArchInstruction *iter; /* Boucle de parcours #1 */
GDecInstruction *decomp; /* Dernier résultat de décomp. */
- instrs = g_flow_block_get_all_instructions_list(block);
+ instrs = NULL; // FIXME g_flow_block_get_all_instructions_list(block);
g_flow_block_get_boundary(block, &first, NULL);
g_flow_block_get_boundary_addresses(block, NULL, &max);
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 2e7b46d..6ce9272 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -1553,10 +1553,25 @@ static bool insert_extra_symbol_into_mem_areas(mem_area **list, size_t *count, G
size_t find_memory_area_by_addr(mem_area *list, size_t count, const vmpa2t *addr)
{
size_t result; /* Trouvaille à retourner */
+ mem_area *found; /* Elément trouvé éventuel */
- for (result = 0; result < count; result++)
- if (mrange_contains_addr(&list[result].range, addr))
- break;
+ int find_mem_area(const vmpa2t *addr, const mem_area *area)
+ {
+ int status; /* Bilan à retourner */
+
+ if (mrange_contains_addr(&area->range, addr))
+ status = 0;
+
+ else
+ status = cmp_vmpa(addr, get_mrange_addr(&area->range));
+
+ return status;
+
+ }
+
+ found = bsearch(addr, list, count, sizeof(mem_area), (__compar_fn_t)find_mem_area);
+
+ result = (found != NULL ? found - list : count);
return result;
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index a779dd1..2b518f9 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -397,7 +397,7 @@ G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary)
//qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_rcompare);
- group_routines_instructions(*disass->instrs, routines, routines_count, statusbar, id);
+ group_routines_instructions(proc, routines, routines_count, statusbar, id);
gtk_extended_status_bar_remove(statusbar, id);
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index b478c74..4e77881 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -111,7 +111,7 @@ static bool add_hop_into_branch(branch_info *, const vmpa2t *);
static const vmpa2t *get_entry_to_branch(const branch_info *);
/* Identifie les différents points de passage d'une branche. */
-static void find_next_hops(GArchInstruction *, const vmpa2t *, const code_coverage *, branch_info *);
+static void find_next_hops(GArchProcessor *, const vmpa2t *, const code_coverage *, branch_info *);
/* Retrouve le point de ralliement entre deux branches. */
static bool compute_first_common_addr(const branch_info *, const branch_info *, vmpa2t *);
@@ -170,19 +170,19 @@ static bool compute_first_common_addr_in_group(const branch_group *, vmpa2t *);
/* Procède à la création d'un bloc d'instructions simple. */
-static GInstrBlock *build_instruction_block_simple(GArchInstruction *, code_coverage *, GArchInstruction **, GArchInstruction *);
+static GInstrBlock *build_instruction_block_simple(GArchProcessor *, code_coverage *, GArchInstruction **, GArchInstruction *);
/* Procède à la définition d'un bloc d'instructions selectif. */
-static GInstrBlock *build_instruction_blocks_case(GArchInstruction *, code_coverage *, const branch_group *, vmpa2t *);
+static GInstrBlock *build_instruction_blocks_case(GArchProcessor *, code_coverage *, const branch_group *, vmpa2t *);
/* Procède à la définition d'un bloc d'instruction if/then/else. */
-static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *, code_coverage *, const branch_info *, const branch_info *, vmpa2t *);
+static GInstrBlock *build_instruction_blocks_ite(GArchProcessor *, code_coverage *, const branch_info *, const branch_info *, vmpa2t *);
/* Procède à la définition d'un bloc d'instructions d'exception. */
-static void add_instruction_blocks_except(GInstrBlock **, GInstrBlock **, GArchInstruction *, code_coverage *, const branch_group *, const branch_info *);
+static void add_instruction_blocks_except(GInstrBlock **, GInstrBlock **, GArchProcessor *, code_coverage *, const branch_group *, const branch_info *);
/* Procède à la définition de bloc regroupant des instructions. */
-static GInstrBlock *build_instruction_blocks(GArchInstruction *, code_coverage *);
+static GInstrBlock *build_instruction_blocks(GArchProcessor *, code_coverage *);
@@ -581,7 +581,7 @@ static const vmpa2t *get_entry_to_branch(const branch_info *info)
/******************************************************************************
* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
+* Paramètres : proc = ensemble des instructions d'assemblage. *
* start = position du début de bloc. *
* coverage = liste des adresses de fin butoir. *
* count = nombre de sauts détectés. [OUT] *
@@ -594,7 +594,7 @@ static const vmpa2t *get_entry_to_branch(const branch_info *info)
* *
******************************************************************************/
-static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const code_coverage *coverage, branch_info *info)
+static void find_next_hops(GArchProcessor *proc, const vmpa2t *start, const code_coverage *coverage, branch_info *info)
{
GArchInstruction *iter; /* Boucle de parcours #1 */
const mrange_t *range; /* Emplacement d'instruction */
@@ -619,9 +619,9 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
printf(" ++ add 0x%08x\n", (unsigned int)start->virtual);
/* On suit le flot jusqu'à la prochaine bifurcation */
- for (iter = g_arch_instruction_find_by_address(instrs, start, true);
+ for (iter = g_arch_processor_find_instr_by_address(proc, start);
iter != NULL;
- iter = g_arch_instruction_get_next_iter(instrs, iter, VMPA_MAX))
+ iter = g_arch_processor_get_next_instr(proc, iter))
{
range = g_arch_instruction_get_range(iter);
@@ -673,7 +673,7 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
case ILT_CASE_JUMP:
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- find_next_hops(instrs, get_mrange_addr(range), coverage, info);
+ find_next_hops(proc, get_mrange_addr(range), coverage, info);
break;
case ILT_LOOP:
@@ -877,7 +877,7 @@ static bool compute_first_common_addr_in_group(const branch_group *group, vmpa2t
/******************************************************************************
* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
+* Paramètres : proc = ensemble des instructions d'assemblage. *
* coverage = délimitations de la zone à couvrir. *
* first = première instruction d'un bloc préliminaire. *
* cur = instruction courante dans le traitement. *
@@ -890,13 +890,13 @@ static bool compute_first_common_addr_in_group(const branch_group *group, vmpa2t
* *
******************************************************************************/
#include "../../arch/instruction-int.h"
-static GInstrBlock *build_instruction_block_simple(GArchInstruction *instrs, code_coverage *coverage, GArchInstruction **first, GArchInstruction *cur)
+static GInstrBlock *build_instruction_block_simple(GArchProcessor *proc, code_coverage *coverage, GArchInstruction **first, GArchInstruction *cur)
{
GInstrBlock *result; /* Regroupement à retourner */
if (*first != NULL)
{
- result = g_flow_block_new(instrs, *first, cur);
+ result = g_flow_block_new(proc, *first, cur);
mark_range_as_processed_in_coverage(coverage, *first);
@@ -912,7 +912,7 @@ static GInstrBlock *build_instruction_block_simple(GArchInstruction *instrs, cod
/******************************************************************************
* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
+* Paramètres : proc = ensemble des instructions d'assemblage. *
* coverage = délimitations de la zone à couvrir. *
* cases = branches conditionnelles des situations. *
* next = localisation de l'instruction de reprise. *
@@ -925,7 +925,7 @@ static GInstrBlock *build_instruction_block_simple(GArchInstruction *instrs, cod
* *
******************************************************************************/
-static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code_coverage *coverage, const branch_group *cases, vmpa2t *next)
+static GInstrBlock *build_instruction_blocks_case(GArchProcessor *proc, code_coverage *coverage, const branch_group *cases, vmpa2t *next)
{
GInstrBlock *result; /* Regroupement à retourner */
bool has_common; /* Fin commune ? */
@@ -948,7 +948,7 @@ static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code
for (j = 0; j < cases->count; j++)
add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(&cases->branches[j]));
- block = build_instruction_blocks(instrs, sub_coverage);
+ block = build_instruction_blocks(proc, sub_coverage);
if (block != NULL)
g_virtual_block_add_child(G_VIRTUAL_BLOCK(result), block);
@@ -970,7 +970,7 @@ static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code
/******************************************************************************
* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
+* Paramètres : proc = ensemble des instructions d'assemblage. *
* coverage = délimitations de la zone à couvrir. *
* true_branch = branche conditionnelle correspondant à true. *
* false_branch = branche conditionnelle correspondant à false. *
@@ -984,7 +984,7 @@ static GInstrBlock *build_instruction_blocks_case(GArchInstruction *instrs, code
* *
******************************************************************************/
-static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_coverage *coverage, const branch_info *true_branch, const branch_info *false_branch, vmpa2t *next)
+static GInstrBlock *build_instruction_blocks_ite(GArchProcessor *proc, code_coverage *coverage, const branch_info *true_branch, const branch_info *false_branch, vmpa2t *next)
{
GInstrBlock *result; /* Regroupement à retourner */
bool has_common; /* Fin commune ? */
@@ -1005,7 +1005,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
_sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(true_branch));
- block = build_instruction_blocks(instrs, _sub_coverage);
+ block = build_instruction_blocks(proc, _sub_coverage);
delete_code_coverage(_sub_coverage);
@@ -1018,7 +1018,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
_sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(false_branch));
- block = build_instruction_blocks(instrs, _sub_coverage);
+ block = build_instruction_blocks(proc, _sub_coverage);
delete_code_coverage(_sub_coverage);
@@ -1053,7 +1053,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
* Encapsulation des branches conditionnelles.
*/
- GInstrBlock *build_instr_block_bi(GArchInstruction *instrs, const code_coverage *coverage, const branch_info *br0, const branch_info *br1, const vmpa2t *next)
+ GInstrBlock *build_instr_block_bi(GArchProcessor *proc, const code_coverage *coverage, const branch_info *br0, const branch_info *br1, const vmpa2t *next)
{
GInstrBlock *result; /* Bloc construit à renvoyer */
code_coverage *sub_coverage; /* Couverture pour les suivants*/
@@ -1069,7 +1069,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
if (br1->count > 0)
add_ending_address_code_coverage(sub_coverage, get_entry_to_branch(br1));
- result = build_instruction_blocks(instrs, sub_coverage);
+ result = build_instruction_blocks(proc, sub_coverage);
delete_code_coverage(sub_coverage);
@@ -1081,7 +1081,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
/* Branche 'true' */
- block = build_instr_block_bi(instrs, coverage, true_branch, false_branch, next);
+ block = build_instr_block_bi(proc, coverage, true_branch, false_branch, next);
printf("===> TRUE_BRANCH = %p\n", block);
@@ -1090,7 +1090,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
/* Branche 'false' */
- block = build_instr_block_bi(instrs, coverage, false_branch, true_branch, next);
+ block = build_instr_block_bi(proc, coverage, false_branch, true_branch, next);
printf("===> FALSE_BRANCH = %p\n", block);
@@ -1114,7 +1114,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
* *
* Paramètres : result = liste générale résultante du découpage. [OUT] *
* cached = emplacement pour le cache des résultats. [OUT] *
-* instrs = ensemble des instructions d'assemblage. *
+* proc = ensemble des instructions d'assemblage. *
* coverage = délimitations de la zone à couvrir. *
* exceptions = branche conditionnelle correspondant à true. *
* main_branch = branche principale avec son flot d'exécution. *
@@ -1127,7 +1127,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
* *
******************************************************************************/
-static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **cached, GArchInstruction *instrs, code_coverage *coverage, const branch_group *exceptions, const branch_info *main_branch)
+static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **cached, GArchProcessor *proc, code_coverage *coverage, const branch_group *exceptions, const branch_info *main_branch)
{
size_t i; /* Boucle de parcours */
vmpa2t stop_addr; /* Adresse de fin de bloc */
@@ -1143,7 +1143,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca
sub_coverage = dup_code_coverage(coverage, get_entry_to_branch(&exceptions->branches[i]));
add_ending_address_code_coverage(sub_coverage, &stop_addr);
- block = build_instruction_blocks(instrs, sub_coverage);
+ block = build_instruction_blocks(proc, sub_coverage);
if (block != NULL)
DELAYED_BLOCK_ADDING(*result, *cached, block);
@@ -1157,7 +1157,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca
/******************************************************************************
* *
-* Paramètres : instrs = ensemble des instructions d'assemblage. *
+* Paramètres : proc = ensemble des instructions d'assemblage. *
* coverage = délimitations de la zone à couvrir. *
* *
* Description : Procède à la définition de bloc regroupant des instructions. *
@@ -1168,7 +1168,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca
* *
******************************************************************************/
#include "../../arch/instruction-int.h"
-static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_coverage *coverage)
+static GInstrBlock *build_instruction_blocks(GArchProcessor *proc, code_coverage *coverage)
{
GInstrBlock *result; /* Regroupement à retourner */
GInstrBlock *result_cached; /* Temporisation pour unicité */
@@ -1199,17 +1199,17 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
last = NULL;
init_branch_info(&main_branch);
- find_next_hops(instrs, get_code_coverage_start_addr(coverage), coverage, &main_branch);
+ find_next_hops(proc, get_code_coverage_start_addr(coverage), coverage, &main_branch);
printf("//////////////////////////\n");
printf("/// Cutting for 0x%08x -> %p\n",
get_code_coverage_start_addr(coverage)->virtual,
- g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true));
+ g_arch_processor_find_instr_by_address(proc, get_code_coverage_start_addr(coverage)));
printf("//////////////////////////\n");
- for (iter = g_arch_instruction_find_by_address(instrs, get_code_coverage_start_addr(coverage), true);
+ for (iter = g_arch_processor_find_instr_by_address(proc, get_code_coverage_start_addr(coverage));
iter != NULL;
)
{
@@ -1236,7 +1236,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* On n'approfondit que les chemins qui se séparent */
if (!g_arch_instruction_has_destinations(iter))
{
- iter = g_arch_instruction_get_next_iter(instrs, iter, VMPA_MAX);
+ iter = g_arch_processor_get_next_instr(proc, iter);
continue;
}
@@ -1268,7 +1268,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
_saved0 = first;
- block = build_instruction_block_simple(instrs, coverage, &first, iter);
+ block = build_instruction_block_simple(proc, coverage, &first, iter);
printf(" -- simple block JMP -- @ 0x%08x <-> 0x%08x\n",
(unsigned int)(_saved0 ? _saved0->range.addr.virtual : ~0),
(unsigned int)iter->range.addr.virtual);
@@ -1349,7 +1349,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
printf("BUILD @ 0x%08x\n", (unsigned int)addr->virtual);
- find_next_hops(instrs, addr, coverage, branch);
+ find_next_hops(proc, addr, coverage, branch);
printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
}
@@ -1359,10 +1359,10 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* Post-traitements de ILT_CASE_JUMP */
if (cases_branches.count > 0)
{
- block = build_instruction_block_simple(instrs, coverage, &first, iter);
+ block = build_instruction_block_simple(proc, coverage, &first, iter);
DELAYED_BLOCK_ADDING(result, result_cached, block);
- group = build_instruction_blocks_case(instrs, coverage, &cases_branches, &next_addr);
+ group = build_instruction_blocks_case(proc, coverage, &cases_branches, &next_addr);
if (group != NULL)
{
@@ -1375,7 +1375,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* Post-traitements de ILT_JUMP_IF_TRUE / ILT_JUMP_IF_FALSE */
else if (true_branch.count > 0 || false_branch.count > 0)
{
- block = build_instruction_block_simple(instrs, coverage, &first, iter);
+ block = build_instruction_block_simple(proc, coverage, &first, iter);
GArchInstruction *_saved1;
@@ -1391,7 +1391,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
fflush(NULL);
DELAYED_BLOCK_ADDING(result, result_cached, block);
- group = build_instruction_blocks_ite(instrs, coverage, &true_branch, &false_branch, &next_addr);
+ group = build_instruction_blocks_ite(proc, coverage, &true_branch, &false_branch, &next_addr);
printf(" --> group = %p - next = 0x%08x\n", group, next_addr.virtual);
@@ -1406,10 +1406,10 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* Post-traitements de ILT_CATCH_EXCEPTION */
if (excep_branches.count > 0)
{
- block = build_instruction_block_simple(instrs, coverage, &first, iter);
+ block = build_instruction_block_simple(proc, coverage, &first, iter);
if (block != NULL) DELAYED_BLOCK_ADDING(result, result_cached, block);
- add_instruction_blocks_except(&result, &result_cached, instrs, coverage,
+ add_instruction_blocks_except(&result, &result_cached, proc, coverage,
&excep_branches, &main_branch);
}
@@ -1422,9 +1422,9 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/* Détermination du prochain point de chute */
if (not_handled == dcount)
- iter = g_arch_instruction_get_next_iter(instrs, iter, VMPA_MAX);
+ iter = g_arch_processor_get_next_instr(proc, iter);
else
- iter = g_arch_instruction_find_by_address(instrs, &next_addr, true);
+ iter = g_arch_processor_find_instr_by_address(proc, &next_addr);
}
@@ -1434,7 +1434,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
if (!is_range_processed_in_coverage(coverage, range))
{
- block = build_instruction_block_simple(instrs, coverage, &first, last);
+ block = build_instruction_block_simple(proc, coverage, &first, last);
DELAYED_BLOCK_ADDING(result, result_cached, block);
}
@@ -1449,7 +1449,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
/******************************************************************************
* *
-* Paramètres : list = ensemble d'instructions à relier. *
+* Paramètres : proc = processeur rassemblant les instructions à relier.*
* routines = prototypes existants à insérer. *
* count = quantité de ces prototypes. *
* statusbar = barre de statut avec progression à mettre à jour.*
@@ -1463,7 +1463,7 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
* *
******************************************************************************/
-void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+void group_routines_instructions(GArchProcessor *proc, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
{
size_t i; /* Boucle de parcours */
const mrange_t *range; /* Emplacement de routine */
@@ -1478,7 +1478,7 @@ void group_routines_instructions(GArchInstruction *list, GBinRoutine **routines,
coverage = create_code_coverage(range);
- block = build_instruction_blocks(list, coverage);
+ block = build_instruction_blocks(proc, coverage);
g_binary_routine_set_basic_blocks(routines[i], block);
diff --git a/src/analysis/disass/macro.h b/src/analysis/disass/macro.h
index 82185bb..2c03520 100644
--- a/src/analysis/disass/macro.h
+++ b/src/analysis/disass/macro.h
@@ -32,7 +32,7 @@
/* Regroupe les instructions par blocs. */
-void group_routines_instructions(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
+void group_routines_instructions(GArchProcessor *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 25a38b4..2c86ffe 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -381,62 +381,22 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc
GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr)
{
GArchInstruction *result; /* Trouvaille à retourner */
- GArchInstruction *fake; /* Coquille vide à comparer */
void *ptr; /* Résultat des recherches */
- size_t i; /* Boucle de parcours */
- const mrange_t *range; /* Emplacement d'instruction */
- if (has_phys_addr(addr))
+ int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b)
{
- fake = g_raw_instruction_new_from_value(addr, MDS_8_BITS_UNSIGNED, 0);
+ const mrange_t *range_b; /* Emplacement pour l'instr. B */
- int search_for_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
- {
- const mrange_t *range_a; /* Emplacement pour l'instr. A */
- const mrange_t *range_b; /* Emplacement pour l'instr. B */
-
- range_a = g_arch_instruction_get_range(*a);
- range_b = g_arch_instruction_get_range(*b);
-
- /*
- printf(" -- cmp -- 0x%08x vs 0x%08x => %d\n",
- (unsigned int)range_a->addr.virtual,
- (unsigned int)range_b->addr.virtual,
- cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b)));
- */
+ range_b = g_arch_instruction_get_range(*b);
- return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b));
-
- }
-
- ptr = bsearch(&fake, proc->instructions, proc->instr_count,
- sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr);
-
- g_object_unref(G_OBJECT(fake));
-
- result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
+ return cmp_vmpa(a, get_mrange_addr(range_b));
}
- else
- {
- result = NULL;
-
- for (i = 0; i < proc->instr_count && result == NULL; i++)
- {
- range = g_arch_instruction_get_range(proc->instructions[i]);
-
- if (cmp_vmpa(addr, get_mrange_addr(range)) == 0)
- result = proc->instructions[i];
+ ptr = bsearch(addr, proc->instructions, proc->instr_count,
+ sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr);
- }
-
- /*
- for (i = 0; i < proc->instr_count; i++)
- printf(" # %04zu 0x%08x\n", i, proc->instructions[i]->range.addr.virtual);
- */
-
- }
+ result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
return result;
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index 04ba3de..655eda1 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -137,6 +137,8 @@ bool load_elf_symbols(GElfFormat *format)
result &= load_all_elf_basic_entry_points(format);
+ g_binary_format_sort_symbols(G_BIN_FORMAT(format));
+
return result;
}
@@ -201,7 +203,7 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0);
g_binary_symbol_attach_routine(symbol, routine);
- g_binary_format_add_symbol(base, symbol);
+ _g_binary_format_add_symbol(base, symbol, false);
}
@@ -632,7 +634,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
}
if (symbol != NULL)
- g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+ _g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol, false);
}
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 96ff081..340264a 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -50,9 +50,12 @@ struct _GBinFormat
GBinSymbol **symbols; /* Liste des symboles trouvés */
size_t symbols_count; /* Quantité de ces symboles */
+ GRWLock syms_lock; /* Accès à la liste de symboles*/
+ gint unsorted_symbols; /* Etat du tri des symboles */
GBinRoutine **routines; /* Liste des routines trouvées */
size_t routines_count; /* Nombre de ces routines */
+ bool unsorted_routines; /* Etat du tri des routines */
const char **src_files; /* Nom des fichiers source */
size_t src_count; /* Taille de la liste */
diff --git a/src/format/format.c b/src/format/format.c
index c1877d2..3373af3 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -90,10 +90,19 @@ static void g_binary_format_class_init(GBinFormatClass *klass)
static void g_binary_format_init(GBinFormat *format)
{
+ g_rw_lock_init(&format->syms_lock);
+ g_atomic_int_set(&format->unsorted_symbols, false);
+
+ format->unsorted_routines = false;
}
+
+/* FIXME : g_rw_lock_clear(&format->syms_lock);*/
+
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
@@ -181,6 +190,7 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
* *
* Paramètres : format = informations chargées à compléter. *
* symbol = symbole à ajouter à la liste. *
+* sort = fait état d'un obligation de tri final. *
* *
* Description : Ajoute un symbole à la collection du format binaire. *
* *
@@ -190,15 +200,17 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
* *
******************************************************************************/
-void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
+void _g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol, bool sort)
{
+
+ g_rw_lock_writer_lock(&format->syms_lock);
+
format->symbols = (GBinSymbol **)realloc(format->symbols,
++format->symbols_count * sizeof(GBinSymbol *));
format->symbols[format->symbols_count - 1] = symbol;
- qsort(format->symbols, format->symbols_count,
- sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp);
+ g_atomic_int_set(&format->unsorted_symbols, true);
switch (g_binary_symbol_get_target_type(symbol))
{
@@ -209,9 +221,8 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
++format->routines_count * sizeof(GBinRoutine *));
format->routines[format->routines_count - 1] = g_binary_symbol_get_routine(symbol);
-
- qsort(format->routines, format->routines_count,
- sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare);
+
+ format->unsorted_routines = true;
break;
@@ -220,6 +231,11 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
}
+ g_rw_lock_writer_unlock(&format->syms_lock);
+
+ if (sort)
+ g_binary_format_sort_symbols(format);
+
}
@@ -315,6 +331,43 @@ void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol)
/******************************************************************************
* *
+* Paramètres : format = informations chargées à arranger. *
+* *
+* Description : Réorganise si besoin est les symboles collectés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_binary_format_sort_symbols(GBinFormat *format)
+{
+ if (g_atomic_int_compare_and_exchange(&format->unsorted_symbols, true, false))
+ {
+ g_rw_lock_writer_lock(&format->syms_lock);
+
+ qsort(format->symbols, format->symbols_count,
+ sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp);
+
+ if (format->unsorted_routines)
+ {
+ qsort(format->routines, format->routines_count,
+ sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare);
+
+ format->unsorted_routines = false;
+
+ }
+
+ g_rw_lock_writer_unlock(&format->syms_lock);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à consulter. *
* count = taille du tableau créé. [OUT] *
* *
@@ -477,25 +530,32 @@ bool g_binary_format_find_symbol_by_label(const GBinFormat *format, const char *
bool g_binary_format_find_symbol_at(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol)
{
bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- const mrange_t *range; /* Espace mémoire parcouru */
+ void *found; /* Résultat de recherches */
result = false;
*symbol = NULL; /* TODO : vérifier les doublons côtés appelants */
- for (i = 0; i < format->symbols_count && !result; i++)
+ int find_symbol(const vmpa2t *addr, const GBinSymbol **sym)
{
- range = g_binary_symbol_get_range(format->symbols[i]);
+ const mrange_t *range; /* Espace mémoire parcouru */
- if (cmp_vmpa(get_mrange_addr(range), addr) == 0)
- {
- *symbol = format->symbols[i];
- g_object_ref(G_OBJECT(*symbol));
+ range = g_binary_symbol_get_range(*sym);
- result = true;
+ return cmp_vmpa_by_virt(addr, get_mrange_addr(range));
- }
+ }
+
+ found = bsearch(addr, format->symbols,
+ format->symbols_count, sizeof(GBinSymbol *),
+ (__compar_fn_t)find_symbol);
+
+ if (found != NULL)
+ {
+ *symbol = *(GBinSymbol **)found;
+
+ g_object_ref(G_OBJECT(*symbol));
+ result = true;
}
@@ -565,29 +625,16 @@ bool g_binary_format_find_next_symbol_at(const GBinFormat *format, const vmpa2t
bool g_binary_format_resolve_symbol(const GBinFormat *format, const vmpa2t *addr, GBinSymbol **symbol, phys_t *diff)
{
- bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- const mrange_t *range; /* Espace mémoire parcouru */
+ bool result; /* Bilan à retourner */
+ const mrange_t *range; /* Espace mémoire parcouru */
- result = false;
-
- //for (i = 0; i < format->symbols_count && !result; i++)
- for (i = format->symbols_count; i > 0 && !result; i--)
- {
- range = g_binary_symbol_get_range(format->symbols[i - 1]);
+ result = g_binary_format_find_symbol_at(format, addr, symbol);
- if (mrange_contains_addr(range, addr))
- {
- *symbol = format->symbols[i - 1];
- g_object_ref(G_OBJECT(*symbol));
-
- *diff = compute_vmpa_diff(get_mrange_addr(range), addr);
-
- result = true;
-
- }
-
- }
+ if (result)
+ {
+ range = g_binary_symbol_get_range(*symbol);
+ *diff = compute_vmpa_diff(get_mrange_addr(range), addr);
+ }
return result;
diff --git a/src/format/format.h b/src/format/format.h
index 807e328..51c542f 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -65,11 +65,16 @@ GBinContent *g_binary_format_get_conten_(const GBinFormat *);
void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContext *);
/* Ajoute un symbole à la collection du format binaire. */
-void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
+void _g_binary_format_add_symbol(GBinFormat *, GBinSymbol *, bool);
+
+#define g_binary_format_add_symbol(fmt, sym) _g_binary_format_add_symbol(fmt, sym, true)
/* Retire un symbole de la collection du format binaire. */
void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
+/* Réorganise si besoin est les symboles collectés. */
+void g_binary_format_sort_symbols(GBinFormat *);
+
/* Fournit la liste de tous les symboles détectés. */
GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
diff --git a/src/format/symbol.c b/src/format/symbol.c
index c867b68..f676e9e 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -177,7 +177,9 @@ int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b)
aa = get_mrange_addr(ra);
ab = get_mrange_addr(rb);
- result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0);
+ result = cmp_vmpa_by_virt(aa, ab);
+
+ //result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0);
///result = cmp_mrange(ra, rb);
//printf(" ?? 0x%08lx vs 0x%08lx -> %d\n", aa->virtual, ab->virtual, result);