@@ -1158,11 +1158,21 @@ static int should_keep_rela_group(struct section *sec, int start, int size)
struct rela *rela;
int found = 0;
- /* check if any relas in the group reference any changed functions */
+ /*
+ * Check if any relas in the group reference any changed functions.
+ *
+ * Relocations in the .altinstructions and .ex_table special sections
+ * can also reference changed section symbols, since the replacement
+ * text in both cases resides on a section that has no function symbols
+ * (.altinstr_replacement and .fixup respectively). Account for that
+ * and also check whether the referenced symbols are section ones in
+ * order to decide whether the relocation group needs including.
+ */
list_for_each_entry(rela, &sec->relas, list) {
if (rela->offset >= start &&
rela->offset < start + size &&
- rela->sym->type == STT_FUNC &&
+ (rela->sym->type == STT_FUNC ||
+ rela->sym->type == STT_SECTION) &&
rela->sym->sec->include) {
found = 1;
log_debug("new/changed symbol %s found in special section %s\n",
@@ -1338,6 +1348,21 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf,
rela->sym->include = 1;
+ /*
+ * Changes that cause only the
+ * .altinstr_replacement or .fixup sections to
+ * be modified need the target function of the
+ * replacement to also be marked as CHANGED,
+ * otherwise livepatch won't replace the
+ * function, and the new replacement code won't
+ * take effect.
+ */
+ if (rela->sym->type == STT_FUNC &&
+ rela->sym->status == SAME) {
+ rela->sym->status = CHANGED;
+ kpatch_include_symbol(rela->sym, 0);
+ }
+
if (!strcmp(special->name, ".fixup"))
kpatch_update_ex_table_addend(kelf, special,
src_offset,
The current logic to detect changes in special sections elements will only include group elements that reference function symbols that need including (either because they have changed or are new). This works fine in order to detect when a special section element needs including because of the function is points has changed or is newly introduced, but doesn't detect changes to the replacement code in .altinstr_replacement or .fixup sections, as the relocations in that case are against STT_SECTION symbols. Fix this by also including the special section group if the symbol the relocations points to is of type section. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- create-diff-object.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)