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>
36 #include "disassemble.h"
38 #include "sparse_buffer.h"
39 #include "sparse_view.h"
45 *---------------------------------------------------------------------------*/
47 enum {DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
= 256,
48 DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
= 4,
49 DMA_DISASSEMBLY_TAB_LENGTH
= 4,
50 DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
= 8,
51 DMA_DISASSEMBLY_PAGE_DISTANCE
= 4 * 60,
52 DMA_DISASSEMBLY_VALID_ADDRESS
= 0,
53 DMA_DISASSEMBLY_KNOW_ADDRESS
= -1,
54 DMA_DISASSEMBLY_UNKNOWN_ADDRESS
= -2};
56 enum {DMA_DISASSEMBLY_KEEP_ALL
,
57 DMA_DISASSEMBLY_SKIP_BEGINNING
};
60 *---------------------------------------------------------------------------*/
62 typedef struct _DmaDisassemblyLine DmaDisassemblyLine
;
63 typedef struct _DmaDisassemblyBufferNode DmaDisassemblyBufferNode
;
65 typedef struct _DmaDisassemblyBuffer DmaDisassemblyBuffer
;
66 typedef struct _DmaDisassemblyBufferClass DmaDisassemblyBufferClass
;
68 typedef struct _DmaDisassemblyView DmaDisassemblyView
;
69 typedef struct _DmaDisassemblyViewClass DmaDisassemblyViewClass
;
71 struct _DmaDisassemble
73 DmaDebuggerQueue
*debugger
;
74 DebugManagerPlugin
*plugin
;
77 DmaSparseBuffer
* buffer
;
81 /* Disassembly buffer object
82 *---------------------------------------------------------------------------*/
84 struct _DmaDisassemblyBuffer
86 DmaSparseBuffer parent
;
87 DmaDebuggerQueue
*debugger
;
91 struct _DmaDisassemblyBufferClass
93 DmaSparseBufferClass parent
;
96 struct _DmaDisassemblyLine
102 struct _DmaDisassemblyBufferNode
104 DmaSparseBufferNode parent
;
107 DmaDisassemblyLine data
[];
110 #define DMA_DISASSEMBLY_BUFFER_TYPE (dma_disassembly_buffer_get_type ())
111 #define DMA_DISASSEMBLY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBuffer))
112 #define DMA_DISASSEMBLY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBufferClass))
113 #define IS_DMA_DISASSEMBLY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DMA_DISASSEMBLY_BUFFER_TYPE))
114 #define IS_DMA_DISASSEMBLY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DMA_DISASSEMBLY_BUFFER_TYPE))
115 #define GET_DMA_DISASSEMBLY_BUFFER_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DMA_DISASSEMBLY_BUFFER_TYPE, DmaDisassemblyBufferClass))
117 static DmaSparseBufferClass
*parent_buffer_class
= NULL
;
119 static GType
dma_disassembly_buffer_get_type (void);
121 /* Disassembly iterator function
122 *---------------------------------------------------------------------------*/
125 * Iterator can be divided in 3 cases:
126 * 1. Iterator on valid address:
130 * line = line number in node
131 * 2. Iterator on know address:
135 * 3. Iterator on unknown address:
136 * base = address (often known)
137 * offset != 0 (could be 0 too)
139 *---------------------------------------------------------------------------*/
142 dma_disassembly_get_address (DmaSparseIter
*iter
)
144 return iter
->base
+ iter
->offset
;
148 dma_disassembly_iter_refresh (DmaSparseIter
*iter
)
150 /* Call this after updating node according to base */
152 DmaDisassemblyBufferNode
*node
= (DmaDisassemblyBufferNode
*)iter
->node
;
154 if (iter
->node
!= NULL
)
156 /* Find line corresponding to base */
157 if ((iter
->node
->lower
<= iter
->base
) && (iter
->base
<= iter
->node
->upper
))
159 /* Iterator in current node */
160 if ((iter
->line
>= 0) && (iter
->line
< ((DmaDisassemblyBufferNode
*)iter
->node
)->size
)
161 && (((DmaDisassemblyBufferNode
*)iter
->node
)->data
[iter
->line
].address
== iter
->base
))
163 /* Already get the right node */
168 /* Search for correct line */
170 if (iter
->offset
>= 0)
172 for (line
= 0; line
< node
->size
; line
++)
174 if (node
->data
[line
].address
>= iter
->base
) break;
179 for (line
= node
->size
- 1; line
>= 0; line
--)
181 if (node
->data
[line
].address
<= iter
->base
) break;
185 if (node
->data
[line
].address
== iter
->base
)
189 else if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
191 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
195 else if (iter
->base
== iter
->node
->upper
+ 1)
198 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
200 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
205 /* Invalid base address */
206 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
208 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
214 /* Invalid base address */
215 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
217 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
221 /* Try to reduce offset */
224 if (iter
->offset
> 0)
226 /* Need to go upper if possible */
227 guint up
= (DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
+ iter
->offset
- 1)/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
231 gint len
= node
->size
- line
;
235 iter
->node
= (DmaSparseBufferNode
*)node
;
236 iter
->line
= line
+ up
;
237 iter
->base
= node
->data
[iter
->line
].address
;
243 if (iter
->node
->upper
== dma_sparse_buffer_get_upper (iter
->buffer
))
245 gboolean move
= iter
->line
!= node
->size
- 1;
247 iter
->node
= (DmaSparseBufferNode
*)node
;
248 iter
->line
= node
->size
- 1;
249 iter
->base
= node
->data
[iter
->line
].address
;
257 if ((node
->parent
.next
== NULL
) || (node
->parent
.upper
!= node
->parent
.next
->lower
- 1))
259 /* No following node */
261 iter
->node
= (DmaSparseBufferNode
*)node
;
262 iter
->base
= node
->parent
.upper
+ 1;
263 iter
->offset
= up
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
265 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
267 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
273 node
= (DmaDisassemblyBufferNode
*)node
->parent
.next
;
277 else if (iter
->offset
< 0)
279 /* Need to go down if possible */
280 gint down
= (- iter
->offset
) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
288 iter
->node
= (DmaSparseBufferNode
*)node
;
289 iter
->line
= line
- down
;
290 iter
->base
= node
->data
[iter
->line
].address
;
296 if (iter
->node
->lower
== dma_sparse_buffer_get_lower (iter
->buffer
))
298 gboolean move
= iter
->line
!= 0;
300 iter
->node
= (DmaSparseBufferNode
*)node
;
302 iter
->base
= node
->data
[0].address
;
310 if ((node
->parent
.prev
== NULL
) || (node
->parent
.lower
!= node
->parent
.prev
->upper
+ 1))
312 /* No following node */
314 iter
->node
= (DmaSparseBufferNode
*)node
;
315 iter
->base
= node
->parent
.lower
;
316 iter
->offset
= -down
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
317 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
319 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
324 node
= (DmaDisassemblyBufferNode
*)node
->parent
.prev
;
331 if (iter
->offset
< 0)
334 gboolean move
= TRUE
;
336 address
= iter
->offset
+ iter
->base
;
337 if ((address
< dma_sparse_buffer_get_lower (iter
->buffer
)) || (address
> iter
->base
))
339 address
= dma_sparse_buffer_get_lower (iter
->buffer
);
342 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
343 iter
->offset
= address
- iter
->base
;
347 else if ((iter
->offset
> 0) || (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
))
350 gboolean move
= TRUE
;
352 address
= iter
->offset
+ iter
->base
;
353 if ((address
> dma_sparse_buffer_get_upper (iter
->buffer
)) || (address
< iter
->base
))
355 address
= dma_sparse_buffer_get_upper (iter
->buffer
);
358 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
359 iter
->offset
= address
- iter
->base
;
364 /* return FALSE if iterator reach the lower or upper limit */
369 dma_disassembly_iter_backward_line (DmaSparseIter
*iter
)
371 iter
->offset
-= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
372 return dma_disassembly_iter_refresh (iter
);
376 dma_disassembly_iter_forward_line (DmaSparseIter
*iter
)
378 iter
->offset
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
379 return dma_disassembly_iter_refresh (iter
);
384 dma_disassembly_iter_round (DmaSparseIter
*iter
, gboolean round_up
)
386 iter
->offset
+= round_up
? 1 : -1;
387 dma_disassembly_iter_refresh (iter
);
391 on_disassemble (const IAnjutaDebuggerInstructionDisassembly
*block
, DmaSparseBufferTransport
*trans
, GError
*err
)
393 DmaDisassemblyBufferNode
*node
;
394 DmaDisassemblyBuffer
*buffer
= (DmaDisassemblyBuffer
*)trans
->buffer
;
395 DmaSparseBufferNode
*next
;
399 DEBUG_PRINT ("on disassemble %p", block
);
401 if ((err
!= NULL
) && !g_error_matches (err
, IANJUTA_DEBUGGER_ERROR
, IANJUTA_DEBUGGER_UNABLE_TO_ACCESS_MEMORY
))
404 /* Command has been cancelled */
405 dma_sparse_buffer_free_transport (trans
);
410 /* Find following block */
411 DEBUG_PRINT("trans %p buffer %p trans->buffer %p trans->start %lu", trans
, buffer
, trans
== NULL
? NULL
: trans
->buffer
, trans
== NULL
? 0 : trans
->start
);
412 next
= dma_sparse_buffer_lookup (DMA_SPARSE_BUFFER (buffer
), trans
->start
+ trans
->length
- 1);
413 if ((next
!= NULL
) && (next
->upper
<= trans
->start
)) next
= NULL
;
417 gulong address
= trans
->start
;
420 /* Create a dummy node */
421 len
= (trans
->length
+ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
- 1) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
422 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * len
);
423 node
->parent
.lower
= address
;
424 for (i
= 0; i
< len
; i
++)
426 if ((next
!= NULL
) && (address
>= next
->lower
)) break;
427 node
->data
[i
].address
= address
;
428 node
->data
[i
].text
= "????????";
429 address
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
430 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
433 if ((next
!= NULL
) && (address
>= next
->lower
))
435 address
= next
->lower
-1;
439 address
= trans
->start
+ trans
->length
- 1;
441 node
->parent
.upper
= address
;
448 /* Compute size of all data */
449 /* use size -1 because last block has no data (NULL) */
450 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : 4; i
< block
->size
- 1; i
++)
452 if (block
->data
[i
].label
)
454 size
+= strlen(block
->data
[i
].label
) + 2;
457 size
+= strlen(block
->data
[i
].text
) + 1 + DMA_DISASSEMBLY_TAB_LENGTH
;
461 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * line
+ size
);
464 dst
= (gchar
*)&(node
->data
[line
]);
466 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
; i
< block
->size
- 1; i
++)
470 if ((next
!= NULL
) && (block
->data
[i
].address
== next
->lower
)) break;
472 /* Add label if exist */
473 if (block
->data
[i
].label
!= NULL
)
475 len
= strlen(block
->data
[i
].label
);
477 node
->data
[line
].address
= block
->data
[i
].address
;
478 node
->data
[line
].text
= dst
;
480 memcpy(dst
, block
->data
[i
].label
, len
);
488 /* Add disassembled instruction */
489 len
= strlen(block
->data
[i
].text
) + 1;
491 node
->data
[line
].address
= block
->data
[i
].address
;
492 node
->data
[line
].text
= dst
;
494 memset (dst
, ' ', DMA_DISASSEMBLY_TAB_LENGTH
);
495 memcpy (dst
+ DMA_DISASSEMBLY_TAB_LENGTH
, block
->data
[i
].text
, len
);
496 dst
+= len
+ DMA_DISASSEMBLY_TAB_LENGTH
;
500 /* fill last block */
502 node
->parent
.lower
= node
->data
[0].address
;
503 node
->parent
.upper
= block
->data
[i
].address
- 1;
507 dma_sparse_buffer_insert (DMA_SPARSE_BUFFER (buffer
), (DmaSparseBufferNode
*)node
);
508 dma_sparse_buffer_free_transport (trans
);
509 dma_sparse_buffer_changed (DMA_SPARSE_BUFFER (buffer
));
513 dma_disassembly_buffer_insert_line (DmaSparseIter
*iter
, GtkTextIter
*dst
)
515 DmaDisassemblyBuffer
* dis
= (DmaDisassemblyBuffer
*)iter
->buffer
;
516 GtkTextBuffer
*buffer
= gtk_text_iter_get_buffer (dst
);
518 if (dis
->debugger
!= NULL
)
520 dma_sparse_iter_refresh (iter
);
521 if (iter
->line
< DMA_DISASSEMBLY_VALID_ADDRESS
)
523 if (iter
->buffer
->pending
== NULL
)
526 DmaSparseBufferTransport
*trans
;
532 /* If following line is define, get a block stopping here */
533 dma_sparse_iter_copy (&end
, iter
);
535 for (j
= 0; j
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; j
++)
537 if (!dma_disassembly_iter_forward_line (&end
))
540 end
.base
= dma_sparse_buffer_get_upper (end
.buffer
);
543 if (margin
> DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
) break;
544 if ((margin
!= 0) || (end
.line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)) margin
++;
547 if (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
)
549 for (i
= j
; i
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; i
++)
551 if (!dma_disassembly_iter_backward_line (iter
)) break;
552 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
) break;
555 start_adr
= dma_sparse_iter_get_address (iter
);
556 end_adr
= dma_sparse_iter_get_address (&end
);
557 trans
= dma_sparse_buffer_alloc_transport (DMA_SPARSE_BUFFER (dis
), i
, 0);
558 trans
->tag
= i
!= j
? DMA_DISASSEMBLY_SKIP_BEGINNING
: DMA_DISASSEMBLY_KEEP_ALL
;
559 trans
->start
= start_adr
;
560 trans
->length
= end_adr
- start_adr
;
561 if (end_adr
== dma_sparse_buffer_get_upper (DMA_SPARSE_BUFFER (dis
)))
565 DEBUG_PRINT("get disassemble %lx %lx %ld trans %p buffer %p", start_adr
, end_adr
, trans
->length
, trans
, trans
->buffer
);
566 dma_queue_disassemble (dis
->debugger
, start_adr
, end_adr
+ 1 - start_adr
, (IAnjutaDebuggerCallback
)on_disassemble
, trans
);
571 /* Fill with known data */
572 gtk_text_buffer_insert (buffer
, dst
, ((DmaDisassemblyBufferNode
*)(iter
->node
))->data
[iter
->line
].text
, -1);
578 /* Fill with unknow data */
579 gtk_text_buffer_insert (buffer
, dst
, "??", 2);
583 dma_disassembly_buffer_class_init (DmaDisassemblyBufferClass
*klass
)
585 DmaSparseBufferClass
* buffer_class
;
587 g_return_if_fail (klass
!= NULL
);
589 parent_buffer_class
= (DmaSparseBufferClass
*) g_type_class_peek_parent (klass
);
591 buffer_class
= DMA_SPARSE_BUFFER_CLASS (klass
);
593 buffer_class
->refresh_iter
= dma_disassembly_iter_refresh
;
594 buffer_class
->round_iter
= dma_disassembly_iter_round
;
595 buffer_class
->insert_line
= dma_disassembly_buffer_insert_line
;
596 buffer_class
->forward_line
= dma_disassembly_iter_forward_line
;
597 buffer_class
->backward_line
= dma_disassembly_iter_backward_line
;
598 buffer_class
->get_address
= dma_disassembly_get_address
;
602 dma_disassembly_buffer_get_type (void)
604 static GType type
= 0;
608 static const GTypeInfo type_info
=
610 sizeof (DmaDisassemblyBufferClass
),
611 (GBaseInitFunc
) NULL
,
612 (GBaseFinalizeFunc
) NULL
,
613 (GClassInitFunc
) dma_disassembly_buffer_class_init
,
614 (GClassFinalizeFunc
) NULL
,
615 NULL
, /* class_data */
616 sizeof (DmaDisassemblyBuffer
),
618 (GInstanceInitFunc
) NULL
,
619 NULL
/* value_table */
622 type
= g_type_register_static (DMA_SPARSE_BUFFER_TYPE
,
623 "DmaDisassemblyBuffer", &type_info
, 0);
630 static DmaDisassemblyBuffer
*
631 dma_disassembly_buffer_new (DmaDebuggerQueue
*debugger
, gulong lower
, gulong upper
)
633 DmaDisassemblyBuffer
*buffer
;
635 buffer
= g_object_new (DMA_DISASSEMBLY_BUFFER_TYPE
, NULL
);
636 g_assert (buffer
!= NULL
);
638 buffer
->debugger
= debugger
;
640 DMA_SPARSE_BUFFER (buffer
)->lower
= lower
;
641 DMA_SPARSE_BUFFER (buffer
)->upper
= upper
;
646 /* Disassembly view object
647 *---------------------------------------------------------------------------*/
649 struct _DmaDisassemblyView
651 DmaSparseView parent
;
652 DmaDebuggerQueue
*debugger
;
656 struct _DmaDisassemblyViewClass
658 DmaSparseViewClass parent
;
661 #define DMA_DISASSEMBLY_VIEW_TYPE (dma_disassembly_view_get_type ())
662 #define DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyView))
663 #define DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
664 #define IS_DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DMA_DISASSEMBLY_VIEW_TYPE))
665 #define IS_DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DMA_DISASSEMBLY_VIEW_TYPE))
666 #define GET_DMA_DISASSEMBLY_VIEW_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
668 static DmaSparseViewClass
*parent_class
= NULL
;
670 static GType
dma_disassembly_view_get_type (void);
672 /* instance_init is the constructor. All functions should work after this
676 dma_disassembly_view_instance_init (DmaSparseView
*view
)
678 gtk_text_view_set_editable (GTK_TEXT_VIEW (view
), FALSE
);
681 /* class_init intialize the class itself not the instance */
684 dma_disassembly_view_class_init (DmaDisassemblyViewClass
*klass
)
686 DmaSparseViewClass
* view_class
;
688 g_return_if_fail (klass
!= NULL
);
690 parent_class
= (DmaSparseViewClass
*) g_type_class_peek_parent (klass
);
692 view_class
= DMA_SPARSE_VIEW_CLASS (klass
);
696 dma_disassembly_view_get_type (void)
698 static GType type
= 0;
702 static const GTypeInfo type_info
=
704 sizeof (DmaDisassemblyViewClass
),
705 (GBaseInitFunc
) NULL
,
706 (GBaseFinalizeFunc
) NULL
,
707 (GClassInitFunc
) dma_disassembly_view_class_init
,
708 (GClassFinalizeFunc
) NULL
,
709 NULL
, /* class_data */
710 sizeof (DmaDisassemblyView
),
712 (GInstanceInitFunc
) dma_disassembly_view_instance_init
,
713 NULL
/* value_table */
716 type
= g_type_register_static (DMA_SPARSE_VIEW_TYPE
,
717 "DmaDisassemblyView", &type_info
, 0);
724 static DmaDisassemblyView
*
725 dma_disassembly_view_new_with_buffer (DmaDebuggerQueue
*debugger
, DmaSparseBuffer
*buffer
)
727 DmaDisassemblyView
*view
;
729 view
= g_object_new (DMA_DISASSEMBLY_VIEW_TYPE
, NULL
);
730 g_assert (view
!= NULL
);
732 view
->debugger
= debugger
;
734 dma_sparse_view_set_sparse_buffer (DMA_SPARSE_VIEW(view
), buffer
);
740 *---------------------------------------------------------------------------*/
743 on_disassembly_buffer_changed (DmaDisassemblyBuffer
*buffer
, DmaSparseView
*view
)
745 dma_sparse_view_refresh (view
);
749 on_breakpoint_changed (DmaDisassemble
*self
, IAnjutaDebuggerBreakpointItem
*bp
)
751 g_return_if_fail (bp
!= NULL
);
753 dma_sparse_view_unmark (self
->view
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
754 dma_sparse_view_unmark (self
->view
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_ENABLED
);
755 if (!(bp
->type
& IANJUTA_DEBUGGER_BREAKPOINT_REMOVED
))
757 dma_sparse_view_mark (self
->view
, bp
->address
, bp
->enable
? IANJUTA_MARKABLE_BREAKPOINT_ENABLED
: IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
762 destroy_disassemble_gui (DmaDisassemble
*self
)
765 if (self
->menu
!= NULL
)
767 gtk_widget_destroy (self
->menu
);
771 if (self
->window
!= NULL
)
773 gtk_widget_destroy (self
->window
);
781 dma_sparse_buffer_free (DMA_SPARSE_BUFFER (self
->buffer
));
787 on_program_running (DmaDisassemble
*self
)
789 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
793 on_program_moved (DmaDisassemble
*self
, guint pid
, guint tid
, gulong address
, const gchar
* file
, guint line
)
795 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
799 dma_sparse_view_mark (self
->view
, address
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
800 dma_sparse_view_goto (self
->view
, address
);
805 on_location_changed (DmaDisassemble
*self
, gulong address
, GFile
* file
, guint line
)
807 dma_sparse_view_goto (self
->view
, address
);
811 on_program_unloaded (DmaDisassemble
*self
)
813 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_unloaded
), self
);
814 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_breakpoint_changed
), self
);
815 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_running
), self
);
816 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_program_moved
), self
);
817 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_location_changed
), self
);
819 dma_sparse_view_delete_all_markers (self
->view
, IANJUTA_MARKABLE_PROGRAM_COUNTER
);
821 destroy_disassemble_gui (self
);
825 create_disassemble_gui (DmaDisassemble
*self
)
829 g_return_val_if_fail (self
->buffer
== NULL
, FALSE
);
830 g_return_val_if_fail (self
->window
== NULL
, FALSE
);
833 self
->buffer
= DMA_SPARSE_BUFFER (dma_disassembly_buffer_new (self
->debugger
, 0x00000000U
,0xFFFFFFFFU
));
834 if (self
->buffer
== NULL
) return FALSE
;
836 dataview
= GTK_WIDGET (dma_disassembly_view_new_with_buffer (self
->debugger
, self
->buffer
));
837 self
->view
= DMA_SPARSE_VIEW (dataview
);
838 DMA_DISASSEMBLY_VIEW (dataview
)->pending
= FALSE
;
839 g_signal_connect (G_OBJECT (self
->buffer
), "changed", G_CALLBACK (on_disassembly_buffer_changed
), self
->view
);
841 /* Add disassembly window */
842 self
->window
= gtk_scrolled_window_new (NULL
, NULL
);
843 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self
->window
),
844 GTK_POLICY_AUTOMATIC
,
845 GTK_POLICY_AUTOMATIC
);
846 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self
->window
),
848 gtk_container_add (GTK_CONTAINER (self
->window
), GTK_WIDGET (dataview
));
850 anjuta_shell_add_widget (ANJUTA_PLUGIN (self
->plugin
)->shell
,
852 "AnjutaDebuggerDisassemble", _("Disassembly"),
853 NULL
, ANJUTA_SHELL_PLACEMENT_LEFT
,
860 on_program_loaded (DmaDisassemble
*self
)
862 if (!dma_debugger_queue_is_supported (self
->debugger
, HAS_INSTRUCTION
)) return;
864 if (!create_disassemble_gui (self
)) return;
866 /* Connect signals */
867 g_signal_connect_swapped (self
->plugin
, "program-unloaded", G_CALLBACK (on_program_unloaded
), self
);
868 g_signal_connect_swapped (self
->plugin
, "breakpoint-changed", G_CALLBACK (on_breakpoint_changed
), self
);
869 g_signal_connect_swapped (self
->plugin
, "program-running", G_CALLBACK (on_program_running
), self
);
870 g_signal_connect_swapped (self
->plugin
, "program-moved", G_CALLBACK (on_program_moved
), self
);
871 g_signal_connect_swapped (self
->plugin
, "location-changed", G_CALLBACK (on_location_changed
), self
);
875 *---------------------------------------------------------------------------*/
878 dma_disassemble_is_focus (DmaDisassemble
*self
)
880 return gtk_widget_is_focus (GTK_WIDGET(self
->view
));
884 dma_disassemble_get_current_address (DmaDisassemble
*self
)
886 return dma_sparse_view_get_location (self
->view
);
889 /* Constructor & Destructor
890 *---------------------------------------------------------------------------*/
893 dma_disassemble_new(DebugManagerPlugin
*plugin
)
895 DmaDisassemble
* self
;
897 self
= g_new0 (DmaDisassemble
, 1);
899 self
->plugin
= plugin
;
900 self
->debugger
= dma_debug_manager_get_queue (plugin
);;
902 g_signal_connect_swapped (self
->plugin
, "program-loaded", G_CALLBACK (on_program_loaded
), self
);
908 dma_disassemble_free(DmaDisassemble
* self
)
910 g_return_if_fail (self
!= NULL
);
912 g_signal_handlers_disconnect_matched (self
->plugin
, G_SIGNAL_MATCH_DATA
, 0, 0, NULL
, NULL
, self
);
914 destroy_disassemble_gui (self
);