summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/db/collection.c39
-rw-r--r--src/analysis/db/items/bookmark.c2
-rw-r--r--src/analysis/db/items/comment.c460
-rw-r--r--src/analysis/db/items/comment.h6
-rw-r--r--src/analysis/db/items/switcher.c2
-rw-r--r--src/analysis/disass/output.c2
6 files changed, 488 insertions, 23 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index d5518dd..aa7591e 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -992,15 +992,21 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
/**
* On réalise une petite conversion selon le champ.
*
- * Le filtre SQLITE_NATIVE est destiné à conserver un champ sur 32 bits
- * quand il s'agit du format utilisé, même si toutes les valeurs sont
- * enregistrées en 64 bits.
+ * Le filtre SQLITE_NATIVE est destiné à conserver le type choisi par
+ * SQLite. Typiquement, une chaîne peut être à SQLITE_NULL ou SQLITE_TEXT
+ * selon la valeur conservée dans la base.
*
- * C'est par exemple le cas dans les bascules d'affichage.
- *
- * D'autres éléments, comme les localisations en mémoire, peuvent
+ * D'autres éléments, comme les localisations en mémoire, peuvent aussi
* avoir un champ éventuellement nul, donc la définition à partir des
* indications de la base de données reste importante.
+ *
+ * En ce qui concerne les valeurs numériques, SQLite ne fait pas de
+ * distinction : tout passe par la fonction sqlite3VdbeIntValue(),
+ * qui effectue des transtypages au besoin pour tout ce qui n'est
+ * pas numérique.
+ *
+ * Pour les types internes SQLITE_INTEGER et SQLITE_BOOLEAN,
+ * il est donc nécessaire d'ajuster en interne.
*/
if (native_type == SQLITE_INTEGER)
@@ -1010,13 +1016,18 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)
values[i].type = native_type;
else
- assert(values[i].type == native_type || values[i].type == SQLITE_INTEGER);
-
+ assert(values[i].type == native_type
+ || values[i].type == SQLITE_INTEGER
+ || values[i].type == SQLITE_BOOLEAN);
switch (values[i].type)
{
+ case SQLITE_BOOLEAN:
+ values[i].boolean = (bool)sqlite3_column_int(stmt, i);
+ break;
+
case SQLITE_INTEGER:
- values[i].integer = (int)sqlite3_column_int64(stmt, i);
+ values[i].integer = sqlite3_column_int(stmt, i);
break;
case SQLITE_INT64:
@@ -1142,6 +1153,11 @@ static bool g_db_collection_store_item(const GDbCollection *collec, const GDbIte
{
switch (values[i].type)
{
+ case SQLITE_BOOLEAN:
+ ret = sqlite3_bind_int(stmt, index, values[i].boolean);
+ index++;
+ break;
+
case SQLITE_INTEGER:
ret = sqlite3_bind_int(stmt, index, values[i].integer);
index++;
@@ -1301,6 +1317,11 @@ static bool g_db_collection_store_updated_item(const GDbCollection *collec, cons
switch (values[i].type)
{
+ case SQLITE_BOOLEAN:
+ ret = sqlite3_bind_int(stmt, index, values[i].boolean);
+ index++;
+ break;
+
case SQLITE_INTEGER:
ret = sqlite3_bind_int(stmt, index, values[i].integer);
index++;
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 6914bc3..4c93faf 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -393,7 +393,7 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark)
* *
* Paramètres : bookmark = signet à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
-* prev = état précédent de la présence du drapeau. *
+* prev = état précédent de la présence du drapeau. [OUT] *
* set = précision quant au nouvel état du drapeau. *
* *
* Description : Exécute un signet sur un tampon de binaire chargé. *
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 9212cae..b4a1dc0 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -24,12 +24,18 @@
#include "comment.h"
+#include <assert.h>
+#include <malloc.h>
#include <stdio.h>
#include <sys/socket.h>
+#include <i18n.h>
+
+
#include "../collection-int.h"
#include "../item-int.h"
+#include "../../../common/io.h"
@@ -42,8 +48,21 @@ struct _GDbComment
GDbItem parent; /* A laisser en premier */
vmpa2t addr; /* Adresse du commentaire */
+ BufferLineFlags flags; /* Identification de l'accroche*/
+
rle_string text; /* Contenu du commentaire */
+ bool inlined; /* Intégration dans une ligne ?*/
+
+ union
+ {
+ bool repeatable; /* Répétition aux lignes liées */
+ bool before; /* Zone dédiée au dessus ? */
+ };
+
+ GDbComment **oldies; /* Commentaires d'origine ? */
+ size_t old_count; /* Nombre de places à restaurer*/
+
};
/* Commentaire à placer dans du texte quelconque (classe) */
@@ -75,6 +94,18 @@ static bool g_db_comment_recv_from_fd(GDbComment *, int, int);
/* Exporte la définition d'un commentaire dans un flux réseau. */
static bool g_db_comment_send_to_fd(const GDbComment *, int, int);
+/* Construit la description humaine d'un commentaire. */
+static void g_db_comment_build_label(GDbComment *);
+
+/* Exécute l'impression de commentaire dans du code de binaire. */
+static bool g_db_comment_run(GDbComment *, GLoadedBinary *, bool);
+
+/* Réalise l'impression de commentaire dans du code de binaire. */
+static bool g_db_comment_apply(GDbComment *, GLoadedBinary *);
+
+/* Annule l'impression d'un commentaire dans du code de binaire. */
+static bool g_db_comment_cancel(GDbComment *, GLoadedBinary *);
+
/* Constitue les champs destinés à une insertion / modification. */
static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value **, size_t *);
@@ -162,6 +193,10 @@ static void g_db_comment_class_init(GDbCommentClass *klass)
item->recv = (recv_db_item_fc)g_db_comment_recv_from_fd;
item->send = (send_db_item_fc)g_db_comment_send_to_fd;
+ item->build_label = (build_item_label_fc)g_db_comment_build_label;
+ item->apply = (run_item_fc)g_db_comment_apply;
+ item->cancel = (run_item_fc)g_db_comment_cancel;
+
item->prepare_stmt = (prepare_db_statement)g_db_comment_prepare_db_statement;
item->load = (load_db_item_fc)g_db_comment_load;
@@ -200,6 +235,14 @@ static void g_db_comment_init(GDbComment *comment)
static void g_db_comment_dispose(GDbComment *comment)
{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < comment->old_count; i++)
+ g_object_unref(G_OBJECT(comment->oldies[i]));
+
+ if (comment->oldies != NULL)
+ free(comment->oldies);
+
G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
}
@@ -228,9 +271,10 @@ static void g_db_comment_finalize(GDbComment *comment)
/******************************************************************************
* *
-* Paramètres : addr = adresse inamovible localisant une position. *
-* text = commentaire construit ou NULL. *
-* is_volatile = état du besoin en sauvegarde. *
+* Paramètres : addr = adresse inamovible localisant une position. *
+* flags = indentifiants supplémentaires de ligne visée. *
+* text = commentaire construit ou NULL. *
+* repeatable = repétition aux instructions liées ? *
* *
* Description : Crée une définition de commentaire dans une zone de texte. *
* *
@@ -240,7 +284,7 @@ static void g_db_comment_finalize(GDbComment *comment)
* *
******************************************************************************/
-GDbComment *g_db_comment_new(const vmpa2t *addr, const char *text, bool is_volatile)
+GDbComment *g_db_comment_new_inlined(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool repeatable)
{
GDbComment *result; /* Instance à retourner */
@@ -248,9 +292,49 @@ GDbComment *g_db_comment_new(const vmpa2t *addr, const char *text, bool is_volat
copy_vmpa(&result->addr, addr);
+ result->flags = flags;
+
g_db_comment_set_text(result, text);
- g_db_item_set_volatile(G_DB_ITEM(result), is_volatile);
+ result->inlined = true;
+
+ result->repeatable = repeatable;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : addr = adresse inamovible localisant une position. *
+* flags = indentifiants supplémentaires de ligne visée. *
+* text = commentaire construit ou NULL. *
+* before = précision quant à la position de la zone à définir. *
+* *
+* Description : Crée une définition de commentaire dans une zone de texte. *
+* *
+* Retour : Commentaire mis en place ou NULL en cas d'erreur. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDbComment *g_db_comment_new_area(const vmpa2t *addr, BufferLineFlags flags, const char *text, bool before)
+{
+ GDbComment *result; /* Instance à retourner */
+
+ result = g_object_new(G_TYPE_DB_COMMENT, NULL);
+
+ copy_vmpa(&result->addr, addr);
+
+ result->flags = flags;
+
+ g_db_comment_set_text(result, text);
+
+ result->inlined = false;
+
+ result->before = before;
return result;
@@ -305,6 +389,8 @@ static gint g_db_comment_cmp(GDbComment *a, GDbComment *b, bool with)
static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags)
{
bool status; /* Bilan d'opération initiale */
+ uint32_t val32; /* Valeur sur 32 bits */
+ uint8_t val8; /* Valeur sur 8 bits */
status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->recv(G_DB_ITEM(comment), fd, flags);
if (!status) return false;
@@ -312,9 +398,24 @@ static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags)
if (!recv_vmpa(&comment->addr, fd, flags))
return false;
+ status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags);
+ if (!status) return false;
+
+ comment->flags = be32toh(val32);
+
if (!recv_rle_string(&comment->text, fd, flags))
return false;
+ status = safe_recv(fd, &val8, sizeof(uint8_t), MSG_WAITALL | flags);
+ if (!status) return false;
+
+ comment->inlined = val8;
+
+ status = safe_recv(fd, &val8, sizeof(uint8_t), MSG_WAITALL | flags);
+ if (!status) return false;
+
+ comment->repeatable = val8;
+
return true;
}
@@ -344,9 +445,18 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags
if (!send_vmpa(&comment->addr, fd, MSG_MORE | flags))
return false;
- if (!send_rle_string(&comment->text, fd, flags))
+ status = safe_send(fd, (uint32_t []) { htobe32(comment->flags) }, sizeof(uint32_t), MSG_MORE | flags);
+ if (!status) return false;
+
+ if (!send_rle_string(&comment->text, fd, MSG_MORE | flags))
return false;
+ status = safe_send(fd, (uint8_t []) { (uint8_t)comment->inlined }, sizeof(uint8_t), MSG_MORE | flags);
+ if (!status) return false;
+
+ status = safe_send(fd, (uint8_t []) { (uint8_t)comment->repeatable }, sizeof(uint8_t), flags);
+ if (!status) return false;
+
return true;
}
@@ -354,6 +464,250 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags
/******************************************************************************
* *
+* Paramètres : comment = définition de commentaire à manipuler. *
+* *
+* Description : Construit la description humaine d'un commentaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_db_comment_build_label(GDbComment *comment)
+{
+ VMPA_BUFFER(loc); /* Indication de position */
+
+ if (has_virt_addr(&comment->addr))
+ vmpa2_virt_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL);
+ else
+ vmpa2_phys_to_string(&comment->addr, MDS_UNDEFINED, loc, NULL);
+
+ if (is_rle_string_empty(&comment->text))
+ asprintf(&G_DB_ITEM(comment)->label, _("Delete comment at %s"), loc);
+
+ else
+ {
+ if (comment->inlined)
+ asprintf(&G_DB_ITEM(comment)->label, _("Enter inlined comment at %s"), loc);
+ else
+ asprintf(&G_DB_ITEM(comment)->label, _("Enter comment area at %s"), loc);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = définition de commentaire à manipuler. *
+* binary = binaire chargé en mémoire à modifier. *
+* apply = indique s'il faut appliquer la définition ou non. *
+* *
+* Description : Exécute l'impression de commentaire dans du code de binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool apply)
+{
+ bool result; /* Bilan à faire remonter */
+ GCodeBuffer *buffer; /* Tampon de lignes à traiter */
+ GBufferLine *line; /* Ligne de tampon à marquer */
+ GArchProcessor *proc; /* Propriétaire d'instructions */
+ GArchInstruction *instr; /* Instruction à traiter */
+ GArchInstruction **sources; /* Instructions diverses liées */
+ size_t scount; /* Nbre de sources affichées */
+ size_t i; /* Boucle de parcours */
+ const mrange_t *range; /* Emplacement d'instruction */
+ GBufferLine *linked; /* Ligne liée à traiter */
+ GDbComment *old; /* Ancien élément à restaurer */
+
+ result = true;
+
+ /* Recherche de la ligne visée */
+
+ buffer = g_loaded_binary_get_disassembled_buffer(binary);
+
+ line = g_code_buffer_find_line_by_addr(buffer, &comment->addr, comment->flags, NULL);
+ if (line == NULL)
+ {
+ result = false;
+ goto exit_gui;
+ }
+
+ /* Détermination de l'imprimeur précédent */
+
+ if (apply)
+ {
+ assert(comment->old_count == 0);
+
+ comment->old_count = 1;
+ comment->oldies = (GDbComment **)calloc(comment->old_count, sizeof(GDbComment *));
+
+ }
+
+ /* Applications globales finales */
+
+#define g_code_buffer_update_inlined_comment_dummy(b, l, c, d, o) \
+ g_code_buffer_update_inlined_comment(b, l, c, o)
+
+ /**
+ * Note : on part du principe qu'un commentaire intégré ne peut remplacer qu'un
+ * commentaire intégré. Et pareil pour les commentaires en blocs.
+ */
+
+#define RUN_COMMENT_ON(ln, idx, func) \
+ if (apply) \
+ { \
+ comment->oldies[idx] = (GDbComment *)g_code_buffer_get_comment_creator(buffer, ln); \
+ assert(comment->oldies[idx] == NULL || G_IS_DB_COMMENT(comment->oldies[idx])); \
+ assert(comment->oldies[idx] == NULL || comment->oldies[idx]->inlined == comment->inlined); \
+ \
+ if (is_rle_string_empty(&comment->text)) \
+ result = g_code_buffer_delete_lines_comment(buffer, ln); \
+ else \
+ result = func(buffer, ln, get_rle_string(&comment->text), \
+ comment->before, G_OBJECT(comment)); \
+ } \
+ else \
+ { \
+ old = comment->oldies[idx]; \
+ \
+ if (old == NULL) \
+ { \
+ if (!is_rle_string_empty(&comment->text)) \
+ result = g_code_buffer_delete_lines_comment(buffer, ln); \
+ else \
+ result = true; \
+ } \
+ else \
+ { \
+ if (is_rle_string_empty(&old->text)) \
+ result = g_code_buffer_delete_lines_comment(buffer, ln); \
+ else \
+ result = func(buffer, ln, get_rle_string(&old->text), \
+ old->before, G_OBJECT(old)); \
+ } \
+ \
+ }
+
+ if (comment->inlined)
+ {
+ /* Traitement d'un commentaire inscrusté */
+
+ RUN_COMMENT_ON(line, 0, g_code_buffer_update_inlined_comment_dummy);
+
+ /* Traitement des répétitions ? */
+
+ if (comment->repeatable/* && result*/)
+ {
+ proc = g_loaded_binary_get_processor(binary);
+
+ range = g_buffer_line_get_range(line);
+
+ instr = g_arch_processor_find_instr_by_address(proc, get_mrange_addr(range));
+ assert(instr != NULL);
+
+ scount = g_arch_instruction_get_sources(instr, &sources, NULL);
+
+ if (apply)
+ {
+ comment->old_count += scount;
+ comment->oldies = (GDbComment **)realloc(comment->oldies,
+ comment->old_count * sizeof(GDbComment *));
+ }
+
+ for (i = 0; i < scount && result; i++)
+ {
+ range = g_arch_instruction_get_range(sources[i]);
+
+ /**
+ * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL.
+ * Comme on ne peut pas traiter les deux cas, on prend la première qui vient
+ * avec BLF_NONE.
+ */
+ linked = g_code_buffer_find_line_by_addr(buffer, get_mrange_addr(range), BLF_NONE, NULL);
+ assert(linked != NULL);
+
+ RUN_COMMENT_ON(linked, 1 + i, g_code_buffer_update_inlined_comment_dummy);
+
+ }
+
+ g_object_unref(G_OBJECT(proc));
+
+ }
+
+ }
+
+ else
+ {
+ RUN_COMMENT_ON(line, 0, g_code_buffer_update_comment_area);
+ }
+
+ g_object_unref(G_OBJECT(line));
+
+ exit_gui:
+
+ /* TODO g_object_unref(G_OBJECT(buffer));*/
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = définition de commentaire à manipuler. *
+* binary = binaire chargé en mémoire à modifier. *
+* *
+* Description : Réalise l'impression de commentaire dans du code de binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_db_comment_apply(GDbComment *comment, GLoadedBinary *binary)
+{
+ bool result; /* Bilan à faire remonter */
+
+ result = g_db_comment_run(comment, binary, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : comment = définition de commentaire à manipuler. *
+* binary = binaire chargé en mémoire à modifier. *
+* *
+* Description : Annule l'impression d'un commentaire dans du code de binaire.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_db_comment_cancel(GDbComment *comment, GLoadedBinary *binary)
+{
+ bool result; /* Bilan à faire remonter */
+
+ result = g_db_comment_run(comment, binary, false);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : comment = base d'éléments sur laquelle s'appuyer. *
* values = couples de champs et de valeurs à lier. [OUT] *
* count = nombre de ces couples. [OUT] *
@@ -369,6 +723,7 @@ static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags
static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_value **values, size_t *count)
{
bool status; /* Bilan d'opération initiale */
+ bound_value *value; /* Valeur à éditer / définir */
status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->prepare_stmt(G_DB_ITEM(comment), values, count);
if (!status) return false;
@@ -376,9 +731,36 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v
status = prepare_vmpa_db_statement(&comment->addr, values, count);
if (!status) return false;
+ *count += 1;
+ *values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
+
+ value = &(*values)[*count - 1];
+
+ value->name = "flags";
+ value->type = SQLITE_INTEGER;
+ value->integer = comment->flags;
+ value->delete = NULL;
+
status &= prepare_db_statement_for_rle_string(&comment->text, "text", values, count);
if (!status) return false;
+ *count += 2;
+ *values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
+
+ value = &(*values)[*count - 2];
+
+ value->name = "inlined";
+ value->type = SQLITE_BOOLEAN;
+ value->boolean = comment->inlined;
+ value->delete = NULL;
+
+ value = &(*values)[*count - 1];
+
+ value->name = "repeatable";
+ value->type = SQLITE_BOOLEAN;
+ value->boolean = comment->repeatable;
+ value->delete = NULL;
+
return true;
}
@@ -401,13 +783,44 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *comment, bound_v
static bool g_db_comment_load(GDbComment *comment, const bound_value *values, size_t count)
{
bool result; /* Bilan à faire remonter */
+ const bound_value *value; /* Valeur à éditer / définir */
result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->load(G_DB_ITEM(comment), values, count);
result &= load_vmpa(&comment->addr, values, count);
+ if (result)
+ {
+ value = find_bound_value(values, count, "flags");
+ result = (value != NULL && value->type == SQLITE_INTEGER);
+
+ if (result)
+ comment->flags = value->integer;
+
+ }
+
result &= load_rle_string(&comment->text, "text", values, count);
+ if (result)
+ {
+ value = find_bound_value(values, count, "inlined");
+ result = (value != NULL && value->type == SQLITE_BOOLEAN);
+
+ if (result)
+ comment->inlined = value->boolean;
+
+ }
+
+ if (result)
+ {
+ value = find_bound_value(values, count, "repeatable");
+ result = (value != NULL && value->type == SQLITE_BOOLEAN);
+
+ if (result)
+ comment->repeatable = value->boolean;
+
+ }
+
return result;
}
@@ -526,7 +939,7 @@ static void g_comment_collection_class_init(GCommentCollectionClass *klass)
static void g_comment_collection_init(GCommentCollection *collec)
{
- G_DB_COLLECTION(collec)->featuring = 0;
+ G_DB_COLLECTION(collec)->featuring = DBF_COMMENTS;
G_DB_COLLECTION(collec)->type = G_TYPE_DB_COMMENT;
G_DB_COLLECTION(collec)->name = "Comments";
@@ -613,10 +1026,13 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
int ret; /* Bilan de la création */
char *msg; /* Message d'erreur */
- sql = "CREATE TABLE Comments (" \
- SQLITE_DB_ITEM_CREATE ", " \
- SQLITE_VMPA_CREATE ", " \
- SQLITE_RLESTR_CREATE("text") \
+ sql = "CREATE TABLE Comments (" \
+ SQLITE_DB_ITEM_CREATE ", " \
+ SQLITE_VMPA_CREATE ", " \
+ "flags INTEGER, " \
+ SQLITE_RLESTR_CREATE("text") ", " \
+ "inlined INTEGER, " \
+ "repeatable INTEGER" \
");";
ret = sqlite3_exec(db, sql, NULL, NULL, &msg);
@@ -648,6 +1064,7 @@ static bool g_comment_collection_create_db_table(const GCommentCollection *colle
static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_value **values, size_t *count)
{
bool status; /* Bilan d'une préparation */
+ bound_value *value; /* Valeur à éditer / définir */
status = G_DB_COLLECTION_CLASS(g_comment_collection_parent_class)->setup_load(G_DB_COLLECTION(collec), \
values, count);
@@ -656,9 +1073,30 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va
if (!setup_load_for_vmpa(NULL, values, count))
return false;
+ *count += 1;
+ *values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
+
+ value = &(*values)[*count - 1];
+
+ value->name = "flags";
+ value->type = SQLITE_INTEGER;
+
if (!setup_load_of_rle_string(NULL, "text", values, count))
return false;
+ *count += 2;
+ *values = (bound_value *)realloc(*values, *count * sizeof(bound_value));
+
+ value = &(*values)[*count - 2];
+
+ value->name = "inlined";
+ value->type = SQLITE_BOOLEAN;
+
+ value = &(*values)[*count - 1];
+
+ value->name = "repeatable";
+ value->type = SQLITE_BOOLEAN;
+
return true;
}
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index 316f4c5..dc9addc 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -32,6 +32,7 @@
#include "../../../arch/vmpa.h"
+#include "../../../glibext/gbufferline.h"
@@ -57,7 +58,10 @@ typedef struct _GDbCommentClass GDbCommentClass;
GType g_db_comment_get_type(void);
/* Crée une définition de commentaire dans une zone de texte. */
-GDbComment *g_db_comment_new(const vmpa2t *, const char *, bool);
+GDbComment *g_db_comment_new_inlined(const vmpa2t *, BufferLineFlags, const char *, bool);
+
+/* Crée une définition de commentaire dans une zone de texte. */
+GDbComment *g_db_comment_new_area(const vmpa2t *, BufferLineFlags, const char *, bool);
/* Fournit l'adresse associée à un commentaire. */
const vmpa2t *g_db_comment_get_address(GDbComment *);
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 7b72cf2..6497e41 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -481,7 +481,7 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher)
* *
* Paramètres : switcher = bascule d'affichage à manipuler. *
* binary = binaire chargé en mémoire à modifier. *
-* old = état précédent à conserver. *
+* old = état précédent à conserver. [OUT] *
* new = nouvel état à appliquer. *
* *
* Description : Exécute une bascule d'affichage d'opérande sur un binaire. *
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 75444a5..07165c0 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -269,6 +269,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
if (comment != NULL)
{
+ /* FIXME : appliquer ! */
+
text = g_db_comment_get_text(comment);