Ejemplo n.º 1
0
def argument(p: WlPatterns, value_str: str) -> wl.Arg.Base:
    match = p.arg_re.match(value_str)
    if match:
        if match.group('int'):
            return wl.Arg.Int(int(value_str))
        elif match.group('obj_id'):
            return wl.Arg.Object(
                wl.UnresolvedObject(int(match.group('obj_id')),
                                    match.group('obj_type')), False)
        elif match.group('new_id'):
            type_name: Optional[str] = match.group('new_type')
            if not type_name:
                type_name = None
            return wl.Arg.Object(
                wl.UnresolvedObject(int(match.group('new_id')), type_name),
                True)
        elif match.group('nil'):
            return wl.Arg.Null()
        elif match.group('str'):
            return wl.Arg.String(match.group('str'))
        elif match.group('float'):
            return wl.Arg.Float(float(value_str.replace(',', '.')))
        elif match.group('fd'):
            return wl.Arg.Fd(int(match.group('fd')))
        elif match.group('array'):
            return wl.Arg.Array()
    return wl.Arg.Unknown(value_str)
Ejemplo n.º 2
0
def received_message() -> Tuple[str, wl.Message]:
    frame = gdb.selected_frame()
    closure = frame.read_var('closure')
    wl_object = frame.read_var('target')
    parent_frame = frame.older()
    calling_func = parent_frame.name()
    # NOTE: closure->proxy is often null but technically undefined in the server case
    # Using it to detect server vs client works for the tests but fails on Mir
    if calling_func == 'dispatch_event':
        # Client connection
        new_id_is_actually_an_object = True
        wl_display = parent_frame.read_var('display')
        connection = _fast_access(wl_display, 'wl_display.connection')
    elif calling_func == 'wl_client_connection_data':
        # Server connection
        new_id_is_actually_an_object = False
        resource_type = lazy_get_wl_resource_ptr_type()
        resource = wl_object.cast(resource_type)
        connection = _fast_access(_fast_access(resource, 'wl_resource.client'), 'wl_client.connection')
    else:
        raise RuntimeError('Unknown libwayland calling function ' + calling_func)
    connection_id = connection_id_of(connection)
    object_id = int(_fast_access(closure, 'wl_closure.sender_id'))
    # wl_object is not a pointer, so can't use _fast_access() to get interface
    obj_type = _fast_access(wl_object['interface'], 'wl_interface.name').string()
    object = wl.UnresolvedObject(object_id, obj_type)
    message = extract_message(closure, object, False, new_id_is_actually_an_object)
    return connection_id, message
Ejemplo n.º 3
0
def sent_message() -> Tuple[str, wl.Message]:
    # We break on serialize_closure() (both wl_closure_send and wl_closure_queue call it, so just breaking on it
    # reduces breakpoints and improves performance). Everything we're interested in is in the parent frame though.
    frame = gdb.selected_frame().older()
    closure = frame.read_var('closure')
    # closure -> proxy is always null in wl_closure_send and wl_closure_queue
    connection = frame.read_var('connection')
    connection_id = connection_id_of(connection)
    object_id = int(_fast_access(closure, 'wl_closure.sender_id'))
    object = wl.UnresolvedObject(object_id, None)
    message = extract_message(closure, object, True, False)
    return connection_id, message
Ejemplo n.º 4
0
def message(raw: str) -> Tuple[str, wl.Message]:
    p = WlPatterns.lazy_get_instance()
    sent = True
    conn_id = 'PARSED'
    matches = p.out_msg_re.findall(raw)
    if not matches:
        sent = False
        matches = p.in_msg_re.findall(raw)
    if len(matches) != 1:
        raise RuntimeError(raw)
    match = matches[0]
    assert isinstance(match, tuple), repr(match)
    abs_timestamp = float(match[0].replace(',', '.')) / 1000.0
    type_name = match[1]
    obj_id = int(match[2])
    message_name = match[3]
    message_args_str = match[4]
    message_args = argument_list(p, message_args_str)
    return conn_id, wl.Message(abs_timestamp,
                               wl.UnresolvedObject(obj_id, type_name), sent,
                               message_name, message_args)
Ejemplo n.º 5
0
def extract_message(closure, object: wl.ObjectBase, is_sending: bool, new_id_is_actually_an_object: bool) -> wl.Message:
    '''Returns a tuple containing…
    Message Name: str, the message being called
    Arguments: list of wl.Arg
    '''
    closure_message = _fast_access(closure, 'wl_closure.message')
    message_name = _fast_access(closure_message, 'wl_message.name').string()
    # The signiture is that stupid '2uufo?i' thing that has the type info
    signiture = _fast_access(closure_message, 'wl_message.signature').string()
    message_types = _fast_access(closure_message, 'wl_message.types')
    closure_args = _fast_access(closure, 'wl_closure.args')
    args: List[wl.Arg.Base] = []
    i = 0
    for c in signiture:
        # If its not a version number or '?' optional indicator
        if c in type_codes:
            # Pull out the right union member at the right index
            value = closure_args[i][c]
            if c == 'i' or c == 'u':
                args.append(wl.Arg.Int(int(value)))
            elif c == 'f':
                # Math is ripped out of wl_fixed_to_double() in libwayland
                f = float(gdb.parse_and_eval('(double)(void*)(((1023LL + 44LL) << 52) + (1LL << 51) + ' + str(value) + ') - (3LL << 43)'))
                args.append(wl.Arg.Float(f))
            elif c == 's':
                if _is_null(value):
                    str_val = '[null string]'
                else:
                    str_val = value.string()
                args.append(wl.Arg.String(str_val))
            elif c == 'a':
                size = int(value['size'])
                elems: List[wl.Arg.Base] = []
                int_type = gdb.lookup_type('int')
                for i in range(size // int_type.sizeof):
                    elem = value['data'].cast(int_type.pointer())[i]
                    elems.append(wl.Arg.Int(int(elem)))
                args.append(wl.Arg.Array(elems))
            elif c == 'h':
                args.append(wl.Arg.Fd(int(value)))
            elif c == 'o':
                arg_type = message_types[i]
                if _is_null(arg_type):
                    arg_type_name = None
                else:
                    arg_type_name = arg_type['name'].string()
                if _is_null(value):
                    args.append(wl.Arg.Null(arg_type_name))
                else:
                    arg_id = int(_fast_access(value, 'wl_object.id'))
                    args.append(wl.Arg.Object(wl.UnresolvedObject(arg_id, arg_type_name), False))
            elif c == 'n':
                arg_type = message_types[i]
                if _is_null(arg_type):
                    arg_type_name = None
                else:
                    arg_type_name = arg_type['name'].string()
                if new_id_is_actually_an_object:
                    arg_id = int(_fast_access(closure_args[i]['o'], 'wl_object.id'))
                else:
                    arg_id = int(value)
                args.append(wl.Arg.Object(wl.UnresolvedObject(arg_id, arg_type_name), True))
            else:
                raise RuntimeError('Invalid type code ' + c)
            i += 1
    return wl.Message(time_now(), object, is_sending, message_name, tuple(args))