diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2014-09-17 21:36:49 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2014-09-17 21:36:49 (GMT) | 
| commit | 65768127dea4c2760fe07cf843da7b4ad9e67da5 (patch) | |
| tree | d0023eb7f378a4118fd074f3f61d5eae02e0882b /src/arch | |
| parent | af083f8bd6da340214ae392451dde5782fb79039 (diff) | |
Introduced memory ranges.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@406 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/instruction-int.h | 7 | ||||
| -rw-r--r-- | src/arch/instruction.c | 25 | ||||
| -rw-r--r-- | src/arch/instruction.h | 10 | ||||
| -rw-r--r-- | src/arch/raw.c | 11 | ||||
| -rw-r--r-- | src/arch/vmpa.c | 231 | ||||
| -rw-r--r-- | src/arch/vmpa.h | 59 | 
6 files changed, 292 insertions, 51 deletions
| diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 28caf78..958a5bd 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -55,12 +55,19 @@ struct _GArchInstruction      DL_LIST_ITEM(flow);                     /* Maillon de liste chaînée    */ +    mrange_t range;                         /* Emplacement en mémoire      */ + +    /* ------- %< ----------- */ +      vmpa2t address2;                         /* Position associée           */      off_t offset;                           /* Position physique de départ */      off_t length;                           /* Taille de l'instruction     */      vmpa_t address;                         /* Position associée           */ +    /* ------- %< ----------- */ + +      GArchOperand **operands;                /* Liste des opérandes         */      size_t operands_count;                  /* Nbre. d'opérandes utilisées */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index ea713cd..402b0f5 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -159,15 +159,9 @@ static void g_arch_instruction_finalize(GArchInstruction *instr)  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *address, off_t length) +void g_arch_instruction_set_range(GArchInstruction *instr, const mrange_t *range)  { -    copy_vmpa(&instr->address2, address); - -    /* FIXME */ -    instr->offset = get_phy_addr(address); -    instr->address = get_virt_addr(address); - -    instr->length = length; +    copy_mrange(&instr->range, range);  } @@ -175,23 +169,18 @@ void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *addr  /******************************************************************************  *                                                                             *  *  Paramètres  : instr   = instruction quelconque à consulter.                * -*                offset  = position physique dans le code binaire/NULL. [OUT] * -*                length  = taille de l'instruction ou NULL. [OUT]             * -*                address = adresse virtuelle ou position physique/NULL. [OUT] *  *                                                                             * -*  Description : Fournit la localisation d'une instruction.                   * +*  Description : Fournit la place mémoire d'une instruction.                  *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Zone mémoire couverte par l'instruction.                     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *instr, off_t *length) +const mrange_t *g_arch_instruction_get_range(const GArchInstruction *instr)  { -    if (length != NULL) *length = instr->length; - -    return &instr->address2; +    return &instr->range;  } @@ -699,7 +688,7 @@ static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCo      size_t klen;                            /* Taille de ce mot clef       */      size_t i;                               /* Boucle de parcours          */ -    result = g_code_buffer_append_new_line(buffer, &instr->address2); +    result = g_code_buffer_append_new_line(buffer, &instr->range);      g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->length, true); diff --git a/src/arch/instruction.h b/src/arch/instruction.h index f04a458..4fe0569 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -57,18 +57,18 @@ typedef struct _GArchInstructionClass GArchInstructionClass;  GType g_arch_instruction_get_type(void);  /* Définit la localisation d'une instruction. */ -void g_arch_instruction_set_location(GArchInstruction *, const vmpa2t *, off_t); +void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *); - - -/* Fournit la localisation d'une instruction. */ -const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *, off_t *); +/* Fournit la place mémoire d'une instruction. */ +const mrange_t *g_arch_instruction_get_range(const GArchInstruction *);  /* Fournit la localisation d'une instruction. */  void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, vmpa_t *); + +  /* Attache un opérande supplémentaire à une instruction. */  void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *); diff --git a/src/arch/raw.c b/src/arch/raw.c index 842c2b4..e127f91 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -187,16 +187,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)  GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian)  {      GArchInstruction *result;               /* Instruction à retourner     */ -    vmpa2t *old;                            /* Sauvegarde de la position   */ +    vmpa2t old;                             /* Sauvegarde de la position   */      size_t i;                               /* Boucle de parcours          */      GArchOperand *operand;                  /* Octet non décodé à afficher */ +    mrange_t range;                         /* Couverture de l'instruction */      /* Par soucis de cohérence */      if (count == 0) return NULL;      result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); -    old = dup_vmpa(addr); +    copy_vmpa(&old, addr);      for (i = 0; i < count; i++)      { @@ -208,9 +209,9 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize          g_arch_instruction_attach_extra_operand(result, operand);      } -    g_arch_instruction_set_location(result, old, compute_vmpa_diff(addr, old)); +    init_mrange(&range, &old, compute_vmpa_diff(addr, &old)); -    delete_vmpa(old); +    g_arch_instruction_set_range(result, &range);      return result; @@ -251,7 +252,7 @@ static GBufferLine *g_raw_instruction_print(const GRawInstruction *instr, GCodeB      else      { -        result = g_code_buffer_append_new_line(buffer, &base->address2); +        result = g_code_buffer_append_new_line(buffer, &base->range);          g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->length, true); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index c3cf17e..6f305fb 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -34,9 +34,14 @@ +/* ---------------------------------------------------------------------------------- */ +/*                        DEFINITION D'UNE POSITION EN MEMOIRE                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : addr = élément à initialiser.                                * +*  Paramètres  : addr = élément à initialiser. [OUT]                          *  *                phy  = position dans la mémoire physique.                    *  *                virt = adresse dans la mémoire virtuelle.                    *  *                                                                             * @@ -48,7 +53,7 @@  *                                                                             *  ******************************************************************************/ -void init_vmpa(vmpa2t *addr, off_t phy, uint64_t virt) +void init_vmpa(vmpa2t *addr, phys_t phy, virt_t virt)  {      addr->physical = phy;      addr->virtual = virt; @@ -69,7 +74,7 @@ void init_vmpa(vmpa2t *addr, off_t phy, uint64_t virt)  *                                                                             *  ******************************************************************************/ -vmpa2t *make_vmpa(off_t phy, uint64_t virt) +vmpa2t *make_vmpa(phys_t phy, virt_t virt)  {      vmpa2t *result;                         /* Structure à retourner       */ @@ -212,7 +217,6 @@ int cmp_vmpa(const vmpa2t *a, const vmpa2t *b)  } -  /******************************************************************************  *                                                                             *  *  Paramètres  : addr = élément à modifier.                                   * @@ -226,7 +230,7 @@ int cmp_vmpa(const vmpa2t *a, const vmpa2t *b)  *                                                                             *  ******************************************************************************/ -void advance_vmpa(vmpa2t *addr, off_t qty) +void advance_vmpa(vmpa2t *addr, phys_t qty)  {      if (addr->physical != VMPA_NO_PHYSICAL)          addr->physical += qty; @@ -250,9 +254,9 @@ void advance_vmpa(vmpa2t *addr, off_t qty)  *                                                                             *  ******************************************************************************/ -off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) +phys_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b)  { -    off_t result;                           /* Valeur à retourner          */ +    phys_t result;                          /* Valeur à retourner          */      result = VMPA_NO_PHYSICAL; @@ -260,7 +264,7 @@ off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b)          result = (b->physical > a->physical ? b->physical - a->physical : a->physical- b->physical);      else if (a->virtual != VMPA_NO_VIRTUAL && b->virtual != VMPA_NO_VIRTUAL) -        result = (off_t)(b->virtual > a->virtual ? b->virtual - a->virtual : a->virtual- b->virtual); +        result = (phys_t)(b->virtual > a->virtual ? b->virtual - a->virtual : a->virtual- b->virtual);      return result; @@ -283,15 +287,15 @@ off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b)  bool recv_vmpa(vmpa2t *addr, int fd, int flags)  { -    uint64_t val64;                         /* Valeur sur 64 bits          */ +    virt_t val64;                           /* Valeur sur 64 bits          */      bool status;                            /* Bilan d'une réception       */ -    status = safe_recv(fd, &val64, sizeof(uint64_t), flags); +    status = safe_recv(fd, &val64, sizeof(virt_t), flags);      if (!status) return false;      addr->physical = be64toh(val64); -    status = safe_recv(fd, &val64, sizeof(uint64_t), flags); +    status = safe_recv(fd, &val64, sizeof(virt_t), flags);      if (!status) return false;      addr->virtual = be64toh(val64); @@ -319,10 +323,10 @@ bool send_vmpa(const vmpa2t *addr, int fd, int flags)  {      bool status;                            /* Bilan d'une émission        */ -    status = safe_send(fd, (uint64_t []) { htobe64(addr->physical) }, sizeof(uint64_t), flags); +    status = safe_send(fd, (virt_t []) { htobe64(addr->physical) }, sizeof(virt_t), flags);      if (!status) return false; -    status = safe_send(fd, (uint64_t []) { htobe64(addr->virtual) }, sizeof(uint64_t), flags); +    status = safe_send(fd, (virt_t []) { htobe64(addr->virtual) }, sizeof(virt_t), flags);      if (!status) return false;      return true; @@ -446,7 +450,7 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer  vmpa2t *string_to_vmpa_phy(const char *buffer)  { -    off_t physical;                         /* Position à retrouver        */ +    phys_t physical;                        /* Position à retrouver        */      physical = strtoull(buffer, NULL, 16); @@ -469,10 +473,207 @@ vmpa2t *string_to_vmpa_phy(const char *buffer)  vmpa2t *string_to_vmpa_virt(const char *buffer)  { -    uint64_t virtual;                       /* Adresse à retrouver         */ +    virt_t virtual;                         /* Adresse à retrouver         */      virtual = strtoull(buffer, NULL, 16);      return make_vmpa(VMPA_NO_PHYSICAL, virtual);  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                          DEFINITION D'UNE ZONE EN MEMOIRE                          */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : range  = plage à initialiser. [OUT]                          * +*                addr   = position de départ dans la mémoire.                 * +*                length = taille de la plage à constituer.                    * +*                                                                             * +*  Description : Initialise une plage dans l'espace mémoire/physique.         * +*                                                                             * +*  Retour      : Place définie en mémoire.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void init_mrange(mrange_t *range, const vmpa2t *addr, phys_t length) +{ +    copy_vmpa(&range->addr, addr); + +    range->length = length; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : dest = structure de destination pour la copie.               * +*                src  = structure de source pour la copie.                    * +*                                                                             * +*  Description : Copie la définition d'une plage mémoire dans une autre.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void copy_mrange(mrange_t *dest, const mrange_t *src) +{ +    copy_vmpa(&dest->addr, &src->addr); + +    dest->length = src->length; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = première définition à analyser.                          * +*                b = seconde définition à analyser.                           * +*                                                                             * +*  Description : Compare deux couvertures mémoire selon leurs propriétés.     * +*                                                                             * +*  Retour      : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut).        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int cmp_mrange(const mrange_t *a, const mrange_t *b) +{ +    int result;                             /* Bilan à retourner           */ + +    result = cmp_vmpa(&a->addr, &b->addr); + +    if (result == 0) +    { +        if (a->length < b->length) +            result = -1; +        else if (a->length > b->length) +            result = 1; +        else +            result = 0; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : range = zone mémoire à consulter.                            * +*                addr  = localisation mémoire à analyser.                     * +*                                                                             * +*  Description : Indique si une localisation est incluse dans une zone ou non.* +*                                                                             * +*  Retour      : Bilan de la consultation.                                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) +{ +    bool result;                            /* Bilan à retourner           */ +    int ret;                                /* Bilan d'une comparaison     */ +    phys_t diff;                            /* Espace entre deux adresses  */ + +    ret = cmp_vmpa(&range->addr, addr); + +    if (ret <= -1) +    { +        diff = compute_vmpa_diff(&range->addr, addr); +        result = (diff < range->length); +    } + +    else if (ret == 0) +        result = true; + +    else +        result = false; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : rane   = emplacement virtuel ou physique à traiter.          * +*                msize  = taille de cette adresse, réelle ou désirée.         * +*                start  = indique si le début ou la fin est à imprimer.       * +*                buffer = tampon de sortie utilisé à constituer. [OUT]        * +*                length = transmission de la taille du résultat ou NULL. [OUT]* +*                                                                             * +*  Description : Transforme un emplacement physique en chaîne de caractères.  * +*                                                                             * +*  Retour      : Chaîne de caractères constituée.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *mrange_phys_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) +{ +    vmpa2t tmp; + +    if (start) +        vmpa2_phys_to_string(&range->addr, msize, buffer, length); + +    else +    { +        copy_vmpa(&tmp, &range->addr); +        advance_vmpa(&tmp, range->length); + +        vmpa2_phys_to_string(&tmp, msize, buffer, length); + +    } + +    return buffer; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : rane   = emplacement virtuel ou physique à traiter.          * +*                msize  = taille de cette adresse, réelle ou désirée.         * +*                start  = indique si le début ou la fin est à imprimer.       * +*                buffer = tampon de sortie utilisé à constituer. [OUT]        * +*                length = transmission de la taille du résultat ou NULL. [OUT]* +*                                                                             * +*  Description : Transforme un emplacement virtuel en chaîne de caractères.   * +*                                                                             * +*  Retour      : Chaîne de caractères constituée.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *mrange_virt_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) +{ +    vmpa2t tmp; + +    if (start) +        vmpa2_virt_to_string(&range->addr, msize, buffer, length); + +    else +    { +        copy_vmpa(&tmp, &range->addr); +        advance_vmpa(&tmp, range->length); + +        vmpa2_virt_to_string(&tmp, msize, buffer, length); + +    } + +    return buffer; + +} diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 85ff6b4..52c5d6a 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -37,6 +37,9 @@ +/* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ + +  /* Taille de la plus longue chaîne de représentation */  #define VMPA_MAX_LEN (sizeof(STR(ULLONG_MAX)) + 1) @@ -44,24 +47,28 @@  #define VMPA_BUFFER(name) char name[VMPA_MAX_LEN] -#define VMPA_NO_PHYSICAL ((off_t)-1) -#define VMPA_NO_VIRTUAL ((uint64_t)-2) +/* Types pour respectivement une position physique et une adresse virtuelle */ +#define phys_t off_t +#define virt_t uint64_t + +#define VMPA_NO_PHYSICAL ((phys_t)-1) +#define VMPA_NO_VIRTUAL ((virt_t)-2)  /* Adresse mémoire ou position physique */  typedef struct _vmpa2t  { -    off_t physical;                         /* Position physique           */ -    uint64_t virtual;                       /* Adresse virtuelle           */ +    phys_t physical;                        /* Position physique           */ +    virt_t virtual;                         /* Adresse virtuelle           */  } vmpa2t;  /* Initialise une localisation dans l'espace mémoire/physique. */ -void init_vmpa(vmpa2t *, off_t, uint64_t); +void init_vmpa(vmpa2t *, phys_t, virt_t);  /* Crée une localisation dans l'adressage mémoire. */ -vmpa2t *make_vmpa(off_t, uint64_t); +vmpa2t *make_vmpa(phys_t, virt_t);  #define delete_vmpa(a) free(a) @@ -87,10 +94,10 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *);      make_vmpa(get_phy_addr(src), get_virt_addr(src))  /* Décalle une position d'une certaine quantité. */ -void advance_vmpa(vmpa2t *, off_t); +void advance_vmpa(vmpa2t *, phys_t);  /* Calcule au mieux la distance entre deux coordonnées. */ -off_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *); +phys_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *);  /* Lit la définition d'une adresse depuis un flux réseau. */  bool recv_vmpa(vmpa2t *, int, int); @@ -112,4 +119,40 @@ vmpa2t *string_to_vmpa_virt(const char *); +/* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ + + +/* Couverture mémoire */ +typedef struct _mrange_t +{ +    vmpa2t addr;                            /* Adresse physique/virtuelle  */ +    phys_t length;                          /* Taille de la couverture     */ + +} mrange_t; + + +#define get_mrange_addr(r) &(r)->addr +#define get_mrange_length(r) (r)->length + + +/* Initialise une plage dans l'espace mémoire/physique. */ +void init_mrange(mrange_t *, const vmpa2t *, phys_t ); + +/* Copie la définition d'une plage mémoire dans une autre. */ +void copy_mrange(mrange_t *, const mrange_t *); + +/* Compare deux couvertures mémoire selon leurs propriétés. */ +int cmp_mrange(const mrange_t *, const mrange_t *); + +/* Indique si une localisation est incluse dans une zone ou non. */ +bool mrange_contains_addr(const mrange_t *, const vmpa2t *); + +/* Transforme un emplacement physique en chaîne de caractères. */ +char *mrange_phys_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); + +/* Transforme un emplacement virtuel en chaîne de caractères. */ +char *mrange_virt_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); + + +  #endif  /* _ARCH_VMPA_H */ | 
