|
@@ -47,14 +47,34 @@ static int jump_label_cmp(const void *a, const void *b)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void jump_label_swap(void *a, void *b, int size)
|
|
|
+{
|
|
|
+ long delta = (unsigned long)a - (unsigned long)b;
|
|
|
+ struct jump_entry *jea = a;
|
|
|
+ struct jump_entry *jeb = b;
|
|
|
+ struct jump_entry tmp = *jea;
|
|
|
+
|
|
|
+ jea->code = jeb->code - delta;
|
|
|
+ jea->target = jeb->target - delta;
|
|
|
+ jea->key = jeb->key - delta;
|
|
|
+
|
|
|
+ jeb->code = tmp.code + delta;
|
|
|
+ jeb->target = tmp.target + delta;
|
|
|
+ jeb->key = tmp.key + delta;
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop)
|
|
|
{
|
|
|
unsigned long size;
|
|
|
+ void *swapfn = NULL;
|
|
|
+
|
|
|
+ if (IS_ENABLED(CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE))
|
|
|
+ swapfn = jump_label_swap;
|
|
|
|
|
|
size = (((unsigned long)stop - (unsigned long)start)
|
|
|
/ sizeof(struct jump_entry));
|
|
|
- sort(start, size, sizeof(struct jump_entry), jump_label_cmp, NULL);
|
|
|
+ sort(start, size, sizeof(struct jump_entry), jump_label_cmp, swapfn);
|
|
|
}
|
|
|
|
|
|
static void jump_label_update(struct static_key *key);
|