summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-09-17 21:36:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-09-17 21:36:49 (GMT)
commit65768127dea4c2760fe07cf843da7b4ad9e67da5 (patch)
treed0023eb7f378a4118fd074f3f61d5eae02e0882b /src/arch
parentaf083f8bd6da340214ae392451dde5782fb79039 (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.h7
-rw-r--r--src/arch/instruction.c25
-rw-r--r--src/arch/instruction.h10
-rw-r--r--src/arch/raw.c11
-rw-r--r--src/arch/vmpa.c231
-rw-r--r--src/arch/vmpa.h59
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 */