mirror of
https://github.com/dynup/kpatch
synced 2025-02-17 02:06:53 +00:00
Merge pull request #573 from arges/493
livepatch-patch-hook: add support for livepatch sympos structures
This commit is contained in:
commit
83beb356ed
@ -27,6 +27,7 @@ struct kpatch_patch_func {
|
|||||||
unsigned long new_size;
|
unsigned long new_size;
|
||||||
unsigned long old_addr;
|
unsigned long old_addr;
|
||||||
unsigned long old_size;
|
unsigned long old_size;
|
||||||
|
unsigned long sympos;
|
||||||
char *name;
|
char *name;
|
||||||
char *objname;
|
char *objname;
|
||||||
};
|
};
|
||||||
@ -35,6 +36,7 @@ struct kpatch_patch_dynrela {
|
|||||||
unsigned long dest;
|
unsigned long dest;
|
||||||
unsigned long src;
|
unsigned long src;
|
||||||
unsigned long type;
|
unsigned long type;
|
||||||
|
unsigned long sympos;
|
||||||
char *name;
|
char *name;
|
||||||
char *objname;
|
char *objname;
|
||||||
int external;
|
int external;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
#include <linux/livepatch.h>
|
#include <linux/livepatch.h>
|
||||||
|
|
||||||
@ -237,7 +238,11 @@ static int __init patch_init(void)
|
|||||||
lfunc = &lfuncs[j];
|
lfunc = &lfuncs[j];
|
||||||
lfunc->old_name = func->kfunc->name;
|
lfunc->old_name = func->kfunc->name;
|
||||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
lfunc->new_func = (void *)func->kfunc->new_addr;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
|
||||||
|
lfunc->old_sympos = func->kfunc->sympos;
|
||||||
|
#else
|
||||||
lfunc->old_addr = func->kfunc->old_addr;
|
lfunc->old_addr = func->kfunc->old_addr;
|
||||||
|
#endif
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +255,11 @@ static int __init patch_init(void)
|
|||||||
list_for_each_entry(reloc, &object->relocs, list) {
|
list_for_each_entry(reloc, &object->relocs, list) {
|
||||||
lreloc = &lrelocs[j];
|
lreloc = &lrelocs[j];
|
||||||
lreloc->loc = reloc->kdynrela->dest;
|
lreloc->loc = reloc->kdynrela->dest;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
|
||||||
|
lreloc->sympos = reloc->kdynrela->sympos;
|
||||||
|
#else
|
||||||
lreloc->val = reloc->kdynrela->src;
|
lreloc->val = reloc->kdynrela->src;
|
||||||
|
#endif
|
||||||
lreloc->type = reloc->kdynrela->type;
|
lreloc->type = reloc->kdynrela->type;
|
||||||
lreloc->name = reloc->kdynrela->name;
|
lreloc->name = reloc->kdynrela->name;
|
||||||
lreloc->addend = reloc->kdynrela->addend;
|
lreloc->addend = reloc->kdynrela->addend;
|
||||||
|
@ -2539,6 +2539,7 @@ void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|||||||
funcs[index].old_addr = result.value;
|
funcs[index].old_addr = result.value;
|
||||||
funcs[index].old_size = result.size;
|
funcs[index].old_size = result.size;
|
||||||
funcs[index].new_size = sym->sym.st_size;
|
funcs[index].new_size = sym->sym.st_size;
|
||||||
|
funcs[index].sympos = result.pos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a relocation that will populate
|
* Add a relocation that will populate
|
||||||
@ -2715,6 +2716,7 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf,
|
|||||||
dynrelas[index].addend = rela->addend;
|
dynrelas[index].addend = rela->addend;
|
||||||
dynrelas[index].type = rela->type;
|
dynrelas[index].type = rela->type;
|
||||||
dynrelas[index].external = external;
|
dynrelas[index].external = external;
|
||||||
|
dynrelas[index].sympos = result.pos;
|
||||||
|
|
||||||
/* add rela to fill in dest field */
|
/* add rela to fill in dest field */
|
||||||
ALLOC_LINK(dynrela, &relasec->relas);
|
ALLOC_LINK(dynrela, &relasec->relas);
|
||||||
|
@ -148,6 +148,7 @@ int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
|||||||
{
|
{
|
||||||
struct symbol *sym, *match = NULL;
|
struct symbol *sym, *match = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
unsigned long pos = 0;
|
||||||
char *curfile = NULL;
|
char *curfile = NULL;
|
||||||
|
|
||||||
memset(result, 0, sizeof(*result));
|
memset(result, 0, sizeof(*result));
|
||||||
@ -159,19 +160,30 @@ int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
|||||||
} else if (curfile)
|
} else if (curfile)
|
||||||
curfile = NULL; /* end hint file symbols */
|
curfile = NULL; /* end hint file symbols */
|
||||||
}
|
}
|
||||||
if (!curfile)
|
if (sym->bind == STB_LOCAL) {
|
||||||
continue;
|
if (sym->name && !strcmp(sym->name, name)) {
|
||||||
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
/*
|
||||||
if (match)
|
* need to count any occurrence of the symbol
|
||||||
/* dup file+symbol, unresolvable ambiguity */
|
* name, unless we've already found a match
|
||||||
return 1;
|
*/
|
||||||
match = sym;
|
if (!match)
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (!curfile)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
/* dup file+symbol, unresolvable ambiguity */
|
||||||
|
return 1;
|
||||||
|
match = sym;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
result->pos = pos;
|
||||||
result->value = match->value;
|
result->value = match->value;
|
||||||
result->size = match->size;
|
result->size = match->size;
|
||||||
return 0;
|
return 0;
|
||||||
@ -189,6 +201,7 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
|||||||
!strcmp(sym->name, name)) {
|
!strcmp(sym->name, name)) {
|
||||||
result->value = sym->value;
|
result->value = sym->value;
|
||||||
result->size = sym->size;
|
result->size = sym->size;
|
||||||
|
result->pos = 0; /* always 0 for global symbols */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,9 +233,9 @@ static void find_this(struct lookup_table *table, char *sym, char *hint)
|
|||||||
else
|
else
|
||||||
lookup_global_symbol(table, sym, &result);
|
lookup_global_symbol(table, sym, &result);
|
||||||
|
|
||||||
printf("%s %s w/ %s hint at 0x%016lx len %lu\n",
|
printf("%s %s w/ %s hint at 0x%016lx len %lu pos %lu\n",
|
||||||
hint ? "local" : "global", sym, hint ? hint : "no",
|
hint ? "local" : "global", sym, hint ? hint : "no",
|
||||||
result.value, result.size);
|
result.value, result.size, result.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -6,6 +6,7 @@ struct lookup_table;
|
|||||||
struct lookup_result {
|
struct lookup_result {
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
unsigned long pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lookup_table *lookup_open(char *path);
|
struct lookup_table *lookup_open(char *path);
|
||||||
|
Loading…
Reference in New Issue
Block a user