forked from enlightenment/efl
96 lines
2.7 KiB
Python
96 lines
2.7 KiB
Python
import gdb
|
|
|
|
"""
|
|
All of this script relies heavily on Eo internals and will break if they
|
|
change. Need to make sure this is always in sync.
|
|
"""
|
|
|
|
ptr_size = int(gdb.parse_and_eval('sizeof(void *)'))
|
|
|
|
if ptr_size == 4:
|
|
# 32 bits
|
|
BITS_MID_TABLE_ID = 5
|
|
BITS_TABLE_ID = 5
|
|
BITS_ENTRY_ID = 11
|
|
BITS_GENERATION_COUNTER = 6
|
|
BITS_DOMAIN = 2
|
|
BITS_CLASS = 1
|
|
REF_TAG_SHIFT = 30
|
|
SUPER_TAG_SHIFT = 31
|
|
DROPPED_TABLES = 0
|
|
DROPPED_ENTRIES = 4
|
|
else:
|
|
# 64 bits
|
|
BITS_MID_TABLE_ID = 11
|
|
BITS_TABLE_ID = 11
|
|
BITS_ENTRY_ID = 11
|
|
BITS_GENERATION_COUNTER = 26
|
|
BITS_DOMAIN = 2
|
|
BITS_CLASS = 1
|
|
REF_TAG_SHIFT = 62
|
|
SUPER_TAG_SHIFT = 63
|
|
DROPPED_TABLES = 2
|
|
DROPPED_ENTRIES = 3
|
|
|
|
# /* Shifts macros to manipulate the Eo id */
|
|
SHIFT_DOMAIN = (BITS_MID_TABLE_ID + BITS_TABLE_ID +
|
|
BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
|
|
SHIFT_MID_TABLE_ID = (BITS_TABLE_ID +
|
|
BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
|
|
SHIFT_TABLE_ID = (BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
|
|
SHIFT_ENTRY_ID = (BITS_GENERATION_COUNTER)
|
|
|
|
# /* Maximum ranges */
|
|
MAX_DOMAIN = (1 << BITS_DOMAIN)
|
|
MAX_MID_TABLE_ID = (1 << BITS_MID_TABLE_ID)
|
|
MAX_TABLE_ID = ((1 << BITS_TABLE_ID) - DROPPED_TABLES)
|
|
MAX_ENTRY_ID = ((1 << BITS_ENTRY_ID) - DROPPED_ENTRIES)
|
|
MAX_GENERATIONS = (1 << BITS_GENERATION_COUNTER)
|
|
|
|
# /* Masks */
|
|
MASK_DOMAIN = (MAX_DOMAIN - 1)
|
|
MASK_MID_TABLE_ID = (MAX_MID_TABLE_ID - 1)
|
|
MASK_TABLE_ID = ((1 << BITS_TABLE_ID) - 1)
|
|
MASK_ENTRY_ID = ((1 << BITS_ENTRY_ID) - 1)
|
|
MASK_GENERATIONS = (MAX_GENERATIONS - 1)
|
|
MASK_OBJ_TAG = (1 << (REF_TAG_SHIFT))
|
|
|
|
|
|
null_ptr = gdb.parse_and_eval('(_Eo_Object *) 0')
|
|
|
|
|
|
class Eo_resolve(gdb.Function):
|
|
def __init__(self):
|
|
gdb.Function.__init__(self, 'eo_resolve')
|
|
|
|
def invoke(self, arg):
|
|
obj_id = int(arg)
|
|
|
|
mid_table_id = (obj_id >> SHIFT_MID_TABLE_ID) & MASK_MID_TABLE_ID
|
|
table_id = (obj_id >> SHIFT_TABLE_ID) & MASK_TABLE_ID
|
|
entry_id = (obj_id >> SHIFT_ENTRY_ID) & MASK_ENTRY_ID
|
|
tag_bit = (obj_id) & MASK_OBJ_TAG
|
|
generation = obj_id & MASK_GENERATIONS
|
|
|
|
if (obj_id == 0) or (tag_bit == 0):
|
|
gdb.write('Pointer is NULL or not a valid object.\n')
|
|
return null_ptr
|
|
|
|
entries = gdb.parse_and_eval('_eo_gdb_main_domain->tables[0]->' +
|
|
'eo_ids_tables[{0}]'.format(mid_table_id))
|
|
|
|
if int(entries) == 0:
|
|
gdb.write('Pointer is not a valid object.\n')
|
|
return null_ptr
|
|
|
|
entry = entries[table_id]['entries'][entry_id]
|
|
|
|
if (not entry['active']) or (int(entry['generation']) != generation):
|
|
gdb.write('Pointer is no longer active.\n')
|
|
return null_ptr
|
|
|
|
return entry['ptr']
|
|
|
|
|
|
Eo_resolve()
|