always_inline void
zero_pair (hash_t * h, hash_pair_t * p)
{
- memset (p, 0, hash_pair_bytes (h));
+ clib_memset (p, 0, hash_pair_bytes (h));
}
always_inline void
init_pair (hash_t * h, hash_pair_t * p)
{
- memset (p->value, ~0, hash_value_bytes (h));
+ clib_memset (p->value, ~0, hash_value_bytes (h));
}
always_inline hash_pair_union_t *
#if uword_bits == 64
static inline u64
-get_unaligned_as_u64 (void const *data, int n)
+zap64 (u64 x, word n)
{
- int i;
- u64 r = 0;
- u8 const *p = (u8 const *) data;
-
+#define _(n) (((u64) 1 << (u64) (8*(n))) - (u64) 1)
+ static u64 masks_little_endian[] = {
+ 0, _(1), _(2), _(3), _(4), _(5), _(6), _(7),
+ };
+ static u64 masks_big_endian[] = {
+ 0, ~_(7), ~_(6), ~_(5), ~_(4), ~_(3), ~_(2), ~_(1),
+ };
+#undef _
if (clib_arch_is_big_endian)
- {
- for (i = 0; i < n; i++)
- r |= ((u64) ((*(p + i)) << (u8) (1 << (8 - i))));
- }
+ return x & masks_big_endian[n];
else
- {
- for (i = 0; i < n; i++)
- r |= ((u64) ((*(p + i)) << (u8) (1 << i)));
- }
-
- return r;
+ return x & masks_little_endian[n];
}
-static inline u64
+/**
+ * make address-sanitizer skip this:
+ * clib_mem_unaligned + zap64 casts its input as u64, computes a mask
+ * according to the input length, and returns the casted maked value.
+ * Therefore all the 8 Bytes of the u64 are systematically read, which
+ * rightfully causes address-sanitizer to raise an error on smaller inputs.
+ *
+ * However the invalid Bytes are discarded within zap64(), whicj is why
+ * this can be silenced safely.
+ */
+static inline u64 __attribute__ ((no_sanitize_address))
hash_memory64 (void *p, word n_bytes, u64 state)
{
u64 *q = p;
case 2:
a += clib_mem_unaligned (q + 0, u64);
b += clib_mem_unaligned (q + 1, u64);
- c += get_unaligned_as_u64 (q + 2, n % sizeof (u64)) << 8;
+ if (n % sizeof (u64))
+ c += zap64 (clib_mem_unaligned (q + 2, u64), n % sizeof (u64)) << 8;
break;
case 1:
a += clib_mem_unaligned (q + 0, u64);
- b += get_unaligned_as_u64 (q + 1, n % sizeof (u64));
+ if (n % sizeof (u64))
+ b += zap64 (clib_mem_unaligned (q + 1, u64), n % sizeof (u64));
break;
case 0:
- a += get_unaligned_as_u64 (q + 0, n % sizeof (u64));
+ if (n % sizeof (u64))
+ a += zap64 (clib_mem_unaligned (q + 0, u64), n % sizeof (u64));
break;
}
sum = string_key_sum (h, key);
break;
+ case KEY_FUNC_MEM:
+ sum = mem_key_sum (h, key);
+ break;
+
default:
sum = h->key_sum (h, key);
break;
e = string_key_equal (h, key1, key2);
break;
+ case KEY_FUNC_MEM:
+ e = mem_key_equal (h, key1, key2);
+ break;
+
default:
e = h->key_equal (h, key1, key2);
break;
log2_bytes = 1 + hash_pair_log2_bytes (h);
q = clib_mem_alloc (1ULL << log2_bytes);
}
- clib_memcpy (q, &p->direct, hash_pair_bytes (h));
+ clib_memcpy_fast (q, &p->direct, hash_pair_bytes (h));
pi->pairs = q;
if (h->log2_pair_size > 0)
if (len == 2)
{
- clib_memcpy (p, q == r ? hash_forward1 (h, r) : r,
- hash_pair_bytes (h));
+ clib_memcpy_fast (p, q == r ? hash_forward1 (h, r) : r,
+ hash_pair_bytes (h));
set_is_user (v, i, 1);
}
else
{
/* If deleting a pair we need to keep non-null pairs together. */
if (q < e)
- clib_memcpy (q, e, hash_pair_bytes (h));
+ clib_memcpy_fast (q, e, hash_pair_bytes (h));
else
zero_pair (h, q);
if (is_vec)
{
set_is_user (v, i, 0);
if (old_value)
- clib_memcpy (old_value, p->direct.value,
- hash_value_bytes (h));
+ clib_memcpy_fast (old_value, p->direct.value,
+ hash_value_bytes (h));
zero_pair (h, &p->direct);
}
}
if (found_key && op == UNSET)
{
if (old_value)
- clib_memcpy (old_value, &p->direct.value,
- hash_value_bytes (h));
+ clib_memcpy_fast (old_value, &p->direct.value,
+ hash_value_bytes (h));
unset_indirect (v, i, &p->direct);
{
/* Save away old value for caller. */
if (old_value && found_key)
- clib_memcpy (old_value, &p->direct.value, hash_value_bytes (h));
- clib_memcpy (&p->direct.value, new_value, hash_value_bytes (h));
+ clib_memcpy_fast (old_value, &p->direct.value, hash_value_bytes (h));
+ clib_memcpy_fast (&p->direct.value, new_value, hash_value_bytes (h));
}
if (op == SET)
{
/* Restore flags. */
h->flags = hn->f;
- memset (hn, 0, sizeof (hn[0]));
+ clib_memset (hn, 0, sizeof (hn[0]));
return 0;
}
if (h_user)
log2_pair_size = h_user->log2_pair_size;
- v = _vec_resize (0,
+ v = _vec_resize ((void *) 0,
/* vec len: */ elts,
/* data bytes: */
(elts << log2_pair_size) * sizeof (hash_pair_t),