diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
commit | 932ea7c83c07d3982fee605c6dd9895fd2753874 (patch) | |
tree | 766ad53bab9e3e3005334c30e823493de8e84168 /src/arch | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/dalvik/link.c | 5 | ||||
-rw-r--r-- | src/arch/instruction-int.h | 2 | ||||
-rw-r--r-- | src/arch/instruction.c | 293 | ||||
-rw-r--r-- | src/arch/instruction.h | 4 | ||||
-rw-r--r-- | src/arch/raw.c | 45 | ||||
-rw-r--r-- | src/arch/undefined.c | 23 | ||||
-rw-r--r-- | src/arch/vmpa.h | 4 |
7 files changed, 248 insertions, 128 deletions
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c index 694ec65..3f9ab8c 100644 --- a/src/arch/dalvik/link.c +++ b/src/arch/dalvik/link.c @@ -58,6 +58,9 @@ typedef struct _case_comment } case_comment; +/* REMME */ +#define COMMENT_LINE_SEP "\n" + /****************************************************************************** * * @@ -262,6 +265,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor * for (k = 0; k < comment->count; k++) { if (k > 0) + /* FIXME : encapsuler ! */ msg = stradd(msg, COMMENT_LINE_SEP); asprintf(&int_val, _("Case %d:"), comment->keys[k]); @@ -280,6 +284,7 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor * msg = strdup(_("Defaut case:")); else { + /* FIXME : encapsuler ! */ msg = stradd(msg, COMMENT_LINE_SEP); msg = stradd(msg, _("Defaut case")); } diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index c7f32e7..dbb2f2c 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -38,7 +38,7 @@ typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegi typedef const char * (* get_instruction_encoding_fc) (const GArchInstruction *); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); +typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBufferLine *, size_t, size_t); /* Fournit le nom humain de l'instruction manipulée. */ typedef const char * (* get_instruction_keyword_fc) (GArchInstruction *, AsmSyntax ); diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 5f35db4..fc474ea 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -30,6 +30,7 @@ #include "instruction-int.h" +#include "../glibext/linegen-int.h" @@ -39,6 +40,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); +/* Procède à l'initialisation de l'interface de génération. */ +static void g_arch_instruction_interface_init(GLineGeneratorInterface *); + /* Supprime toutes les références externes. */ static void g_arch_instruction_dispose(GArchInstruction *); @@ -47,16 +51,32 @@ static void g_arch_instruction_finalize(GArchInstruction *); -/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ +/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ + + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t g_arch_instruction_count_lines(const GArchInstruction *); + +/* Retrouve l'emplacement correspondant à une position donnée. */ +static void g_arch_instruction_compute_addr(const GArchInstruction *, gint, vmpa2t *, size_t, size_t); +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +static int g_arch_instruction_contains_addr(const GArchInstruction *, const vmpa2t *, size_t, size_t); + +/* Renseigne sur les propriétés liées à un générateur. */ +static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static GBufferLine *_g_arch_instruction_print(GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); +static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t); /* Indique le type défini pour une instruction d'architecture. */ -G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init)); /****************************************************************************** @@ -116,6 +136,29 @@ static void g_arch_instruction_init(GArchInstruction *instr) /****************************************************************************** * * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface) +{ + iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines; + iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr; + iface->contains = (linegen_contains_fc)g_arch_instruction_contains_addr; + iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2; + iface->print = (linegen_print_fc)g_arch_instruction_print; + +} + + +/****************************************************************************** +* * * Paramètres : instr = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -897,84 +940,6 @@ void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t } -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* msize = taille idéale des positions et adresses; * -* content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBufferLine *_g_arch_instruction_print(GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) -{ - GBufferLine *result; /* Ligne de destination */ - const char *key; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ - size_t i; /* Boucle de parcours */ - - result = g_code_buffer_prepare_new_line(buffer, &instr->range); - - g_buffer_line_add_flag(result, BLF_HAS_CODE); - - g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->max_displayed_len); - - /* Instruction proprement dite */ - - key = g_arch_instruction_get_keyword(instr, syntax); - klen = strlen(key); - - g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); - - if (instr->operands_count > 0) - { - g_arch_operand_print(instr->operands[0], result, syntax); - - for (i = 1; i < instr->operands_count; i++) - { - g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - - g_arch_operand_print(instr->operands[i], result, syntax); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * -* msize = taille idéale des positions et adresses; * -* content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * -* * -* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBufferLine *g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) -{ - return G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax); - -} - /* ---------------------------------------------------------------------------------- */ /* TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE */ @@ -1110,3 +1075,169 @@ GArchInstruction *g_arch_instruction_find_by_address(GArchInstruction *list, con return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* OFFRE DE CAPACITES DE GENERATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* * +* Description : Indique le nombre de ligne prêtes à être générées. * +* * +* Retour : Nombre de lignes devant apparaître au final. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_arch_instruction_count_lines(const GArchInstruction *instr) +{ + return 1; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* x = position géographique sur la ligne concernée. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Retrouve l'emplacement correspondant à une position donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_compute_addr(const GArchInstruction *instr, gint x, vmpa2t *addr, size_t index, size_t repeat) +{ + copy_vmpa(addr, get_mrange_addr(&instr->range)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * +* * +* Retour : Bilan de la détermination, utilisable en comparaisons. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int g_arch_instruction_contains_addr(const GArchInstruction *instr, const vmpa2t *addr, size_t index, size_t repeat) +{ + int result; /* Conclusion à retourner */ + + result = cmp_mrange_with_vmpa(&instr->range, addr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à consulter. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Renseigne sur les propriétés liées à un générateur. * +* * +* Retour : Propriétés particulières associées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *instr, size_t index, size_t repeat) +{ + return BLF_HAS_CODE; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction d'assemblage à représenter. * +* buffer = espace où placer ledit contenu. * +* msize = taille idéale des positions et adresses; * +* content = contenu binaire global à venir lire. * +* syntax = type de représentation demandée. * +* * +* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat) +{ + const char *key; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + size_t i; /* Boucle de parcours */ + + g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); + + /* Instruction proprement dite */ + + key = g_arch_instruction_get_keyword(instr, 0/*, syntax*/); + klen = strlen(key); + + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); + + if (instr->operands_count > 0) + { + g_arch_operand_print(instr->operands[0], line, 0/*syntax*/); + + for (i = 1; i < instr->operands_count; i++) + { + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); + + g_arch_operand_print(instr->operands[i], line, 0/*syntax*/); + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : instr = générateur à utiliser pour l'impression. * +* line = ligne de rendu à compléter. * +* index = indice de cette même ligne dans le tampon global. * +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Imprime dans une ligne de rendu le contenu représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat) +{ + G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat); + +} diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 54778b5..814cc86 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -35,7 +35,6 @@ #include "../analysis/content.h" #include "../analysis/type.h" #include "../format/executable.h" -#include "../glibext/gcodebuffer.h" @@ -222,9 +221,6 @@ phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *); /* Définit la quantité maximale de code affiché. */ void g_arch_instruction_set_displayed_max_length(GArchInstruction *, phys_t); -/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -GBufferLine *g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); - /* -------------------- TRAITEMENT DES INSTRUCTIONS PAR ENSEMBLE -------------------- */ diff --git a/src/arch/raw.c b/src/arch/raw.c index 61a37e0..d0348c9 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -78,7 +78,7 @@ static const char *g_raw_instruction_get_encoding(const GRawInstruction *); static const char *g_raw_instruction_get_keyword(const GRawInstruction *, AsmSyntax); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static GBufferLine *g_raw_instruction_print(GRawInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); +static void g_raw_instruction_print(GRawInstruction *, GBufferLine *, size_t, size_t); @@ -444,11 +444,11 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A /****************************************************************************** * * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * +* Paramètres : instr = instruction d'assemblage à représenter. * +* buffer = espace où placer ledit contenu. * * msize = taille idéale des positions et adresses; * * content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * +* syntax = type de représentation demandée. * * * * Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * * * @@ -458,9 +458,8 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A * * ******************************************************************************/ -static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) +static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, size_t index, size_t repeat) { - GBufferLine *result; /* Ligne de destination */ GArchInstruction *base; /* Autre version de l'instance */ const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ @@ -474,25 +473,21 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer base = G_ARCH_INSTRUCTION(instr); if (!instr->is_padding && !instr->is_string) - result = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, buffer, msize, content, syntax); + G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class)->print(base, line, index, repeat); else { - result = g_code_buffer_prepare_new_line(buffer, &base->range); - - g_buffer_line_add_flag(result, BLF_HAS_CODE); - - g_buffer_line_fill_mrange(result, msize/* TODO ! */, msize); + g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); /* Instruction proprement dite */ - key = g_arch_instruction_get_keyword(base, syntax); + key = g_arch_instruction_get_keyword(base, 0/*, syntax*/); klen = strlen(key); - g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL); if (instr->is_padding) - g_buffer_line_append_text(result, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL); else /*if (instr->is_string)*/ { @@ -516,15 +511,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer { if (!first) { - g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; string[iter++] = '"'; - g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); iter = 1; @@ -534,13 +529,13 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer if (!first) { - g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; - g_arch_operand_print(base->operands[i], result, syntax); + g_arch_operand_print(base->operands[i], line, 0/*, syntax*/); } @@ -554,15 +549,15 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer { if (!first) { - g_buffer_line_append_text(result, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(result, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } else first = false; string[iter++] = '"'; - g_buffer_line_append_text(result, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); + g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL); } @@ -572,8 +567,6 @@ static GBufferLine *g_raw_instruction_print(GRawInstruction *instr, GCodeBuffer } - return result; - } diff --git a/src/arch/undefined.c b/src/arch/undefined.c index 0957764..d239dd5 100644 --- a/src/arch/undefined.c +++ b/src/arch/undefined.c @@ -70,7 +70,7 @@ static const char *g_undef_instruction_get_encoding(const GUndefInstruction *); static const char *g_undef_instruction_get_keyword(const GUndefInstruction *, AsmSyntax); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ -static GBufferLine *g_undef_instruction_print(GUndefInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax); +static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t); @@ -262,11 +262,11 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS /****************************************************************************** * * -* Paramètres : instr = instruction d'assemblage à représenter. * -* buffer = espace où placer ledit contenu. * +* Paramètres : instr = instruction d'assemblage à représenter. * +* buffer = espace où placer ledit contenu. * * msize = taille idéale des positions et adresses; * * content = contenu binaire global à venir lire. * -* syntax = type de représentation demandée. * +* syntax = type de représentation demandée. * * * * Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. * * * @@ -276,29 +276,22 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr, AsmS * * ******************************************************************************/ -static GBufferLine *g_undef_instruction_print(GUndefInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const GBinContent *content, AsmSyntax syntax) +static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat) { - GBufferLine *result; /* Ligne de destination */ GArchInstruction *base; /* Version de base */ const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ base = G_ARCH_INSTRUCTION(instr); - result = g_code_buffer_prepare_new_line(buffer, &base->range); - - g_buffer_line_add_flag(result, BLF_HAS_CODE); - - g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->max_displayed_len); + g_buffer_line_fill_vmpa(line, get_mrange_addr(&base->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED); /* Instruction proprement dite */ - key = g_arch_instruction_get_keyword(base, syntax); + key = g_arch_instruction_get_keyword(base, 0/*, syntax*/); klen = strlen(key); - g_buffer_line_append_text(result, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL); - - return result; + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL); } diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 1e17f17..16fada4 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -104,7 +104,9 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *); #define has_phys_addr(a) ((a)->physical != VMPA_NO_PHYSICAL) #define has_virt_addr(a) ((a)->virtual != VMPA_NO_VIRTUAL) -#define dup_vmpa(src) \ +#define is_invalid_vmpa(a) (!has_phys_addr(a) && !has_virt_addr(a)) + +#define dup_vmpa(src) \ make_vmpa(get_phy_addr(src), get_virt_addr(src)) /* Décalle une position d'une certaine quantité. */ |