Skip to content
  • Kees Cook's avatar
    treewide: setup_timer() -> timer_setup() (2 field) · 86cb30ec
    Kees Cook authored
    
    
    This converts all remaining setup_timer() calls that use a nested field
    to reach a struct timer_list. Coccinelle does not have an easy way to
    match multiple fields, so a new script is needed to change the matches of
    "&_E->_timer" into "&_E->_field1._timer" in all the rules.
    
    spatch --very-quiet --all-includes --include-headers \
    	-I ./arch/x86/include -I ./arch/x86/include/generated \
    	-I ./include -I ./arch/x86/include/uapi \
    	-I ./arch/x86/include/generated/uapi -I ./include/uapi \
    	-I ./include/generated/uapi --include ./include/linux/kconfig.h \
    	--dir . \
    	--cocci-file ~/src/data/timer_setup-2fields.cocci
    
    @fix_address_of depends@
    expression e;
    @@
    
     setup_timer(
    -&(e)
    +&e
     , ...)
    
    // Update any raw setup_timer() usages that have a NULL callback, but
    // would otherwise match change_timer_function_usage, since the latter
    // will update all function assignments done in the face of a NULL
    // function initialization in setup_timer().
    @change_timer_function_usage_NULL@
    expression _E;
    identifier _field1;
    identifier _timer;
    type _cast_data;
    @@
    
    (
    -setup_timer(&_E->_field1._timer, NULL, _E);
    +timer_setup(&_E->_field1._timer, NULL, 0);
    |
    -setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, NULL, 0);
    |
    -setup_timer(&_E._field1._timer, NULL, &_E);
    +timer_setup(&_E._field1._timer, NULL, 0);
    |
    -setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, NULL, 0);
    )
    
    @change_timer_function_usage@
    expression _E;
    identifier _field1;
    identifier _timer;
    struct timer_list _stl;
    identifier _callback;
    type _cast_func, _cast_data;
    @@
    
    (
    -setup_timer(&_E->_field1._timer, _callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, &_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
     _E->_field1._timer@_stl.function = _callback;
    |
     _E->_field1._timer@_stl.function = &_callback;
    |
     _E->_field1._timer@_stl.function = (_cast_func)_callback;
    |
     _E->_field1._timer@_stl.function = (_cast_func)&_callback;
    |
     _E._field1._timer@_stl.function = _callback;
    |
     _E._field1._timer@_stl.function = &_callback;
    |
     _E._field1._timer@_stl.function = (_cast_func)_callback;
    |
     _E._field1._timer@_stl.function = (_cast_func)&_callback;
    )
    
    // callback(unsigned long arg)
    @change_callback_handle_cast
     depends on change_timer_function_usage@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    identifier _handle;
    @@
    
     void _callback(
    -_origtype _origarg
    +struct timer_list *t
     )
     {
    (
    	... when != _origarg
    	_handletype *_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    	... when != _origarg
    |
    	... when != _origarg
    	_handletype *_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    	... when != _origarg
    |
    	... when != _origarg
    	_handletype *_handle;
    	... when != _handle
    	_handle =
    -(_handletype *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    	... when != _origarg
    |
    	... when != _origarg
    	_handletype *_handle;
    	... when != _handle
    	_handle =
    -(void *)_origarg;
    +from_timer(_handle, t, _field1._timer);
    	... when != _origarg
    )
     }
    
    // callback(unsigned long arg) without existing variable
    @change_callback_handle_cast_no_arg
     depends on change_timer_function_usage &&
                         !change_callback_handle_cast@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    type _origtype;
    identifier _origarg;
    type _handletype;
    @@
    
     void _callback(
    -_origtype _origarg
    +struct timer_list *t
     )
     {
    +	_handletype *_origarg = from_timer(_origarg, t, _field1._timer);
    +
    	... when != _origarg
    -	(_handletype *)_origarg
    +	_origarg
    	... when != _origarg
     }
    
    // Avoid already converted callbacks.
    @match_callback_converted
     depends on change_timer_function_usage &&
                !change_callback_handle_cast &&
    	    !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier t;
    @@
    
     void _callback(struct timer_list *t)
     { ... }
    
    // callback(struct something *handle)
    @change_callback_handle_arg
     depends on change_timer_function_usage &&
    	    !match_callback_converted &&
                !change_callback_handle_cast &&
                !change_callback_handle_cast_no_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    @@
    
     void _callback(
    -_handletype *_handle
    +struct timer_list *t
     )
     {
    +	_handletype *_handle = from_timer(_handle, t, _field1._timer);
    	...
     }
    
    // If change_callback_handle_arg ran on an empty function, remove
    // the added handler.
    @unchange_callback_handle_arg
     depends on change_timer_function_usage &&
    	    change_callback_handle_arg@
    identifier change_timer_function_usage._callback;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    type _handletype;
    identifier _handle;
    identifier t;
    @@
    
     void _callback(struct timer_list *t)
     {
    -	_handletype *_handle = from_timer(_handle, t, _field1._timer);
     }
    
    // We only want to refactor the setup_timer() data argument if we've found
    // the matching callback. This undoes changes in change_timer_function_usage.
    @unchange_timer_function_usage
     depends on change_timer_function_usage &&
                !change_callback_handle_cast &&
                !change_callback_handle_cast_no_arg &&
    	    !change_callback_handle_arg@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type change_timer_function_usage._cast_data;
    @@
    
    (
    -timer_setup(&_E->_field1._timer, _callback, 0);
    +setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
    |
    -timer_setup(&_E._field1._timer, _callback, 0);
    +setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
    )
    
    // If we fixed a callback from a .function assignment, fix the
    // assignment cast now.
    @change_timer_function_assignment
     depends on change_timer_function_usage &&
                (change_callback_handle_cast ||
                 change_callback_handle_cast_no_arg ||
                 change_callback_handle_arg)@
    expression change_timer_function_usage._E;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_func;
    typedef TIMER_FUNC_TYPE;
    @@
    
    (
     _E->_field1._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E->_field1._timer.function =
    -&_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E->_field1._timer.function =
    -(_cast_func)_callback;
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E->_field1._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E._field1._timer.function =
    -_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E._field1._timer.function =
    -&_callback;
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E._field1._timer.function =
    -(_cast_func)_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    |
     _E._field1._timer.function =
    -(_cast_func)&_callback
    +(TIMER_FUNC_TYPE)_callback
     ;
    )
    
    // Sometimes timer functions are called directly. Replace matched args.
    @change_timer_function_calls
     depends on change_timer_function_usage &&
                (change_callback_handle_cast ||
                 change_callback_handle_cast_no_arg ||
                 change_callback_handle_arg)@
    expression _E;
    identifier change_timer_function_usage._field1;
    identifier change_timer_function_usage._timer;
    identifier change_timer_function_usage._callback;
    type _cast_data;
    @@
    
     _callback(
    (
    -(_cast_data)_E
    +&_E->_field1._timer
    |
    -(_cast_data)&_E
    +&_E._field1._timer
    |
    -_E
    +&_E->_field1._timer
    )
     )
    
    // If a timer has been configured without a data argument, it can be
    // converted without regard to the callback argument, since it is unused.
    @match_timer_function_unused_data@
    expression _E;
    identifier _field1;
    identifier _timer;
    identifier _callback;
    @@
    
    (
    -setup_timer(&_E->_field1._timer, _callback, 0);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, 0L);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E->_field1._timer, _callback, 0UL);
    +timer_setup(&_E->_field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0L);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_E._field1._timer, _callback, 0UL);
    +timer_setup(&_E._field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0L);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(&_field1._timer, _callback, 0UL);
    +timer_setup(&_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0);
    +timer_setup(_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0L);
    +timer_setup(_field1._timer, _callback, 0);
    |
    -setup_timer(_field1._timer, _callback, 0UL);
    +timer_setup(_field1._timer, _callback, 0);
    )
    
    @change_callback_unused_data
     depends on match_timer_function_unused_data@
    identifier match_timer_function_unused_data._callback;
    type _origtype;
    identifier _origarg;
    @@
    
     void _callback(
    -_origtype _origarg
    +struct timer_list *unused
     )
     {
    	... when != _origarg
     }
    
    Signed-off-by: default avatarKees Cook <keescook@chromium.org>
    86cb30ec