mirror of https://github.com/dynup/kpatch
fix review comments
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
parent
880e271841
commit
e1177e3a03
|
@ -7,7 +7,6 @@
|
||||||
*.swp
|
*.swp
|
||||||
.tmp_versions
|
.tmp_versions
|
||||||
Module.symvers
|
Module.symvers
|
||||||
kpatch-build/lookup.o
|
|
||||||
kpatch-build/lookup
|
kpatch-build/lookup
|
||||||
kpatch-build/create-diff-object
|
kpatch-build/create-diff-object
|
||||||
man/kpatch.1.gz
|
man/kpatch.1.gz
|
||||||
|
|
|
@ -472,13 +472,13 @@ int kpatch_register(struct kpatch_module *kpmod, bool replace)
|
||||||
dynrela->type, dynrela->dest,
|
dynrela->type, dynrela->dest,
|
||||||
dynrela->src, i);
|
dynrela->src, i);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err_up;
|
goto err_put;
|
||||||
}
|
}
|
||||||
set_memory_rw((unsigned long)loc & PAGE_MASK, 1);
|
set_memory_rw((unsigned long)loc & PAGE_MASK, 1);
|
||||||
ret = probe_kernel_write(loc, &val, size);
|
ret = probe_kernel_write(loc, &val, size);
|
||||||
set_memory_ro((unsigned long)loc & PAGE_MASK, 1);
|
set_memory_ro((unsigned long)loc & PAGE_MASK, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_up;
|
goto err_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_funcs; i++) {
|
for (i = 0; i < num_funcs; i++) {
|
||||||
|
@ -597,6 +597,7 @@ err_unregister:
|
||||||
kpatch_num_registered--;
|
kpatch_num_registered--;
|
||||||
err_rollback:
|
err_rollback:
|
||||||
kpatch_remove_funcs_from_filter(funcs, num_funcs);
|
kpatch_remove_funcs_from_filter(funcs, num_funcs);
|
||||||
|
err_put:
|
||||||
module_put(kpmod->mod);
|
module_put(kpmod->mod);
|
||||||
err_up:
|
err_up:
|
||||||
up(&kpatch_mutex);
|
up(&kpatch_mutex);
|
||||||
|
|
|
@ -7,9 +7,6 @@ TARGETS = create-diff-object
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
%: %.c
|
|
||||||
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
|
||||||
|
|
||||||
create-diff-object: create-diff-object.c list.h lookup.c lookup.h
|
create-diff-object: create-diff-object.c list.h lookup.c lookup.h
|
||||||
$(CC) $(CFLAGS) create-diff-object.c lookup.c -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) create-diff-object.c lookup.c -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -1366,7 +1366,7 @@ void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
/* allocate section resources */
|
/* allocate section resources */
|
||||||
ALLOC_LINK(sec, &kelf->sections);
|
ALLOC_LINK(sec, &kelf->sections);
|
||||||
size = nr * sizeof(*patches);
|
size = nr * sizeof(*patches);
|
||||||
patches = malloc(nr * sizeof(*patches));
|
patches = malloc(size);
|
||||||
if (!patches)
|
if (!patches)
|
||||||
ERROR("malloc");
|
ERROR("malloc");
|
||||||
sec->name = ".kpatch.patches";
|
sec->name = ".kpatch.patches";
|
||||||
|
@ -1410,7 +1410,7 @@ void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
find_section_by_name(&kelf->sections, ".symtab")->index;
|
find_section_by_name(&kelf->sections, ".symtab")->index;
|
||||||
relasec->sh.sh_info = sec->index;
|
relasec->sh.sh_info = sec->index;
|
||||||
|
|
||||||
/* populate text section */
|
/* populate sections */
|
||||||
index = 0;
|
index = 0;
|
||||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||||
if (sym->type == STT_FUNC && sym->sec->include) {
|
if (sym->type == STT_FUNC && sym->sec->include) {
|
||||||
|
@ -1433,7 +1433,11 @@ void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
patches[index].old_size = result.size;
|
patches[index].old_size = result.size;
|
||||||
patches[index].new_size = sym->sym.st_size;
|
patches[index].new_size = sym->sym.st_size;
|
||||||
|
|
||||||
/* add entry in rela list */
|
/*
|
||||||
|
* Add a relocation that will populate
|
||||||
|
* the patches[index].new_addr field at
|
||||||
|
* module load time.
|
||||||
|
*/
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
rela->sym = sym;
|
rela->sym = sym;
|
||||||
rela->type = R_X86_64_64;
|
rela->type = R_X86_64_64;
|
||||||
|
@ -1480,7 +1484,7 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf,
|
||||||
/* allocate section resources */
|
/* allocate section resources */
|
||||||
ALLOC_LINK(sec, &kelf->sections);
|
ALLOC_LINK(sec, &kelf->sections);
|
||||||
size = nr * sizeof(*dynrelas);
|
size = nr * sizeof(*dynrelas);
|
||||||
dynrelas = malloc(nr * sizeof(*dynrelas));
|
dynrelas = malloc(size);
|
||||||
if (!dynrelas)
|
if (!dynrelas)
|
||||||
ERROR("malloc");
|
ERROR("malloc");
|
||||||
sec->name = ".kpatch.dynrelas";
|
sec->name = ".kpatch.dynrelas";
|
||||||
|
@ -1524,7 +1528,7 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf,
|
||||||
find_section_by_name(&kelf->sections, ".symtab")->index;
|
find_section_by_name(&kelf->sections, ".symtab")->index;
|
||||||
relasec->sh.sh_info = sec->index;
|
relasec->sh.sh_info = sec->index;
|
||||||
|
|
||||||
/* populate text section (reuse sec for iterator here) */
|
/* populate sections (reuse sec for iterator here) */
|
||||||
index = 0;
|
index = 0;
|
||||||
list_for_each_entry(sec, &kelf->sections, list) {
|
list_for_each_entry(sec, &kelf->sections, list) {
|
||||||
if (!is_rela_section(sec))
|
if (!is_rela_section(sec))
|
||||||
|
@ -1575,7 +1579,12 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf,
|
||||||
ERROR("size mismatch in dynrelas sections");
|
ERROR("size mismatch in dynrelas sections");
|
||||||
}
|
}
|
||||||
|
|
||||||
void kpatch_strip_non_included_syms(struct lookup_table *table,
|
/*
|
||||||
|
* This function strips out symbols that were referenced by changed rela
|
||||||
|
* sections, but the rela entries that referenced them were converted to
|
||||||
|
* dynrelas and are no longer needed.
|
||||||
|
*/
|
||||||
|
void kpatch_strip_unneeded_syms(struct lookup_table *table,
|
||||||
struct kpatch_elf *kelf)
|
struct kpatch_elf *kelf)
|
||||||
{
|
{
|
||||||
struct symbol *sym, *safe;
|
struct symbol *sym, *safe;
|
||||||
|
@ -1666,9 +1675,6 @@ void kpatch_write_output_elf(struct kpatch_elf *kelf, Elf *elf, char *outfile)
|
||||||
|
|
||||||
/* add changed sections */
|
/* add changed sections */
|
||||||
list_for_each_entry(sec, &kelf->sections, list) {
|
list_for_each_entry(sec, &kelf->sections, list) {
|
||||||
if (is_rela_section(sec))
|
|
||||||
kpatch_rebuild_rela_section_data(sec);
|
|
||||||
|
|
||||||
scn = elf_newscn(elfout);
|
scn = elf_newscn(elfout);
|
||||||
if (!scn)
|
if (!scn)
|
||||||
ERROR("elf_newscn");
|
ERROR("elf_newscn");
|
||||||
|
@ -1756,6 +1762,7 @@ int main(int argc, char *argv[])
|
||||||
struct arguments arguments;
|
struct arguments arguments;
|
||||||
int num_changed;
|
int num_changed;
|
||||||
struct lookup_table *vmlinux;
|
struct lookup_table *vmlinux;
|
||||||
|
struct section *sec;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
char *hint;
|
char *hint;
|
||||||
|
|
||||||
|
@ -1825,7 +1832,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
kpatch_create_patches_sections(kelf_out, vmlinux, hint);
|
kpatch_create_patches_sections(kelf_out, vmlinux, hint);
|
||||||
kpatch_create_dynamic_rela_sections(kelf_out, vmlinux, hint);
|
kpatch_create_dynamic_rela_sections(kelf_out, vmlinux, hint);
|
||||||
kpatch_strip_non_included_syms(vmlinux, kelf_out);
|
kpatch_strip_unneeded_syms(vmlinux, kelf_out);
|
||||||
|
|
||||||
kpatch_create_shstrtab(kelf_out);
|
kpatch_create_shstrtab(kelf_out);
|
||||||
kpatch_create_strtab(kelf_out);
|
kpatch_create_strtab(kelf_out);
|
||||||
|
@ -1834,6 +1841,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (arguments.inventory)
|
if (arguments.inventory)
|
||||||
kpatch_write_inventory_file(kelf_out, outfile);
|
kpatch_write_inventory_file(kelf_out, outfile);
|
||||||
|
|
||||||
|
/* rebuild the rela section data buffers from their relas lists */
|
||||||
|
list_for_each_entry(sec, &kelf_out->sections, list)
|
||||||
|
if (is_rela_section(sec))
|
||||||
|
kpatch_rebuild_rela_section_data(sec);
|
||||||
|
|
||||||
kpatch_write_output_elf(kelf_out, kelf_patched->elf, outfile);
|
kpatch_write_output_elf(kelf_out, kelf_patched->elf, outfile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -140,7 +140,7 @@ void lookup_close(struct lookup_table *table)
|
||||||
int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
||||||
struct lookup_result *result)
|
struct lookup_result *result)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym, *match = NULL;
|
||||||
int i;
|
int i;
|
||||||
char *curfile = NULL;
|
char *curfile = NULL;
|
||||||
|
|
||||||
|
@ -151,18 +151,24 @@ int lookup_local_symbol(struct lookup_table *table, char *name, char *hint,
|
||||||
curfile = sym->name;
|
curfile = sym->name;
|
||||||
continue; /* begin hint file symbols */
|
continue; /* begin hint file symbols */
|
||||||
} else if (curfile)
|
} else if (curfile)
|
||||||
break; /* end hint file symbols */
|
curfile = NULL; /* end hint file symbols */
|
||||||
}
|
}
|
||||||
if (!curfile)
|
if (!curfile)
|
||||||
continue;
|
continue;
|
||||||
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
||||||
result->value = sym->value;
|
if (match)
|
||||||
result->size = sym->size;
|
/* dup file+symbol, unresolvable ambiguity */
|
||||||
return 0;
|
return 1;
|
||||||
|
match = sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
result->value = match->value;
|
||||||
|
result->size = match->size;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lookup_global_symbol(struct lookup_table *table, char *name,
|
int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||||
|
|
Loading…
Reference in New Issue