From 3dd442b12db06fb2dd782e8f055f2478839f3b64 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 6 Oct 2014 22:17:24 -0500 Subject: [PATCH] section reference replacement for references inside symbols Currently unbundled section references are only replaced if the start of the symbol is referenced. It's also useful to support replacement of references which point to inside the symbol. --- kpatch-build/create-diff-object.c | 11 +++++-- .../replace-section-references.patch | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/integration/replace-section-references.patch diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index dd31377..9f63975 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1118,21 +1118,26 @@ void kpatch_replace_sections_syms(struct kpatch_elf *kelf) * with their symbols. */ list_for_each_entry(sym, &kelf->symbols, list) { + int start, end; if (sym->type == STT_SECTION || sym->sec != rela->sym->sec) continue; - if (sym->sym.st_value != rela->addend + add_off) + start = sym->sym.st_value; + end = sym->sym.st_value + sym->sym.st_size; + + if (rela->addend + add_off < start || + rela->addend + add_off >= end) continue; log_debug("%s: replacing %s+%d reference with %s+%d\n", sec->name, rela->sym->name, rela->addend, - sym->name, rela->addend - add_off); + sym->name, rela->addend - start); rela->sym = sym; - rela->addend = -add_off; + rela->addend -= start; break; } } diff --git a/test/integration/replace-section-references.patch b/test/integration/replace-section-references.patch new file mode 100644 index 0000000..24ccc4e --- /dev/null +++ b/test/integration/replace-section-references.patch @@ -0,0 +1,29 @@ +Index: src/arch/x86/kvm/x86.c +=================================================================== +--- src.orig/arch/x86/kvm/x86.c ++++ src/arch/x86/kvm/x86.c +@@ -211,6 +211,8 @@ static void shared_msr_update(unsigned s + + void kvm_define_shared_msr(unsigned slot, u32 msr) + { ++ if (!jiffies) ++ printk("kpatch kvm define shared msr\n"); + if (slot >= shared_msrs_global.nr) + shared_msrs_global.nr = slot + 1; + shared_msrs_global.msrs[slot] = msr; +@@ -6307,6 +6309,7 @@ static int complete_emulated_mmio(struct + } + + ++#include "kpatch-macros.h" + int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) + { + int r; +@@ -6352,6 +6355,7 @@ out: + + return r; + } ++KPATCH_IGNORE_FUNCTION(kvm_arch_vcpu_ioctl_run); + + int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) + {