From 9233e07a0dfdb3eceb44093feb2e5928a9e391d9 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Mon, 2 Mar 2020 04:35:07 -0500 Subject: [PATCH 19/21] create-diff-object: add jump label support This patch processes the __jump_table special section, and only the jump_lable used by the changed functions will be included in __jump_table section and solve this limitation. (The livepatch in kernel should also be modified that processing the tracepoint again after the dynamic relocation by livepatch.) Signed-off-by: Zhipeng Xie --- kpatch-build/create-diff-object.c | 47 +------------------------------ 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 7d24c7e..448911b 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -2135,7 +2135,6 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, struct rela *rela, *safe; char *src, *dest; unsigned int group_size, src_offset, dest_offset, include; - int jump_table = !strcmp(special->name, "__jump_table"); LIST_HEAD(newrelas); @@ -2175,49 +2174,6 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, if (!include) continue; - /* - * Jump labels (aka static keys or static branches) aren't - * actually supported for the time being. Warn on all - * non-tracepoint jump labels when they occur in a replacement - * function. An inert tracepoint is harmless enough, but a - * broken static key can cause unexpected behavior. - * - * Here we hard-code knowledge about the contents of the - * jump_label struct. It has three fields: code, target, and - * key. - */ - if (jump_table) { - struct rela *code, *key; - int i = 0; - - list_for_each_entry(rela, &sec->relas, list) { - if (rela->offset >= src_offset && - rela->offset < src_offset + group_size) { - if (i == 0) - code = rela; - else if (i == 2) - key = rela; - i++; - } - } - - if (i != 3) - ERROR("BUG: __jump_table has an unexpected format"); - - /* inert tracepoints are harmless */ - if (!strncmp(key->sym->name, "__tracepoint_", 13)) - continue; - - /* inert dynamic debug printks are harmless */ - if (is_dynamic_debug_symbol(key->sym)) - continue; - - ERROR("Found a jump label at %s()+0x%lx, using key %s. Jump labels aren't currently supported. Use static_key_enabled() instead.", - code->sym->name, code->addend, key->sym->name); - - continue; - } - /* * Copy all relas in the group. It's possible that the relas * aren't sorted (e.g. .rela.fixup), so go through the entire @@ -2654,8 +2610,7 @@ static void kpatch_process_special_sections(struct kpatch_elf *kelf) * jump labels and enable tracepoints in a patched function. */ list_for_each_entry(sec, &kelf->sections, list) { - if (strcmp(sec->name, "__jump_table") && - strcmp(sec->name, "__tracepoints") && + if (strcmp(sec->name, "__tracepoints") && strcmp(sec->name, "__tracepoints_ptrs") && strcmp(sec->name, "__tracepoints_strings")) continue; -- 2.18.1