summaryrefslogtreecommitdiff
path: root/gdb/libdom.py
blob: 65286e3d216c2f8af2349f226a91dc12a70f75bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# LibDOM related commands and utilities for gdb

import gdb

def dom_get_type_ptr(typename):
    return gdb.lookup_type(typename).pointer()

def dom_node_at(ptr):
    nodetype = dom_get_type_ptr("dom_node_internal")
    return ptr.cast(nodetype).dereference()

def dom_document_at(ptr):
    doctype = dom_get_type_ptr("dom_document")
    return ptr.cast(doctype).dereference()

def dom_node_type(node):
    return node["type"]

def dom_node_refcnt(node):
    return node["base"]["refcnt"]

def lwc_string_value(strptr):
    cptr = strptr+1
    charptr = cptr.cast(dom_get_type_ptr("char"))
    return charptr.string()

def dom_string__is_intern(intstr):
    return str(intstr['type']) == "DOM_STRING_INTERNED"

def cdata_string_value(cdata):
    cptr = cdata['ptr']
    charptr = cptr.cast(dom_get_type_ptr("char"))
    return charptr.string()

def dom_string_value(stringptr):
    intstr = stringptr.cast(dom_get_type_ptr("dom_string_internal")).dereference()
    if intstr.address == gdb.parse_and_eval("(dom_string_internal*)0"):
        return ""
    if dom_string__is_intern(intstr):
        return lwc_string_value(intstr['data']['intern'])
    else:
        return cdata_string_value(intstr['data']['cdata'])

def dom_node_name(node):
    namestr = node["name"]
    return " '%s'" % dom_string_value(namestr)

def dom_node_pending_offset():
    return gdb.parse_and_eval("(int)&((struct dom_node_internal *)0)->pending_list")

def dom_print_node(node, prefix = ""):
    print("%s%s @ %s [%s]%s" % (prefix, dom_node_type(node), 
                                node.address, dom_node_refcnt(node),
                                dom_node_name(node)))

def dom_walk_tree(node, prefix = ""):
    dom_print_node(node, prefix)
    current = node['first_child'].dereference()
    while current.address != 0:
        dom_walk_tree(current, "%s  " % prefix)
        current = current['next'].dereference()

def dom_document_show(doc):
    print "Node Tree:"
    node = dom_node_at(doc.address)
    dom_walk_tree(node, "  ")
    pending = doc['pending_nodes']
    if pending['next'] != pending.address:
        print "Pending Node trees:"
        current_list_entry = pending['next']
        while current_list_entry is not None:
            voidp = current_list_entry.cast(dom_get_type_ptr("void"))
            voidp = voidp - dom_node_pending_offset()
            node = dom_node_at(voidp)
            dom_walk_tree(node, "  ")
            current_list_entry = node['pending_list']['next']
            if current_list_entry == pending.address:
                current_list_entry = None
    

class DOMCommand(gdb.Command):
    """DOM related commands"""

    def __init__(self):
        gdb.Command.__init__(self, "dom", gdb.COMMAND_DATA,
                             gdb.COMPLETE_COMMAND, True)

class DOMNodeCommand(gdb.Command):
    """DOMNode related commands"""

    def __init__(self):
        gdb.Command.__init__(self, "dom node", gdb.COMMAND_DATA,
                             gdb.COMPLETE_COMMAND, True)

class DOMDocumentCommand(gdb.Command):
    """DOMDocument related commands"""

    def __init__(self):
        gdb.Command.__init__(self, "dom document", gdb.COMMAND_DATA,
                             gdb.COMPLETE_COMMAND, True)

class DOMNodeShowCommand(gdb.Command):
    """Show a node at a given address."""

    def __init__(self):
        gdb.Command.__init__(self, "dom node show", gdb.COMMAND_DATA,
                             gdb.COMPLETE_NONE, True)

    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)
        self._invoke(*args)

    def _invoke(self, nodeptr):
        _ptr = gdb.parse_and_eval(nodeptr)
        node = dom_node_at(_ptr)
        dom_print_node(node)

class DOMNodeWalkCommand(gdb.Command):
    """Walk a node tree at a given address."""

    def __init__(self):
        gdb.Command.__init__(self, "dom node walk", gdb.COMMAND_DATA,
                             gdb.COMPLETE_NONE, True)

    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)
        self._invoke(*args)

    def _invoke(self, nodeptr):
        _ptr = gdb.parse_and_eval(nodeptr)
        node = dom_node_at(_ptr)
        dom_walk_tree(node)

class DOMDocumentShowCommand(gdb.Command):
    """Show a document at a given address."""

    def __init__(self):
        gdb.Command.__init__(self, "dom document show", gdb.COMMAND_DATA,
                             gdb.COMPLETE_NONE, True)

    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)
        self._invoke(*args)

    def _invoke(self, docptr):
        _ptr = gdb.parse_and_eval(docptr)
        doc = dom_document_at(_ptr)
        dom_document_show(doc)

DOMCommand()

DOMNodeCommand()
DOMNodeShowCommand()
DOMNodeWalkCommand()

DOMDocumentCommand()
DOMDocumentShowCommand()