efl

Форк
0
/
eo_gdb.py 
146 строк · 4.4 Кб
1
import gdb
2

3
"""
4
All of this script relies heavily on Eo internals and will break if they
5
change. Need to make sure this is always in sync.
6
"""
7

8
ptr_size = int(gdb.parse_and_eval('sizeof(void *)'))
9

10
if ptr_size == 4:
11
    # 32 bits
12
    BITS_MID_TABLE_ID = 5
13
    BITS_TABLE_ID = 5
14
    BITS_ENTRY_ID = 11
15
    BITS_GENERATION_COUNTER = 6
16
    BITS_DOMAIN = 2
17
    BITS_CLASS = 1
18
    REF_TAG_SHIFT = 30
19
    SUPER_TAG_SHIFT = 31
20
    DROPPED_TABLES = 0
21
    DROPPED_ENTRIES = 4
22
else:
23
    # 64 bits
24
    BITS_MID_TABLE_ID = 11
25
    BITS_TABLE_ID = 11
26
    BITS_ENTRY_ID = 11
27
    BITS_GENERATION_COUNTER = 26
28
    BITS_DOMAIN = 2
29
    BITS_CLASS = 1
30
    REF_TAG_SHIFT = 62
31
    SUPER_TAG_SHIFT = 63
32
    DROPPED_TABLES = 2
33
    DROPPED_ENTRIES = 3
34

35
# /* Shifts macros to manipulate the Eo id */
36
SHIFT_DOMAIN = (BITS_MID_TABLE_ID + BITS_TABLE_ID +
37
                BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
38
SHIFT_MID_TABLE_ID = (BITS_TABLE_ID +
39
                      BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
40
SHIFT_TABLE_ID = (BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
41
SHIFT_ENTRY_ID = (BITS_GENERATION_COUNTER)
42

43
# /* Maximum ranges */
44
MAX_DOMAIN = (1 << BITS_DOMAIN)
45
MAX_MID_TABLE_ID = (1 << BITS_MID_TABLE_ID)
46
MAX_TABLE_ID = ((1 << BITS_TABLE_ID) - DROPPED_TABLES)
47
MAX_ENTRY_ID = ((1 << BITS_ENTRY_ID) - DROPPED_ENTRIES)
48
MAX_GENERATIONS = (1 << BITS_GENERATION_COUNTER)
49

50
# /* Masks */
51
MASK_DOMAIN = (MAX_DOMAIN - 1)
52
MASK_MID_TABLE_ID = (MAX_MID_TABLE_ID - 1)
53
MASK_TABLE_ID = ((1 << BITS_TABLE_ID) - 1)
54
MASK_ENTRY_ID = ((1 << BITS_ENTRY_ID) - 1)
55
MASK_GENERATIONS = (MAX_GENERATIONS - 1)
56
MASK_OBJ_TAG = (1 << (REF_TAG_SHIFT))
57

58

59
null_void_ptr = gdb.parse_and_eval('(_Eo_Object *) 0')
60
null_eo_object_ptr = gdb.parse_and_eval('(_Eo_Object *) 0')
61
zero_uintptr_t = gdb.parse_and_eval('(uintptr_t) 0')
62

63

64
class Eo_resolve(gdb.Function):
65
    def __init__(self):
66
        gdb.Function.__init__(self, 'eo_resolve')
67

68
    def invoke(self, arg):
69
        obj_id = int(str(arg.cast(zero_uintptr_t.type)), 0)
70

71
        mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID
72
        table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID
73
        entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID
74
        tag_bit = (obj_id) & MASK_OBJ_TAG
75
        generation = obj_id & MASK_GENERATIONS
76

77
        if (obj_id == 0) or (tag_bit == 0):
78
            gdb.write('Pointer is NULL or not a valid object.\n')
79
            return null_eo_object_ptr
80

81
        entries = gdb.parse_and_eval('_eo_gdb_main_domain->tables[0]->' +
82
                                     'eo_ids_tables[{0}]'.format(mid_table_id))
83

84
        if int(entries) == 0:
85
            gdb.write('Pointer is not a valid object.\n')
86
            return null_eo_object_ptr
87

88
        entry = entries[table_id]['entries'][entry_id]
89

90
        if (not entry['active']) or (int(entry['generation']) != generation):
91
            gdb.write('Pointer is no longer active.\n')
92
            return null_eo_object_ptr
93

94
        return entry['ptr']
95

96

97
Eo_resolve()
98

99

100
class Eo_data_get(gdb.Function):
101
    def __init__(self):
102
        gdb.Function.__init__(self, 'eo_data_get')
103

104
    def invoke(self, ptr, kls_name):
105
        ptr = ptr.cast(null_eo_object_ptr.type)  # Cast to correct type
106

107
        if int(ptr) == 0:
108
            gdb.write('Object is not a valid pointer (NULL).\n')
109
            return null_void_ptr
110

111
        kls_name = kls_name.string()
112
        extns = ptr['klass']['mro']
113
        kls = None
114

115
        i = 0
116
        while int(extns[i]) != 0:
117
            if extns[i]['desc']['name'].string() == kls_name:
118
                kls = extns[i]
119
            i += 1
120

121
        if kls is None:
122
            gdb.write('Class "{}" not found in the object mro.\n'
123
                      .format(kls_name))
124
            return null_void_ptr
125

126
        # Check if not mixin
127
        if int(kls['desc']['type'].cast(zero_uintptr_t.type)) != 3:
128
            return gdb.parse_and_eval('(void *) (((char *) {}) + {})'
129
                                      .format(ptr, kls['data_offset']))
130
        else:
131
            extn_off = ptr['klass']['extn_data_off']
132
            if int(extn_off) == 0:
133
                return null_void_ptr
134

135
            i = 0
136
            while int(extn_off[i]['klass']) != 0:
137
                kls = extn_off[i]['klass']
138
                if kls['desc']['name'].string() == kls_name:
139
                    return gdb.parse_and_eval('(void *) (((char *) {}) + {})'
140
                                              .format(ptr, kls['data_offset']))
141
                i += 1
142

143
        return null_void_ptr
144

145

146
Eo_data_get()
147

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.