Print this page
11506 smatch resync
*** 47,56 ****
--- 47,57 ----
enum return_type {
ret_any,
ret_non_zero,
ret_zero,
+ ret_one,
ret_negative,
ret_positive,
};
#define RETURN_VAL -1
*** 149,170 ****
{"_spin_lock_bh", LOCK, "spin_lock", 0, ret_any},
{"_spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any},
{"__spin_lock_bh", LOCK, "spin_lock", 0, ret_any},
{"__spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any},
! {"spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"__spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"_raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"spin_trylock_irq", LOCK, "spin_lock", 0, ret_non_zero},
! {"spin_trylock_irqsave", LOCK, "spin_lock", 0, ret_non_zero},
! {"spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero},
! {"_spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero},
! {"__spin_trylock_bh", LOCK, "spin_lock", 0, ret_non_zero},
! {"__raw_spin_trylock", LOCK, "spin_lock", 0, ret_non_zero},
! {"_atomic_dec_and_lock", LOCK, "spin_lock", 1, ret_non_zero},
{"read_lock", LOCK, "read_lock", 0, ret_any},
{"read_unlock", UNLOCK, "read_lock", 0, ret_any},
{"_read_lock", LOCK, "read_lock", 0, ret_any},
{"_read_unlock", UNLOCK, "read_lock", 0, ret_any},
--- 150,171 ----
{"_spin_lock_bh", LOCK, "spin_lock", 0, ret_any},
{"_spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any},
{"__spin_lock_bh", LOCK, "spin_lock", 0, ret_any},
{"__spin_unlock_bh", UNLOCK, "spin_lock", 0, ret_any},
! {"spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"_spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"__spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"raw_spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"_raw_spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"spin_trylock_irq", LOCK, "spin_lock", 0, ret_one},
! {"spin_trylock_irqsave", LOCK, "spin_lock", 0, ret_one},
! {"spin_trylock_bh", LOCK, "spin_lock", 0, ret_one},
! {"_spin_trylock_bh", LOCK, "spin_lock", 0, ret_one},
! {"__spin_trylock_bh", LOCK, "spin_lock", 0, ret_one},
! {"__raw_spin_trylock", LOCK, "spin_lock", 0, ret_one},
! {"_atomic_dec_and_lock", LOCK, "spin_lock", 1, ret_one},
{"read_lock", LOCK, "read_lock", 0, ret_any},
{"read_unlock", UNLOCK, "read_lock", 0, ret_any},
{"_read_lock", LOCK, "read_lock", 0, ret_any},
{"_read_unlock", UNLOCK, "read_lock", 0, ret_any},
*** 195,211 ****
{"_raw_read_lock_bh", LOCK, "read_lock", 0, ret_any},
{"_raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any},
{"__raw_read_lock_bh", LOCK, "read_lock", 0, ret_any},
{"__raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any},
! {"generic__raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"_read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"_raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"__raw_read_trylock", LOCK, "read_lock", 0, ret_non_zero},
! {"__read_trylock", LOCK, "read_lock", 0, ret_non_zero},
{"write_lock", LOCK, "write_lock", 0, ret_any},
{"write_unlock", UNLOCK, "write_lock", 0, ret_any},
{"_write_lock", LOCK, "write_lock", 0, ret_any},
{"_write_unlock", UNLOCK, "write_lock", 0, ret_any},
--- 196,212 ----
{"_raw_read_lock_bh", LOCK, "read_lock", 0, ret_any},
{"_raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any},
{"__raw_read_lock_bh", LOCK, "read_lock", 0, ret_any},
{"__raw_read_unlock_bh", UNLOCK, "read_lock", 0, ret_any},
! {"generic__raw_read_trylock", LOCK, "read_lock", 0, ret_one},
! {"read_trylock", LOCK, "read_lock", 0, ret_one},
! {"_read_trylock", LOCK, "read_lock", 0, ret_one},
! {"raw_read_trylock", LOCK, "read_lock", 0, ret_one},
! {"_raw_read_trylock", LOCK, "read_lock", 0, ret_one},
! {"__raw_read_trylock", LOCK, "read_lock", 0, ret_one},
! {"__read_trylock", LOCK, "read_lock", 0, ret_one},
{"write_lock", LOCK, "write_lock", 0, ret_any},
{"write_unlock", UNLOCK, "write_lock", 0, ret_any},
{"_write_lock", LOCK, "write_lock", 0, ret_any},
{"_write_unlock", UNLOCK, "write_lock", 0, ret_any},
*** 232,264 ****
{"_raw_write_lock", LOCK, "write_lock", 0, ret_any},
{"__raw_write_lock", LOCK, "write_lock", 0, ret_any},
{"_raw_write_unlock", UNLOCK, "write_lock", 0, ret_any},
{"__raw_write_unlock", UNLOCK, "write_lock", 0, ret_any},
! {"write_trylock", LOCK, "write_lock", 0, ret_non_zero},
! {"_write_trylock", LOCK, "write_lock", 0, ret_non_zero},
! {"raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero},
! {"_raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero},
! {"__write_trylock", LOCK, "write_lock", 0, ret_non_zero},
! {"__raw_write_trylock", LOCK, "write_lock", 0, ret_non_zero},
{"down", LOCK, "sem", 0, ret_any},
{"up", UNLOCK, "sem", 0, ret_any},
{"down_trylock", LOCK, "sem", 0, ret_zero},
{"down_timeout", LOCK, "sem", 0, ret_zero},
{"down_interruptible", LOCK, "sem", 0, ret_zero},
{"mutex_lock", LOCK, "mutex", 0, ret_any},
{"mutex_unlock", UNLOCK, "mutex", 0, ret_any},
{"mutex_lock_nested", LOCK, "mutex", 0, ret_any},
{"mutex_lock_interruptible", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_interruptible_nested", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_killable", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_killable_nested", LOCK, "mutex", 0, ret_zero},
! {"mutex_trylock", LOCK, "mutex", 0, ret_non_zero},
{"raw_local_irq_disable", LOCK, "irq", NO_ARG, ret_any},
{"raw_local_irq_enable", UNLOCK, "irq", NO_ARG, ret_any},
{"spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
--- 233,279 ----
{"_raw_write_lock", LOCK, "write_lock", 0, ret_any},
{"__raw_write_lock", LOCK, "write_lock", 0, ret_any},
{"_raw_write_unlock", UNLOCK, "write_lock", 0, ret_any},
{"__raw_write_unlock", UNLOCK, "write_lock", 0, ret_any},
! {"write_trylock", LOCK, "write_lock", 0, ret_one},
! {"_write_trylock", LOCK, "write_lock", 0, ret_one},
! {"raw_write_trylock", LOCK, "write_lock", 0, ret_one},
! {"_raw_write_trylock", LOCK, "write_lock", 0, ret_one},
! {"__write_trylock", LOCK, "write_lock", 0, ret_one},
! {"__raw_write_trylock", LOCK, "write_lock", 0, ret_one},
{"down", LOCK, "sem", 0, ret_any},
{"up", UNLOCK, "sem", 0, ret_any},
{"down_trylock", LOCK, "sem", 0, ret_zero},
{"down_timeout", LOCK, "sem", 0, ret_zero},
{"down_interruptible", LOCK, "sem", 0, ret_zero},
+
+ {"down_write", LOCK, "rw_sem", 0, ret_any},
+ {"downgrade_write", UNLOCK, "rw_sem", 0, ret_any},
+ {"downgrade_write", LOCK, "read_sem", 0, ret_any},
+ {"up_write", UNLOCK, "rw_sem", 0, ret_any},
+ {"down_write_trylock", LOCK, "rw_sem", 0, ret_one},
+ {"down_write_killable", LOCK, "rw_sem", 0, ret_zero},
+ {"down_read", LOCK, "read_sem", 0, ret_any},
+ {"down_read_trylock", LOCK, "read_sem", 0, ret_one},
+ {"down_read_killable", LOCK, "read_sem", 0, ret_zero},
+ {"up_read", UNLOCK, "read_sem", 0, ret_any},
+
{"mutex_lock", LOCK, "mutex", 0, ret_any},
+ {"mutex_lock_io", LOCK, "mutex", 0, ret_any},
{"mutex_unlock", UNLOCK, "mutex", 0, ret_any},
{"mutex_lock_nested", LOCK, "mutex", 0, ret_any},
+ {"mutex_lock_io_nested", LOCK, "mutex", 0, ret_any},
{"mutex_lock_interruptible", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_interruptible_nested", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_killable", LOCK, "mutex", 0, ret_zero},
{"mutex_lock_killable_nested", LOCK, "mutex", 0, ret_zero},
! {"mutex_trylock", LOCK, "mutex", 0, ret_one},
{"raw_local_irq_disable", LOCK, "irq", NO_ARG, ret_any},
{"raw_local_irq_enable", UNLOCK, "irq", NO_ARG, ret_any},
{"spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
*** 267,277 ****
{"__spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"__spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"_raw_spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"_raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"__raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
! {"spin_trylock_irq", LOCK, "irq", NO_ARG, ret_non_zero},
{"read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"_read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"_read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"__read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
--- 282,292 ----
{"__spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"__spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"_raw_spin_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"_raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"__raw_spin_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
! {"spin_trylock_irq", LOCK, "irq", NO_ARG, ret_one},
{"read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"_read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
{"_read_unlock_irq", UNLOCK, "irq", NO_ARG, ret_any},
{"__read_lock_irq", LOCK, "irq", NO_ARG, ret_any},
*** 302,312 ****
{"_raw_spin_lock_irqsave", LOCK, "irqsave", 1, ret_any},
{"_raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
{"__raw_spin_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"__raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
{"_raw_spin_lock_irqsave_nested", LOCK, "irqsave", RETURN_VAL, ret_any},
! {"spin_trylock_irqsave", LOCK, "irqsave", 1, ret_non_zero},
{"read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"read_lock_irqsave", LOCK, "irqsave", 1, ret_any},
{"read_unlock_irqrestore", UNLOCK, "irqsave", 1, ret_any},
{"_read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"_read_lock_irqsave", LOCK, "irqsave", 1, ret_any},
--- 317,327 ----
{"_raw_spin_lock_irqsave", LOCK, "irqsave", 1, ret_any},
{"_raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
{"__raw_spin_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"__raw_spin_unlock_irqrestore",UNLOCK, "irqsave", 1, ret_any},
{"_raw_spin_lock_irqsave_nested", LOCK, "irqsave", RETURN_VAL, ret_any},
! {"spin_trylock_irqsave", LOCK, "irqsave", 1, ret_one},
{"read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"read_lock_irqsave", LOCK, "irqsave", 1, ret_any},
{"read_unlock_irqrestore", UNLOCK, "irqsave", 1, ret_any},
{"_read_lock_irqsave", LOCK, "irqsave", RETURN_VAL, ret_any},
{"_read_lock_irqsave", LOCK, "irqsave", 1, ret_any},
*** 346,358 ****
{"write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
{"_write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any},
{"_write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
{"__write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any},
{"__write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
! {"spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero},
! {"_spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero},
! {"__spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_non_zero},
{"ffs_mutex_lock", LOCK, "mutex", 0, ret_zero},
};
static struct lock_info *lock_table;
--- 361,373 ----
{"write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
{"_write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any},
{"_write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
{"__write_lock_bh", LOCK, "bottom_half", NO_ARG, ret_any},
{"__write_unlock_bh", UNLOCK, "bottom_half", NO_ARG, ret_any},
! {"spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one},
! {"_spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one},
! {"__spin_trylock_bh", LOCK, "bottom_half", NO_ARG, ret_one},
{"ffs_mutex_lock", LOCK, "mutex", 0, ret_zero},
};
static struct lock_info *lock_table;
*** 445,454 ****
--- 460,478 ----
{
if (is_impossible_path())
set_state(my_id, sm->name, sm->sym, &impossible);
}
+ static bool nestable(const char *name)
+ {
+ if (strstr(name, "read_sem:"))
+ return true;
+ if (strcmp(name, "bottom_half:") == 0)
+ return true;
+ return false;
+ }
+
static void do_lock(const char *name)
{
struct sm_state *sm;
if (__inline_fn)
*** 455,466 ****
return;
sm = get_sm_state(my_id, name, NULL);
if (!sm)
add_tracker(&starts_unlocked, my_id, name, NULL);
! if (sm && slist_has_state(sm->possible, &locked) &&
! strcmp(name, "bottom_half:") != 0)
sm_error("double lock '%s'", name);
if (sm)
func_has_transition = TRUE;
set_state(my_id, name, NULL, &locked);
}
--- 479,489 ----
return;
sm = get_sm_state(my_id, name, NULL);
if (!sm)
add_tracker(&starts_unlocked, my_id, name, NULL);
! if (sm && slist_has_state(sm->possible, &locked) && !nestable(name))
sm_error("double lock '%s'", name);
if (sm)
func_has_transition = TRUE;
set_state(my_id, name, NULL, &locked);
}
*** 742,757 ****
--- 765,783 ----
}
static int matches_return_type(struct range_list *rl, enum return_type type)
{
sval_t zero_sval = ll_to_sval(0);
+ sval_t one_sval = ll_to_sval(1);
/* All these double negatives are super ugly! */
switch (type) {
case ret_zero:
return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(zero_sval, zero_sval));
+ case ret_one:
+ return !possibly_true_rl(rl, SPECIAL_NOTEQUAL, alloc_rl(one_sval, one_sval));
case ret_non_zero:
return !possibly_true_rl(rl, SPECIAL_EQUAL, alloc_rl(zero_sval, zero_sval));
case ret_negative:
return !possibly_true_rl(rl, SPECIAL_GTE, alloc_rl(zero_sval, zero_sval));
case ret_positive:
*** 904,922 ****
{
struct lock_info *lock = &lock_table[index];
void *idx = INT_PTR(index);
if (lock->return_type == ret_non_zero) {
! return_implies_state(lock->function, valid_ptr_min, valid_ptr_max, &match_lock_held, idx);
return_implies_state(lock->function, 0, 0, &match_lock_failed, idx);
} else if (lock->return_type == ret_any && lock->arg == RETURN_VAL) {
add_function_assign_hook(lock->function, &match_returns_locked, idx);
} else if (lock->return_type == ret_any) {
add_function_hook(lock->function, &match_lock_unlock, idx);
} else if (lock->return_type == ret_zero) {
return_implies_state(lock->function, 0, 0, &match_lock_held, idx);
return_implies_state(lock->function, -4095, -1, &match_lock_failed, idx);
}
}
static void load_table(struct lock_info *_lock_table, int size)
{
--- 930,951 ----
{
struct lock_info *lock = &lock_table[index];
void *idx = INT_PTR(index);
if (lock->return_type == ret_non_zero) {
! return_implies_state(lock->function, 1, INT_MAX, &match_lock_held, idx);
return_implies_state(lock->function, 0, 0, &match_lock_failed, idx);
} else if (lock->return_type == ret_any && lock->arg == RETURN_VAL) {
add_function_assign_hook(lock->function, &match_returns_locked, idx);
} else if (lock->return_type == ret_any) {
add_function_hook(lock->function, &match_lock_unlock, idx);
} else if (lock->return_type == ret_zero) {
return_implies_state(lock->function, 0, 0, &match_lock_held, idx);
return_implies_state(lock->function, -4095, -1, &match_lock_failed, idx);
+ } else if (lock->return_type == ret_one) {
+ return_implies_state(lock->function, 1, 1, &match_lock_held, idx);
+ return_implies_state(lock->function, 0, 0, &match_lock_failed, idx);
}
}
static void load_table(struct lock_info *_lock_table, int size)
{