1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2006 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <libanjuta/anjuta-debug.h>
28 #include <libanjuta/interfaces/ianjuta-markable.h>
35 #include "disassemble.h"
37 #include "sparse_buffer.h"
38 #include "sparse_view.h"
44 *---------------------------------------------------------------------------*/
46 enum {DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
= 256,
47 DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
= 4,
48 DMA_DISASSEMBLY_TAB_LENGTH
= 4,
49 DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
= 8,
50 DMA_DISASSEMBLY_PAGE_DISTANCE
= 4 * 60,
51 DMA_DISASSEMBLY_VALID_ADDRESS
= 0,
52 DMA_DISASSEMBLY_KNOW_ADDRESS
= -1,
53 DMA_DISASSEMBLY_UNKNOWN_ADDRESS
= -2};
55 enum {DMA_DISASSEMBLY_KEEP_ALL
,
56 DMA_DISASSEMBLY_SKIP_BEGINNING
};
59 *---------------------------------------------------------------------------*/
61 typedef struct _DmaDisassemblyLine DmaDisassemblyLine
;
62 typedef struct _DmaDisassemblyBufferNode DmaDisassemblyBufferNode
;
64 typedef struct _DmaDisassemblyBuffer DmaDisassemblyBuffer
;
65 typedef struct _DmaDisassemblyBufferClass DmaDisassemblyBufferClass
;
67 typedef struct _DmaDisassemblyView DmaDisassemblyView
;
68 typedef struct _DmaDisassemblyViewClass DmaDisassemblyViewClass
;
70 struct _DmaDisassemble
72 DmaDebuggerQueue
*debugger
;
73 DebugManagerPlugin
*plugin
;
76 DmaSparseBuffer
* buffer
;
80 /* Disassembly buffer object
81 *---------------------------------------------------------------------------*/
83 struct _DmaDisassemblyBuffer
85 DmaSparseBuffer parent
;
86 DmaDebuggerQueue
*debugger
;
90 struct _DmaDisassemblyBufferClass
92 DmaSparseBufferClass parent
;
95 struct _DmaDisassemblyLine
101 struct _DmaDisassemblyBufferNode
103 DmaSparseBufferNode parent
;
106 DmaDisassemblyLine data
[];
109 #define DMA_DISASSEMBLY_BUFFER_TYPE (dma_disassembly_buffer_get_type ())
110 #define DMA_DISASSEMBLY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBuffer))
111 #define DMA_DISASSEMBLY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBufferClass))
112 #define IS_DMA_DISASSEMBLY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DMA_DISASSEMBLY_BUFFER_TYPE))
113 #define IS_DMA_DISASSEMBLY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DMA_DISASSEMBLY_BUFFER_TYPE))
114 #define GET_DMA_DISASSEMBLY_BUFFER_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBufferClass))
116 static DmaSparseBufferClass
*parent_buffer_class
= NULL
;
118 static GType
dma_disassembly_buffer_get_type (void);
120 /* Disassembly iterator function
121 *---------------------------------------------------------------------------*/
124 * Iterator can be divided in 3 cases:
125 * 1. Iterator on valid address:
129 * line = line number in node
130 * 2. Iterator on know address:
134 * 3. Iterator on unknown address:
135 * base = address (often known)
136 * offset != 0 (could be 0 too)
138 *---------------------------------------------------------------------------*/
141 dma_disassembly_get_address (DmaSparseIter
*iter
)
143 return iter
->base
+ iter
->offset
;
147 dma_disassembly_iter_refresh (DmaSparseIter
*iter
)
149 /* Call this after updating node according to base */
151 DmaDisassemblyBufferNode
*node
= (DmaDisassemblyBufferNode
*)iter
->node
;
153 if (iter
->node
!= NULL
)
155 /* Find line corresponding to base */
156 if ((iter
->node
->lower
<= iter
->base
) && (iter
->base
<= iter
->node
->upper
))
158 /* Iterator in current node */
159 if ((iter
->line
>= 0) && (iter
->line
< ((DmaDisassemblyBufferNode
*)iter
->node
)->size
)
160 && (((DmaDisassemblyBufferNode
*)iter
->node
)->data
[iter
->line
].address
== iter
->base
))
162 /* Already get the right node */
167 /* Search for correct line */
169 if (iter
->offset
>= 0)
171 for (line
= 0; line
< node
->size
; line
++)
173 if (node
->data
[line
].address
>= iter
->base
) break;
178 for (line
= node
->size
- 1; line
>= 0; line
--)
180 if (node
->data
[line
].address
<= iter
->base
) break;
184 if (node
->data
[line
].address
== iter
->base
)
188 else if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
190 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
194 else if (iter
->base
== iter
->node
->upper
+ 1)
197 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
199 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
204 /* Invalid base address */
205 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
207 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
213 /* Invalid base address */
214 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
216 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
220 /* Try to reduce offset */
223 if (iter
->offset
> 0)
225 /* Need to go upper if possible */
226 guint up
= (DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
+ iter
->offset
- 1)/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
230 gint len
= node
->size
- line
;
234 iter
->node
= (DmaSparseBufferNode
*)node
;
235 iter
->line
= line
+ up
;
236 iter
->base
= node
->data
[iter
->line
].address
;
242 if (iter
->node
->upper
== dma_sparse_buffer_get_upper (iter
->buffer
))
244 gboolean move
= iter
->line
!= node
->size
- 1;
246 iter
->node
= (DmaSparseBufferNode
*)node
;
247 iter
->line
= node
->size
- 1;
248 iter
->base
= node
->data
[iter
->line
].address
;
256 if ((node
->parent
.next
== NULL
) || (node
->parent
.upper
!= node
->parent
.next
->lower
- 1))
258 /* No following node */
260 iter
->node
= (DmaSparseBufferNode
*)node
;
261 iter
->base
= node
->parent
.upper
+ 1;
262 iter
->offset
= up
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
264 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
266 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
272 node
= (DmaDisassemblyBufferNode
*)node
->parent
.next
;
276 else if (iter
->offset
< 0)
278 /* Need to go down if possible */
279 gint down
= (- iter
->offset
) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
287 iter
->node
= (DmaSparseBufferNode
*)node
;
288 iter
->line
= line
- down
;
289 iter
->base
= node
->data
[iter
->line
].address
;
295 if (iter
->node
->lower
== dma_sparse_buffer_get_lower (iter
->buffer
))
297 gboolean move
= iter
->line
!= 0;
299 iter
->node
= (DmaSparseBufferNode
*)node
;
301 iter
->base
= node
->data
[0].address
;
309 if ((node
->parent
.prev
== NULL
) || (node
->parent
.lower
!= node
->parent
.prev
->upper
+ 1))
311 /* No following node */
313 iter
->node
= (DmaSparseBufferNode
*)node
;
314 iter
->base
= node
->parent
.lower
;
315 iter
->offset
= -down
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
316 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
318 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
323 node
= (DmaDisassemblyBufferNode
*)node
->parent
.prev
;
330 if (iter
->offset
< 0)
333 gboolean move
= TRUE
;
335 address
= iter
->offset
+ iter
->base
;
336 if ((address
< dma_sparse_buffer_get_lower (iter
->buffer
)) || (address
> iter
->base
))
338 address
= dma_sparse_buffer_get_lower (iter
->buffer
);
341 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
342 iter
->offset
= address
- iter
->base
;
346 else if ((iter
->offset
> 0) || (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
))
349 gboolean move
= TRUE
;
351 address
= iter
->offset
+ iter
->base
;
352 if ((address
> dma_sparse_buffer_get_upper (iter
->buffer
)) || (address
< iter
->base
))
354 address
= dma_sparse_buffer_get_upper (iter
->buffer
);
357 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
358 iter
->offset
= address
- iter
->base
;
363 /* return FALSE if iterator reach the lower or upper limit */
368 dma_disassembly_iter_backward_line (DmaSparseIter
*iter
)
370 iter
->offset
-= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
371 return dma_disassembly_iter_refresh (iter
);
375 dma_disassembly_iter_forward_line (DmaSparseIter
*iter
)
377 iter
->offset
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
378 return dma_disassembly_iter_refresh (iter
);
383 dma_disassembly_iter_round (DmaSparseIter
*iter
, gboolean round_up
)
385 iter
->offset
+= round_up
? 1 : -1;
386 dma_disassembly_iter_refresh (iter
);
390 on_disassemble (const IAnjutaDebuggerInstructionDisassembly
*block
, DmaSparseBufferTransport
*trans
, GError
*err
)
392 DmaDisassemblyBufferNode
*node
;
393 DmaDisassemblyBuffer
*buffer
= (DmaDisassemblyBuffer
*)trans
->buffer
;
394 DmaSparseBufferNode
*next
;
398 DEBUG_PRINT ("on disassemble %p", block
);
400 if ((err
!= NULL
) && !g_error_matches (err
, IANJUTA_DEBUGGER_ERROR
, IANJUTA_DEBUGGER_UNABLE_TO_ACCESS_MEMORY
))
403 /* Command has been cancelled */
404 dma_sparse_buffer_free_transport (trans
);
409 /* Find following block */
410 DEBUG_PRINT("trans %p buffer %p trans->buffer %p trans->start %lu", trans
, buffer
, trans
== NULL
? NULL
: trans
->buffer
, trans
== NULL
? 0 : trans
->start
);
411 next
= dma_sparse_buffer_lookup (DMA_SPARSE_BUFFER (buffer
), trans
->start
+ trans
->length
- 1);
412 if ((next
!= NULL
) && (next
->upper
<= trans
->start
)) next
= NULL
;
416 gulong address
= trans
->start
;
419 /* Create a dummy node */
420 len
= (trans
->length
+ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
- 1) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
421 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * len
);
422 node
->parent
.lower
= address
;
423 for (i
= 0; i
< len
; i
++)
425 if ((next
!= NULL
) && (address
>= next
->lower
)) break;
426 node
->data
[i
].address
= address
;
427 node
->data
[i
].text
= "????????";
428 address
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
429 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
432 if ((next
!= NULL
) && (address
>= next
->lower
))
434 address
= next
->lower
-1;
438 address
= trans
->start
+ trans
->length
- 1;
440 node
->parent
.upper
= address
;
447 /* Compute size of all data */
448 /* use size -1 because last block has no data (NULL) */
449 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : 4; i
< block
->size
- 1; i
++)
451 if (block
->data
[i
].label
)
453 size
+= strlen(block
->data
[i
].label
) + 2;
456 size
+= strlen(block
->data
[i
].text
) + 1 + DMA_DISASSEMBLY_TAB_LENGTH
;
460 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * line
+ size
);
463 dst
= (gchar
*)&(node
->data
[line
]);
465 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
; i
< block
->size
- 1; i
++)
469 if ((next
!= NULL
) && (block
->data
[i
].address
== next
->lower
)) break;
471 /* Add label if exist */
472 if (block
->data
[i
].label
!= NULL
)
474 len
= strlen(block
->data
[i
].label
);
476 node
->data
[line
].address
= block
->data
[i
].address
;
477 node
->data
[line
].text
= dst
;
479 memcpy(dst
, block
->data
[i
].label
, len
);
487 /* Add disassembled instruction */
488 len
= strlen(block
->data
[i
].text
) + 1;
490 node
->data
[line
].address
= block
->data
[i
].address
;
491 node
->data
[line
].text
= dst
;
493 memset (dst
, ' ', DMA_DISASSEMBLY_TAB_LENGTH
);
494 memcpy (dst
+ DMA_DISASSEMBLY_TAB_LENGTH
, block
->data
[i
].text
, len
);
495 dst
+= len
+ DMA_DISASSEMBLY_TAB_LENGTH
;
499 /* fill last block */
501 node
->parent
.lower
= node
->data
[0].address
;
502 node
->parent
.upper
= block
->data
[i
].address
- 1;
506 dma_sparse_buffer_insert (DMA_SPARSE_BUFFER (buffer
), (DmaSparseBufferNode
*)node
);
507 dma_sparse_buffer_free_transport (trans
);
508 dma_sparse_buffer_changed (DMA_SPARSE_BUFFER (buffer
));
512 dma_disassembly_buffer_insert_line (DmaSparseIter
*iter
, GtkTextIter
*dst
)
514 DmaDisassemblyBuffer
* dis
= (DmaDisassemblyBuffer
*)iter
->buffer
;
515 GtkTextBuffer
*buffer
= gtk_text_iter_get_buffer (dst
);
517 if (dis
->debugger
!= NULL
)
519 dma_sparse_iter_refresh (iter
);
520 if (iter
->line
< DMA_DISASSEMBLY_VALID_ADDRESS
)
522 if (iter
->buffer
->pending
== NULL
)
525 DmaSparseBufferTransport
*trans
;
531 /* If following line is define, get a block stopping here */
532 dma_sparse_iter_copy (&end
, iter
);
534 for (j
= 0; j
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; j
++)
536 if (!dma_disassembly_iter_forward_line (&end
))
539 end
.base
= dma_sparse_buffer_get_upper (end
.buffer
);
542 if (margin
> DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
) break;
543 if ((margin
!= 0) || (end
.line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)) margin
++;
546 if (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
)
548 for (i
= j
; i
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; i
++)
550 if (!dma_disassembly_iter_backward_line (iter
)) break;
551 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
) break;
554 start_adr
= dma_sparse_iter_get_address (iter
);
555 end_adr
= dma_sparse_iter_get_address (&end
);
556 trans
= dma_sparse_buffer_alloc_transport (DMA_SPARSE_BUFFER (dis
), i
, 0);
557 trans
->tag
= i
!= j
? DMA_DISASSEMBLY_SKIP_BEGINNING
: DMA_DISASSEMBLY_KEEP_ALL
;
558 trans
->start
= start_adr
;
559 trans
->length
= end_adr
- start_adr
;
560 if (end_adr
== dma_sparse_buffer_get_upper (DMA_SPARSE_BUFFER (dis
)))
564 DEBUG_PRINT("get disassemble %lx %lx %ld trans %p buffer %p", start_adr
, end_adr
, trans
->length
, trans
, trans
->buffer
);
565 dma_queue_disassemble (dis
->debugger
, start_adr
, end_adr
+ 1 - start_adr
, (IAnjutaDebuggerCallback
)on_disassemble
, trans
);
570 /* Fill with known data */
571 gtk_text_buffer_insert (buffer
, dst
, ((DmaDisassemblyBufferNode
*)(iter
->node
))->data
[iter
->line
].text
, -1);
577 /* Fill with unknow data */
578 gtk_text_buffer_insert (buffer
, dst
, "??", 2);
582 dma_disassembly_buffer_class_init (DmaDisassemblyBufferClass
*klass
)
584 DmaSparseBufferClass
* buffer_class
;
586 g_return_if_fail (klass
!= NULL
);
588 parent_buffer_class
= (DmaSparseBufferClass
*) g_type_class_peek_parent (klass
);
590 buffer_class
= DMA_SPARSE_BUFFER_CLASS (klass
);
592 buffer_class
->refresh_iter
= dma_disassembly_iter_refresh
;
593 buffer_class
->round_iter
= dma_disassembly_iter_round
;
594 buffer_class
->insert_line
= dma_disassembly_buffer_insert_line
;
595 buffer_class
->forward_line
= dma_disassembly_iter_forward_line
;
596 buffer_class
->backward_line
= dma_disassembly_iter_backward_line
;
597 buffer_class
->get_address
= dma_disassembly_get_address
;
601 dma_disassembly_buffer_get_type (void)
603 static GType type
= 0;
607 static const GTypeInfo type_info
=
609 sizeof (DmaDisassemblyBufferClass
),
610 (GBaseInitFunc
) NULL
,
611 (GBaseFinalizeFunc
) NULL
,
612 (GClassInitFunc
) dma_disassembly_buffer_class_init
,
613 (GClassFinalizeFunc
) NULL
,
614 NULL
, /* class_data */
615 sizeof (DmaDisassemblyBuffer
),
617 (GInstanceInitFunc
) NULL
,
618 NULL
/* value_table */
621 type
= g_type_register_static (DMA_SPARSE_BUFFER_TYPE
,
622 "DmaDisassemblyBuffer", &type_info
, 0);
629 static DmaDisassemblyBuffer
*
630 dma_disassembly_buffer_new (DmaDebuggerQueue
*debugger
, gulong lower
, gulong upper
)
632 DmaDisassemblyBuffer
*buffer
;
634 buffer
= g_object_new (DMA_DISASSEMBLY_BUFFER_TYPE
, NULL
);
635 g_assert (buffer
!= NULL
);
637 buffer
->debugger
= debugger
;
639 DMA_SPARSE_BUFFER (buffer
)->lower
= lower
;
640 DMA_SPARSE_BUFFER (buffer
)->upper
= upper
;
645 /* Disassembly view object
646 *---------------------------------------------------------------------------*/
648 struct _DmaDisassemblyView
650 DmaSparseView parent
;
651 DmaDebuggerQueue
*debugger
;
655 struct _DmaDisassemblyViewClass
657 DmaSparseViewClass parent
;
660 #define DMA_DISASSEMBLY_VIEW_TYPE (dma_disassembly_view_get_type ())
661 #define DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyView))
662 #define DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
663 #define IS_DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DMA_DISASSEMBLY_VIEW_TYPE))
664 #define IS_DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DMA_DISASSEMBLY_VIEW_TYPE))
665 #define GET_DMA_DISASSEMBLY_VIEW_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
667 static DmaSparseViewClass
*parent_class
= NULL
;
669 static GType
dma_disassembly_view_get_type (void);
671 /* instance_init is the constructor. All functions should work after this
675 dma_disassembly_view_instance_init (DmaSparseView
*view
)
677 gtk_text_view_set_editable (GTK_TEXT_VIEW (view
), FALSE
);
680 /* class_init intialize the class itself not the instance */
683 dma_disassembly_view_class_init (DmaDisassemblyViewClass
*klass
)
685 g_return_if_fail (klass
!= NULL
);
687 parent_class
= (DmaSparseViewClass
*) g_type_class_peek_parent (klass
);
691 dma_disassembly_view_get_type (void)
693 static GType type
= 0;
697 static const GTypeInfo type_info
=
699 sizeof (DmaDisassemblyViewClass
),
700 (GBaseInitFunc
) NULL
,
701 (GBaseFinalizeFunc
) NULL
,
702 (GClassInitFunc
) dma_disassembly_view_class_init
,
703 (GClassFinalizeFunc
) NULL
,
704 NULL
, /* class_data */
705 sizeof (DmaDisassemblyView
),
707 (GInstanceInitFunc
) dma_disassembly_view_instance_init
,
708 NULL
/* value_table */
711 type
= g_type_register_static (DMA_SPARSE_VIEW_TYPE
,
712 "DmaDisassemblyView", &type_info
, 0);
719 static DmaDisassemblyView
*
720 dma_disassembly_view_new_with_buffer (DmaDebuggerQueue
*debugger
, DmaSparseBuffer
*buffer
)
722 DmaDisassemblyView
*view
;
724 view
= g_object_new (DMA_DISASSEMBLY_VIEW_TYPE
, "buffer", buffer
, NULL
);
725 g_assert (view
!= NULL
);
727 view
->debugger
= debugger
;
733 *---------------------------------------------------------------------------*/
736 on_disassembly_buffer_changed (DmaDisassemblyBuffer
*buffer
, DmaSparseView
*view
)
738 dma_sparse_view_refresh (view
);
742 on_breakpoint_changed (DmaDisassemble
*self
, IAnjutaDebuggerBreakpointItem
*bp
)
744 g_return_if_fail (bp
!= NULL
);
746 dma_sparse_view_unmark (self
->view
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
747 dma_sparse_view_unmark (self
->view
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_ENABLED
);
748 if (!(bp
->type
& IANJUTA_DEBUGGER_BREAKPOINT_REMOVED
))
750 dma_sparse_view_mark (self
->view
, bp
->address
, bp
->enable
? IANJUTA_MARKABLE_BREAKPOINT_ENABLED
: IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
755 destroy_disassemble_gui (DmaDisassemble
*self
)
758 if (self
->menu
!= NULL
)
760 gtk_widget_destroy (self
->menu
);
764 if (self
->window
!= NULL
)
766 gtk_widget_destroy (self
->window
);
774 dma_sparse_buffer_free (DMA_SPARSE_BUFFER (self
->buffer
));
780 on_program_running (DmaDisassemble
*self
)
782 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
786 on_program_moved (DmaDisassemble
*self
, guint pid
, guint tid
, gulong address
, const gchar
* file
, guint line
)
788 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
792 dma_sparse_view_mark (self
->view
, address
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
793 dma_sparse_view_goto (self
->view
, address
);
798 on_location_changed (DmaDisassemble
*self
, gulong address
, GFile
* file
, guint line
)
800 dma_sparse_view_goto (self
->view
, address
);
804 on_program_unloaded (DmaDisassemble
*self
)
806 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_unloaded
), self
);
807 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_breakpoint_changed
), self
);
808 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_running
), self
);
809 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_moved
), self
);
810 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_location_changed
), self
);
812 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
814 destroy_disassemble_gui (self
);
818 create_disassemble_gui (DmaDisassemble
*self
)
822 g_return_val_if_fail (self
->buffer
== NULL
, FALSE
);
823 g_return_val_if_fail (self
->window
== NULL
, FALSE
);
826 self
->buffer
= DMA_SPARSE_BUFFER (dma_disassembly_buffer_new (self
->debugger
, 0x00000000U
,0xFFFFFFFFU
));
827 if (self
->buffer
== NULL
) return FALSE
;
829 dataview
= GTK_WIDGET (dma_disassembly_view_new_with_buffer (self
->debugger
, self
->buffer
));
830 self
->view
= DMA_SPARSE_VIEW (dataview
);
831 DMA_DISASSEMBLY_VIEW (dataview
)->pending
= FALSE
;
832 g_signal_connect (G_OBJECT (self
->buffer
), "changed", G_CALLBACK (on_disassembly_buffer_changed
), self
->view
);
834 /* Add disassembly window */
835 self
->window
= gtk_scrolled_window_new (NULL
, NULL
);
836 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self
->window
),
837 GTK_POLICY_AUTOMATIC
,
838 GTK_POLICY_AUTOMATIC
);
839 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self
->window
),
841 gtk_container_add (GTK_CONTAINER (self
->window
), GTK_WIDGET (dataview
));
843 gtk_widget_show_all (self
->window
);
844 anjuta_shell_add_widget (ANJUTA_PLUGIN (self
->plugin
)->shell
,
846 "AnjutaDebuggerDisassemble", _("Disassembly"),
847 "debugger-disassembly", ANJUTA_SHELL_PLACEMENT_NONE
,
854 on_program_loaded (DmaDisassemble
*self
)
856 if (!dma_debugger_queue_is_supported (self
->debugger
, HAS_INSTRUCTION
)) return;
858 if (!create_disassemble_gui (self
)) return;
860 /* Connect signals */
861 g_signal_connect_swapped (self
->plugin
, "program-unloaded", G_CALLBACK (on_program_unloaded
), self
);
862 g_signal_connect_swapped (self
->plugin
, "breakpoint-changed", G_CALLBACK (on_breakpoint_changed
), self
);
863 g_signal_connect_swapped (self
->plugin
, "program-running", G_CALLBACK (on_program_running
), self
);
864 g_signal_connect_swapped (self
->plugin
, "program-moved", G_CALLBACK (on_program_moved
), self
);
865 g_signal_connect_swapped (self
->plugin
, "location-changed", G_CALLBACK (on_location_changed
), self
);
869 *---------------------------------------------------------------------------*/
872 dma_disassemble_is_focus (DmaDisassemble
*self
)
874 return gtk_widget_is_focus (GTK_WIDGET(self
->view
));
878 dma_disassemble_get_current_address (DmaDisassemble
*self
)
880 return dma_sparse_view_get_location (self
->view
);
883 /* Constructor & Destructor
884 *---------------------------------------------------------------------------*/
887 dma_disassemble_new(DebugManagerPlugin
*plugin
)
889 DmaDisassemble
* self
;
891 self
= g_new0 (DmaDisassemble
, 1);
893 self
->plugin
= plugin
;
894 self
->debugger
= dma_debug_manager_get_queue (plugin
);;
896 g_signal_connect_swapped (self
->plugin
, "program-loaded", G_CALLBACK (on_program_loaded
), self
);
902 dma_disassemble_free(DmaDisassemble
* self
)
904 g_return_if_fail (self
!= NULL
);
906 g_signal_handlers_disconnect_matched (self
->plugin
, G_SIGNAL_MATCH_DATA
, 0, 0, NULL
, NULL
, self
);
908 destroy_disassemble_gui (self
);