Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions kpatch-build/create-diff-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ static int is_gcc6_localentry_bundled_sym(struct symbol *sym)
}
#endif

static struct rela *toc_rela(const struct rela *rela)
{
if (rela->type != R_PPC64_TOC16_HA &&
rela->type != R_PPC64_TOC16_LO_DS)
return (struct rela *)rela;

/* Will return NULL for .toc constant entries */
return find_rela_by_offset(rela->sym->sec->rela, rela->addend);
}

/*
* When compiling with -ffunction-sections and -fdata-sections, almost every
* symbol gets its own dedicated section. We call such symbols "bundled"
Expand Down Expand Up @@ -854,21 +864,25 @@ static char *kpatch_section_function_name(struct section *sec)
static struct symbol *kpatch_find_static_twin(struct section *sec,
struct symbol *sym)
{
struct rela *rela;
struct rela *rela, *rela_toc;

if (!sec->twin)
return NULL;

/* find the patched object's corresponding variable */
list_for_each_entry(rela, &sec->twin->relas, list) {

if (rela->sym->twin)
rela_toc = toc_rela(rela);
if (!rela_toc)
continue; /* skip toc constants */

if (rela_toc->sym->twin)
continue;

if (kpatch_mangled_strcmp(rela->sym->name, sym->name))
if (kpatch_mangled_strcmp(rela_toc->sym->name, sym->name))
continue;

return rela->sym;
return rela_toc->sym;
}

return NULL;
Expand Down Expand Up @@ -957,12 +971,16 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *base,
list_for_each_entry(sec, &base->sections, list) {

if (!is_rela_section(sec) ||
is_debug_section(sec))
is_debug_section(sec) ||
!strcmp(sec->name, ".rela.toc"))
continue;

list_for_each_entry(rela, &sec->relas, list) {

sym = rela->sym;
if (!toc_rela(rela))
continue; /* skip toc constants */
sym = toc_rela(rela)->sym;

if (!kpatch_is_normal_static_local(sym))
continue;

Expand Down Expand Up @@ -2365,16 +2383,6 @@ static int kpatch_is_core_module_symbol(char *name)
!strcmp(name, "kpatch_shadow_get"));
}

static struct rela *toc_rela(const struct rela *rela)
{
if (rela->type != R_PPC64_TOC16_HA &&
rela->type != R_PPC64_TOC16_LO_DS)
return (struct rela *)rela;

/* Will return NULL for .toc constant entries */
return find_rela_by_offset(rela->sym->sec->rela, rela->addend);
}

/*
* If the patched code refers to a symbol, for example, calls a function
* or stores a pointer to a function somewhere, the address of that symbol
Expand Down
23 changes: 23 additions & 0 deletions test/integration/centos-7/gcc-static-local-var-6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index a9d587a..23336ed 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -106,6 +106,8 @@ static int nf_ip6_reroute(struct sk_buff *skb,
return 0;
}

+#include "kpatch-macros.h"
+
static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct flowi *fl, bool strict)
{
@@ -119,6 +121,9 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct dst_entry *result;
int err;

+ if (!jiffies)
+ printk("kpatch nf_ip6_route foo\n");
+
result = ip6_route_output(net, sk, &fl->u.ip6);
err = result->error;
if (err)
23 changes: 23 additions & 0 deletions test/integration/fedora-27/gcc-static-local-var-6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 9bf2604..026ac6c 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -109,6 +109,8 @@ static int nf_ip6_reroute(struct net *net, struct sk_buff *skb,
return 0;
}

+#include "kpatch-macros.h"
+
static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct flowi *fl, bool strict)
{
@@ -122,6 +124,9 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct dst_entry *result;
int err;

+ if (!jiffies)
+ printk("kpatch nf_ip6_route foo\n");
+
result = ip6_route_output(net, sk, &fl->u.ip6);
err = result->error;
if (err)
23 changes: 23 additions & 0 deletions test/integration/ubuntu-16.04/gcc-static-local-var-6.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 39970e2..85e750d 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -108,6 +108,8 @@ static int nf_ip6_reroute(struct net *net, struct sk_buff *skb,
return 0;
}

+#include "kpatch-macros.h"
+
static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct flowi *fl, bool strict)
{
@@ -121,6 +123,9 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct dst_entry *result;
int err;

+ if (!jiffies)
+ printk("kpatch nf_ip6_route foo\n");
+
result = ip6_route_output(net, sk, &fl->u.ip6);
err = result->error;
if (err)