diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2015-06-12 23:46:47 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2015-06-12 23:46:47 (GMT) | 
| commit | 04d108111fe7ddd01713b4ca22f8d96961ec2486 (patch) | |
| tree | 72ca086e0db2568bc93acb865b84e29c7d206897 /src | |
| parent | 64aee7b4301e720a7420ab8942ef88f72d7a2c99 (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
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/blocks/flow.c | 24 | ||||
| -rw-r--r-- | src/analysis/blocks/flow.h | 8 | ||||
| -rw-r--r-- | src/analysis/db/cdb.c | 33 | ||||
| -rw-r--r-- | src/analysis/decomp/il.c | 2 | ||||
| -rw-r--r-- | src/analysis/disass/area.c | 21 | ||||
| -rw-r--r-- | src/analysis/disass/disassembler.c | 2 | ||||
| -rw-r--r-- | src/analysis/disass/macro.c | 96 | ||||
| -rw-r--r-- | src/analysis/disass/macro.h | 2 | ||||
| -rw-r--r-- | src/arch/processor.c | 54 | ||||
| -rw-r--r-- | src/format/elf/symbols.c | 6 | ||||
| -rw-r--r-- | src/format/format-int.h | 3 | ||||
| -rw-r--r-- | src/format/format.c | 121 | ||||
| -rw-r--r-- | src/format/format.h | 7 | ||||
| -rw-r--r-- | src/format/symbol.c | 4 | 
14 files changed, 218 insertions, 165 deletions
| 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); | 
