mirror of https://github.com/dynup/kpatch
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 old_addr;
|
||||
unsigned long old_size;
|
||||
unsigned long sympos;
|
||||
char *name;
|
||||
char *objname;
|
||||
};
|
||||
|
@ -35,6 +36,7 @@ struct kpatch_patch_dynrela {
|
|||
unsigned long dest;
|
||||
unsigned long src;
|
||||
unsigned long type;
|
||||
unsigned long sympos;
|
||||
char *name;
|
||||
char *objname;
|
||||
int external;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <linux/livepatch.h>
|
||||
|
||||
|
@ -237,7 +238,11 @@ static int __init patch_init(void)
|
|||
lfunc = &lfuncs[j];
|
||||
lfunc->old_name = func->kfunc->name;
|
||||
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;
|
||||
#endif
|
||||
j++;
|
||||
}
|
||||
|
||||
|
@ -250,7 +255,11 @@ static int __init patch_init(void)
|
|||
list_for_each_entry(reloc, &object->relocs, list) {
|
||||
lreloc = &lrelocs[j];
|
||||
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;
|
||||
#endif
|
||||
lreloc->type = reloc->kdynrela->type;
|
||||
lreloc->name = reloc->kdynrela->name;
|
||||
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_size = result.size;
|
||||
funcs[index].new_size = sym->sym.st_size;
|
||||
funcs[index].sympos = result.pos;
|
||||
|
||||
/*
|
||||
* 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].type = rela->type;
|
||||
dynrelas[index].external = external;
|
||||
dynrelas[index].sympos = result.pos;
|
||||
|
||||
/* add rela to fill in dest field */
|
||||
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;
|
||||
int i;
|
||||
unsigned long pos = 0;
|
||||
char *curfile = NULL;
|
||||
|
||||
memset(result, 0, sizeof(*result));
|
||||
|
@ -159,19 +160,30 @@ int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
|||
} else if (curfile)
|
||||
curfile = NULL; /* end hint file symbols */
|
||||
}
|
||||
if (!curfile)
|
||||
continue;
|
||||
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
||||
if (match)
|
||||
/* dup file+symbol, unresolvable ambiguity */
|
||||
return 1;
|
||||
match = sym;
|
||||
if (sym->bind == STB_LOCAL) {
|
||||
if (sym->name && !strcmp(sym->name, name)) {
|
||||
/*
|
||||
* need to count any occurrence of the symbol
|
||||
* name, unless we've already found a match
|
||||
*/
|
||||
if (!match)
|
||||
pos++;
|
||||
|
||||
if (!curfile)
|
||||
continue;
|
||||
|
||||
if (match)
|
||||
/* dup file+symbol, unresolvable ambiguity */
|
||||
return 1;
|
||||
match = sym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return 1;
|
||||
|
||||
result->pos = pos;
|
||||
result->value = match->value;
|
||||
result->size = match->size;
|
||||
return 0;
|
||||
|
@ -189,6 +201,7 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
|||
!strcmp(sym->name, name)) {
|
||||
result->value = sym->value;
|
||||
result->size = sym->size;
|
||||
result->pos = 0; /* always 0 for global symbols */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -220,9 +233,9 @@ static void find_this(struct lookup_table *table, char *sym, char *hint)
|
|||
else
|
||||
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",
|
||||
result.value, result.size);
|
||||
result.value, result.size, result.pos);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
|
@ -6,6 +6,7 @@ struct lookup_table;
|
|||
struct lookup_result {
|
||||
unsigned long value;
|
||||
unsigned long size;
|
||||
unsigned long pos;
|
||||
};
|
||||
|
||||
struct lookup_table *lookup_open(char *path);
|
||||
|
|
Loading…
Reference in New Issue