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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
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 IAnjutaDebugger
*debugger
;
73 DebugManagerPlugin
*plugin
;
76 DmaSparseBuffer
* buffer
;
80 /* Disassembly buffer object
81 *---------------------------------------------------------------------------*/
83 struct _DmaDisassemblyBuffer
85 DmaSparseBuffer parent
;
86 IAnjutaDebugger
*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 DEBUG_PRINT("iter_refresh iter->node %p (%x, %d), base %lx offset %ld", iter
->node
, iter
->node
!= NULL
? iter
->node
->lower
: 0, iter
->node
!= NULL
? ((DmaDisassemblyBufferNode
*)iter
->node
)->size
: 0, iter
->base
, iter
->offset
);
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 */
222 DEBUG_PRINT("iter_refresh offset iter->node %p, base %lx offset %ld line %d line %d", iter
->node
, iter
->base
, iter
->offset
, iter
->line
, line
);
225 if (iter
->offset
> 0)
227 /* Need to go upper if possible */
228 guint up
= (DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
+ iter
->offset
- 1)/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
232 gint len
= node
->size
- line
;
236 iter
->node
= (DmaSparseBufferNode
*)node
;
237 iter
->line
= line
+ up
;
238 iter
->base
= node
->data
[iter
->line
].address
;
244 if (iter
->node
->upper
== dma_sparse_buffer_get_upper (iter
->buffer
))
246 gboolean move
= iter
->line
!= node
->size
- 1;
248 iter
->node
= (DmaSparseBufferNode
*)node
;
249 iter
->line
= node
->size
- 1;
250 iter
->base
= node
->data
[iter
->line
].address
;
258 if ((node
->parent
.next
== NULL
) || (node
->parent
.upper
!= node
->parent
.next
->lower
- 1))
260 /* No following node */
262 iter
->node
= (DmaSparseBufferNode
*)node
;
263 iter
->base
= node
->parent
.upper
+ 1;
264 iter
->offset
= up
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
266 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
268 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
274 node
= (DmaDisassemblyBufferNode
*)node
->parent
.next
;
278 else if (iter
->offset
< 0)
280 /* Need to go down if possible */
281 gint down
= (- iter
->offset
) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
289 iter
->node
= (DmaSparseBufferNode
*)node
;
290 iter
->line
= line
- down
;
291 iter
->base
= node
->data
[iter
->line
].address
;
297 if (iter
->node
->lower
== dma_sparse_buffer_get_lower (iter
->buffer
))
299 gboolean move
= iter
->line
!= 0;
301 iter
->node
= (DmaSparseBufferNode
*)node
;
303 iter
->base
= node
->data
[0].address
;
311 if ((node
->parent
.prev
== NULL
) || (node
->parent
.lower
!= node
->parent
.prev
->upper
+ 1))
313 /* No following node */
315 iter
->node
= (DmaSparseBufferNode
*)node
;
316 iter
->base
= node
->parent
.lower
;
317 iter
->offset
= -down
* DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
318 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)
320 iter
->line
= iter
->offset
== 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS
: DMA_DISASSEMBLY_UNKNOWN_ADDRESS
;
325 node
= (DmaDisassemblyBufferNode
*)node
->parent
.prev
;
332 DEBUG_PRINT("iter_refresh round iter->node %p, base %lx offset %ld line %d line %d", iter
->node
, iter
->base
, iter
->offset
, iter
->line
, line
);
333 if (iter
->offset
< 0)
336 gboolean move
= TRUE
;
338 address
= iter
->offset
+ iter
->base
;
339 if ((address
< dma_sparse_buffer_get_lower (iter
->buffer
)) || (address
> iter
->base
))
341 address
= dma_sparse_buffer_get_lower (iter
->buffer
);
344 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
345 iter
->offset
= address
- iter
->base
;
349 else if ((iter
->offset
> 0) || (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
))
352 gboolean move
= TRUE
;
354 address
= iter
->offset
+ iter
->base
;
355 if ((address
> dma_sparse_buffer_get_upper (iter
->buffer
)) || (address
< iter
->base
))
357 address
= dma_sparse_buffer_get_upper (iter
->buffer
);
360 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
361 iter
->offset
= address
- iter
->base
;
366 /* return FALSE if iterator reach the lower or upper limit */
371 dma_disassembly_iter_backward_line (DmaSparseIter
*iter
)
373 iter
->offset
-= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
374 return dma_disassembly_iter_refresh (iter
);
378 dma_disassembly_iter_forward_line (DmaSparseIter
*iter
)
380 iter
->offset
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
381 return dma_disassembly_iter_refresh (iter
);
386 dma_disassembly_iter_round (DmaSparseIter
*iter
, gboolean round_up
)
388 iter
->offset
+= round_up
? 1 : -1;
389 dma_disassembly_iter_refresh (iter
);
393 on_disassemble (const IAnjutaDebuggerDisassembly
*block
, DmaSparseBufferTransport
*trans
, GError
*err
)
395 DmaDisassemblyBufferNode
*node
;
396 DmaDisassemblyBuffer
*buffer
= (DmaDisassemblyBuffer
*)trans
->buffer
;
397 DmaSparseBufferNode
*next
;
401 DEBUG_PRINT ("on disassemble %p", block
);
403 if ((err
!= NULL
) && !g_error_matches (err
, IANJUTA_DEBUGGER_ERROR
, IANJUTA_DEBUGGER_UNABLE_TO_ACCESS_MEMORY
))
406 /* Command has been cancelled */
407 dma_sparse_buffer_free_transport (trans
);
412 /* Find following block */
413 next
= dma_sparse_buffer_lookup (DMA_SPARSE_BUFFER (buffer
), trans
->start
+ trans
->length
- 1);
414 if ((next
!= NULL
) && (next
->upper
<= trans
->start
)) next
= NULL
;
418 gulong address
= trans
->start
;
421 DEBUG_PRINT ("Create a dummy disassembly node");
423 /* Create a dummy node */
424 len
= (trans
->length
+ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
- 1) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
425 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * len
);
426 node
->parent
.lower
= address
;
427 for (i
= 0; i
< len
; i
++)
429 if ((next
!= NULL
) && (address
>= next
->lower
)) break;
430 node
->data
[i
].address
= address
;
431 node
->data
[i
].text
= "????????";
432 address
+= DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
433 address
-= address
% DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
;
436 if ((next
!= NULL
) && (address
>= next
->lower
))
438 address
= next
->lower
-1;
442 address
= trans
->start
+ trans
->length
- 1;
444 node
->parent
.upper
= address
;
451 DEBUG_PRINT ("on disassemble size %d", block
->size
);
452 /* Compute size of all data */
453 /* use size -1 because last block has no data (NULL) */
454 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : 4; i
< block
->size
- 1; i
++)
456 if (block
->data
[i
].label
)
458 size
+= strlen(block
->data
[i
].label
) + 2;
461 size
+= strlen(block
->data
[i
].text
) + 1 + DMA_DISASSEMBLY_TAB_LENGTH
;
465 node
= (DmaDisassemblyBufferNode
*)g_malloc0 (sizeof(DmaDisassemblyBufferNode
) + sizeof(DmaDisassemblyLine
) * line
+ size
);
468 dst
= (gchar
*)&(node
->data
[line
]);
470 for (i
= trans
->tag
== DMA_DISASSEMBLY_KEEP_ALL
? 0 : DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
; i
< block
->size
- 1; i
++)
474 if ((next
!= NULL
) && (block
->data
[i
].address
== next
->lower
)) break;
476 /* Add label if exist */
477 if (block
->data
[i
].label
!= NULL
)
479 len
= strlen(block
->data
[i
].label
);
481 node
->data
[line
].address
= block
->data
[i
].address
;
482 node
->data
[line
].text
= dst
;
484 memcpy(dst
, block
->data
[i
].label
, len
);
492 /* Add disassembled instruction */
493 len
= strlen(block
->data
[i
].text
) + 1;
495 node
->data
[line
].address
= block
->data
[i
].address
;
496 node
->data
[line
].text
= dst
;
498 memset (dst
, ' ', DMA_DISASSEMBLY_TAB_LENGTH
);
499 memcpy (dst
+ DMA_DISASSEMBLY_TAB_LENGTH
, block
->data
[i
].text
, len
);
500 dst
+= len
+ DMA_DISASSEMBLY_TAB_LENGTH
;
504 /* fill last block */
506 node
->parent
.lower
= node
->data
[0].address
;
507 node
->parent
.upper
= block
->data
[i
].address
- 1;
511 dma_sparse_buffer_insert (DMA_SPARSE_BUFFER (buffer
), (DmaSparseBufferNode
*)node
);
512 dma_sparse_buffer_free_transport (trans
);
513 dma_sparse_buffer_changed (DMA_SPARSE_BUFFER (buffer
));
517 dma_disassembly_buffer_insert_line (DmaSparseIter
*iter
, GtkTextIter
*dst
)
519 DmaDisassemblyBuffer
* dis
= (DmaDisassemblyBuffer
*)iter
->buffer
;
520 GtkTextBuffer
*buffer
= gtk_text_iter_get_buffer (dst
);
522 if (dis
->debugger
!= NULL
)
524 dma_sparse_iter_refresh (iter
);
525 if (iter
->line
< DMA_DISASSEMBLY_VALID_ADDRESS
)
527 if (iter
->buffer
->pending
== NULL
)
530 DmaSparseBufferTransport
*trans
;
536 DEBUG_PRINT("no data at address %lx + %ld", iter
->base
, iter
->offset
);
538 /* If following line is define, get a block stopping here */
539 dma_sparse_iter_copy (&end
, iter
);
541 for (j
= 0; j
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; j
++)
543 if (!dma_disassembly_iter_forward_line (&end
))
546 end
.base
= dma_sparse_buffer_get_upper (end
.buffer
);
549 if (margin
> DMA_DISASSEMBLY_SKIP_BEGINNING_LINE
) break;
550 if ((margin
!= 0) || (end
.line
>= DMA_DISASSEMBLY_VALID_ADDRESS
)) margin
++;
553 if (iter
->line
== DMA_DISASSEMBLY_UNKNOWN_ADDRESS
)
555 for (i
= j
; i
< DMA_DISASSEMBLY_BUFFER_BLOCK_SIZE
/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH
; i
++)
557 if (!dma_disassembly_iter_backward_line (iter
)) break;
558 if (iter
->line
>= DMA_DISASSEMBLY_VALID_ADDRESS
) break;
561 start_adr
= dma_sparse_iter_get_address (iter
);
562 end_adr
= dma_sparse_iter_get_address (&end
);
563 trans
= dma_sparse_buffer_alloc_transport (DMA_SPARSE_BUFFER (dis
), i
, 0);
564 trans
->tag
= i
!= j
? DMA_DISASSEMBLY_SKIP_BEGINNING
: DMA_DISASSEMBLY_KEEP_ALL
;
565 trans
->start
= start_adr
;
566 trans
->length
= end_adr
- start_adr
;
567 if (end_adr
== dma_sparse_buffer_get_upper (DMA_SPARSE_BUFFER (dis
)))
571 DEBUG_PRINT("get disassemble %lx %lx %ld", start_adr
, end_adr
, trans
->length
);
572 ianjuta_cpu_debugger_disassemble ((IAnjutaCpuDebugger
*)dis
->debugger
, start_adr
, end_adr
+ 1 - start_adr
, (IAnjutaDebuggerCallback
)on_disassemble
, trans
, NULL
);
577 /* Fill with known data */
578 gtk_text_buffer_insert (buffer
, dst
, ((DmaDisassemblyBufferNode
*)(iter
->node
))->data
[iter
->line
].text
, -1);
584 /* Fill with unknow data */
585 gtk_text_buffer_insert (buffer
, dst
, "??", 2);
589 dma_disassembly_buffer_class_init (DmaDisassemblyBufferClass
*klass
)
591 DmaSparseBufferClass
* buffer_class
;
593 g_return_if_fail (klass
!= NULL
);
595 parent_buffer_class
= (DmaSparseBufferClass
*) g_type_class_peek_parent (klass
);
597 buffer_class
= DMA_SPARSE_BUFFER_CLASS (klass
);
599 buffer_class
->refresh_iter
= dma_disassembly_iter_refresh
;
600 buffer_class
->round_iter
= dma_disassembly_iter_round
;
601 buffer_class
->insert_line
= dma_disassembly_buffer_insert_line
;
602 buffer_class
->forward_line
= dma_disassembly_iter_forward_line
;
603 buffer_class
->backward_line
= dma_disassembly_iter_backward_line
;
604 buffer_class
->get_address
= dma_disassembly_get_address
;
608 dma_disassembly_buffer_get_type (void)
610 static GType type
= 0;
614 static const GTypeInfo type_info
=
616 sizeof (DmaDisassemblyBufferClass
),
617 (GBaseInitFunc
) NULL
,
618 (GBaseFinalizeFunc
) NULL
,
619 (GClassInitFunc
) dma_disassembly_buffer_class_init
,
620 (GClassFinalizeFunc
) NULL
,
621 NULL
, /* class_data */
622 sizeof (DmaDisassemblyBuffer
),
624 (GInstanceInitFunc
) NULL
,
625 NULL
/* value_table */
628 type
= g_type_register_static (DMA_SPARSE_BUFFER_TYPE
,
629 "DmaDisassemblyBuffer", &type_info
, 0);
636 static DmaDisassemblyBuffer
*
637 dma_disassembly_buffer_new (IAnjutaDebugger
*debugger
, gulong lower
, gulong upper
)
639 DmaDisassemblyBuffer
*buffer
;
641 buffer
= g_object_new (DMA_DISASSEMBLY_BUFFER_TYPE
, NULL
);
642 g_assert (buffer
!= NULL
);
644 buffer
->debugger
= debugger
;
646 DMA_SPARSE_BUFFER (buffer
)->lower
= lower
;
647 DMA_SPARSE_BUFFER (buffer
)->upper
= upper
;
653 dma_disassembly_buffer_free (DmaDisassemblyBuffer
*buffer
)
655 g_object_unref (buffer
);
659 /* Disassembly view object
660 *---------------------------------------------------------------------------*/
662 struct _DmaDisassemblyView
664 DmaSparseView parent
;
665 IAnjutaDebugger
*debugger
;
669 struct _DmaDisassemblyViewClass
671 DmaSparseViewClass parent
;
674 #define DMA_DISASSEMBLY_VIEW_TYPE (dma_disassembly_view_get_type ())
675 #define DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyView))
676 #define DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
677 #define IS_DMA_DISASSEMBLY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DMA_DISASSEMBLY_VIEW_TYPE))
678 #define IS_DMA_DISASSEMBLY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DMA_DISASSEMBLY_VIEW_TYPE))
679 #define GET_DMA_DISASSEMBLY_VIEW_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DMA_DISASSEMBLY_VIEW_TYPE, DmaDisassemblyViewClass))
681 static DmaSparseViewClass
*parent_class
= NULL
;
683 static GType
dma_disassembly_view_get_type (void);
686 dma_disassembly_view_class_init (DmaDisassemblyViewClass
*klass
)
688 DmaSparseViewClass
* view_class
;
690 g_return_if_fail (klass
!= NULL
);
692 parent_class
= (DmaSparseViewClass
*) g_type_class_peek_parent (klass
);
694 view_class
= DMA_SPARSE_VIEW_CLASS (klass
);
698 dma_disassembly_view_get_type (void)
700 static GType type
= 0;
704 static const GTypeInfo type_info
=
706 sizeof (DmaDisassemblyViewClass
),
707 (GBaseInitFunc
) NULL
,
708 (GBaseFinalizeFunc
) NULL
,
709 (GClassInitFunc
) dma_disassembly_view_class_init
,
710 (GClassFinalizeFunc
) NULL
,
711 NULL
, /* class_data */
712 sizeof (DmaDisassemblyView
),
714 (GInstanceInitFunc
) NULL
,
715 NULL
/* value_table */
718 type
= g_type_register_static (DMA_SPARSE_VIEW_TYPE
,
719 "DmaDisassemblyView", &type_info
, 0);
726 static DmaDisassemblyView
*
727 dma_disassembly_view_new_with_buffer (IAnjutaDebugger
*debugger
, DmaSparseBuffer
*buffer
)
729 DmaDisassemblyView
*view
;
731 view
= g_object_new (DMA_DISASSEMBLY_VIEW_TYPE
, NULL
);
732 g_assert (view
!= NULL
);
734 view
->debugger
= debugger
;
736 dma_sparse_view_set_sparse_buffer (DMA_SPARSE_VIEW(view
), buffer
);
742 dma_disassembly_view_free (DmaDisassemblyView
*view
)
744 g_object_unref (view
);
748 *---------------------------------------------------------------------------*/
751 on_disassembly_buffer_changed (DmaDisassemblyBuffer
*buffer
, DmaSparseView
*view
)
753 dma_sparse_view_refresh (view
);
757 on_breakpoint_changed (DmaDisassemble
*self
, IAnjutaDebuggerBreakpoint
*bp
)
759 g_return_if_fail (bp
!= NULL
);
761 dma_disassemble_unmark (self
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
762 dma_disassemble_unmark (self
, bp
->address
, IANJUTA_MARKABLE_BREAKPOINT_ENABLED
);
763 if (bp
->type
!= IANJUTA_DEBUGGER_BREAK_REMOVED
)
765 dma_disassemble_mark (self
, bp
->address
, bp
->enable
? IANJUTA_MARKABLE_BREAKPOINT_ENABLED
: IANJUTA_MARKABLE_BREAKPOINT_DISABLED
);
770 create_disassemble_gui (DmaDisassemble
*self
)
774 dataview
= GTK_WIDGET (dma_disassembly_view_new_with_buffer (self
->debugger
, self
->buffer
));
776 /* Add register window */
777 self
->window
= gtk_scrolled_window_new (NULL
, NULL
);
778 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self
->window
),
779 GTK_POLICY_AUTOMATIC
,
780 GTK_POLICY_AUTOMATIC
);
781 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self
->window
),
783 gtk_container_add (GTK_CONTAINER (self
->window
), GTK_WIDGET (dataview
));
785 anjuta_shell_add_widget (ANJUTA_PLUGIN (self
->plugin
)->shell
,
787 "AnjutaDebuggerDisassemble", _("Disassembly"),
788 NULL
, ANJUTA_SHELL_PLACEMENT_LEFT
,
792 DMA_DISASSEMBLY_VIEW (dataview
)->pending
= FALSE
;
798 on_debugger_started (DmaDisassemble
*self
)
800 self
->buffer
= DMA_SPARSE_BUFFER (dma_disassembly_buffer_new (self
->debugger
, 0x00000000U
,0xFFFFFFFFU
));
802 self
->view
= DMA_SPARSE_VIEW (create_disassemble_gui (self
));
804 g_signal_connect_swapped (self
->plugin
, "breakpoint-changed", G_CALLBACK (on_breakpoint_changed
), self
);
806 g_signal_connect (G_OBJECT (self
->buffer
),
808 G_CALLBACK (on_disassembly_buffer_changed
),
813 destroy_disassemble_gui (DmaDisassemble
*self
)
815 g_signal_handlers_disconnect_by_func (self
->plugin
, G_CALLBACK (on_breakpoint_changed
), self
);
818 if (self
->menu
!= NULL
)
820 gtk_widget_destroy (self
->menu
);
824 if (self
->window
!= NULL
)
826 gtk_widget_destroy (self
->window
);
833 on_debugger_stopped (DmaDisassemble
*self
)
835 g_signal_handlers_disconnect_by_func (self
->buffer
,
836 on_disassembly_buffer_changed
,
839 dma_sparse_buffer_free (DMA_SPARSE_BUFFER (self
->buffer
));
842 destroy_disassemble_gui (self
);
846 *---------------------------------------------------------------------------*/
849 dma_disassemble_mark (DmaDisassemble
*self
, guint address
, gint marker
)
851 g_return_if_fail (self
!= NULL
);
852 g_return_if_fail (self
->view
!= NULL
);
854 dma_sparse_view_mark (self
->view
, address
, marker
);
858 dma_disassemble_unmark (DmaDisassemble
*self
, guint address
, gint marker
)
860 g_return_if_fail (self
!= NULL
);
861 g_return_if_fail (self
->view
!= NULL
);
863 dma_sparse_view_unmark (self
->view
, address
, marker
);
867 dma_disassemble_clear_all_mark (DmaDisassemble
*self
, gint marker
)
869 g_return_if_fail (self
!= NULL
);
870 /* Accept to clear mark without a view, used at initialization */
871 if (self
->view
!= NULL
)
872 dma_sparse_view_delete_all_markers (self
->view
, marker
);
876 dma_disassemble_goto_address (DmaDisassemble
*self
, guint address
)
878 g_return_if_fail (self
!= NULL
);
879 g_return_if_fail (self
->view
!= NULL
);
881 dma_sparse_view_goto (self
->view
, address
);
884 /* Constructor & Destructor
885 *---------------------------------------------------------------------------*/
888 dma_disassemble_new(AnjutaPlugin
*plugin
, IAnjutaDebugger
*debugger
)
890 DmaDisassemble
* self
;
892 self
= g_new0 (DmaDisassemble
, 1);
894 self
->debugger
= debugger
;
895 if (debugger
!= NULL
) g_object_ref (debugger
);
896 self
->plugin
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
900 g_signal_connect_swapped (self
->debugger
, "debugger-started", G_CALLBACK (on_debugger_started
), self
);
901 g_signal_connect_swapped (self
->debugger
, "debugger-stopped", G_CALLBACK (on_debugger_stopped
), self
);
907 dma_disassemble_free(DmaDisassemble
* self
)
909 g_return_if_fail (self
!= NULL
);
911 destroy_disassemble_gui (self
);
913 if (self
->debugger
!= NULL
) g_object_unref (self
->debugger
);