mirror of
https://github.com/dynup/kpatch
synced 2025-01-15 17:40:51 +00:00
Merge pull request #817 from jpoimboe/ppc64le-static-locals-part-1
create-diff-object: fix ppc64le static local variable correlation
This commit is contained in:
commit
055f9c8596
@ -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"
|
||||
@ -854,7 +864,7 @@ 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;
|
||||
@ -862,13 +872,17 @@ static struct symbol *kpatch_find_static_twin(struct section *sec,
|
||||
/* 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;
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
23
test/integration/centos-7/gcc-static-local-var-6.patch
Normal file
23
test/integration/centos-7/gcc-static-local-var-6.patch
Normal file
@ -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
test/integration/fedora-27/gcc-static-local-var-6.patch
Normal file
23
test/integration/fedora-27/gcc-static-local-var-6.patch
Normal file
@ -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
test/integration/ubuntu-16.04/gcc-static-local-var-6.patch
Normal file
23
test/integration/ubuntu-16.04/gcc-static-local-var-6.patch
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user