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 */ |