From 1f17adec074b9f7b8b570946652d40990e3a4df4 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Tue, 1 Jul 2014 15:27:47 -0500 Subject: [PATCH] consolidate new section pair creation Signed-off-by: Seth Jennings --- kpatch-build/create-diff-object.c | 168 ++++++++++-------------------- 1 file changed, 56 insertions(+), 112 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 34a44e2..57517a4 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1559,53 +1559,43 @@ void kpatch_create_symtab(struct kpatch_elf *kelf) symtab->sh.sh_info = nr_local; } -void kpatch_create_patches_sections(struct kpatch_elf *kelf, - struct lookup_table *table, char *hint, - char *objname) +struct section *create_section_pair(struct kpatch_elf *kelf, char *name, + int entsize, int nr) { - int nr, size, index, objname_offset; + char *relaname; struct section *sec, *relasec; - struct symbol *sym, *strsym; - struct rela *rela; - struct lookup_result result; - struct kpatch_patch_func *funcs; + int size = entsize * nr; - /* count patched functions */ - nr = 0; - list_for_each_entry(sym, &kelf->symbols, list) - if (sym->type == STT_FUNC && sym->status == CHANGED) - nr++; - - /* create .kpatch.funcs */ - - /* allocate section resources */ - ALLOC_LINK(sec, &kelf->sections); - size = nr * sizeof(*funcs); - funcs = malloc(size); - if (!funcs) + relaname = malloc(strlen(name) + strlen(".rela") + 1); + if (!relaname) ERROR("malloc"); - sec->name = ".kpatch.funcs"; + strcpy(relaname, ".rela"); + strcat(relaname, name); + + /* allocate text section resources */ + ALLOC_LINK(sec, &kelf->sections); + sec->name = name; /* set data */ sec->data = malloc(sizeof(*sec->data)); if (!sec->data) ERROR("malloc"); - sec->data->d_buf = funcs; + sec->data->d_buf = malloc(size); + if (!sec->data->d_buf) + ERROR("malloc"); sec->data->d_size = size; sec->data->d_type = ELF_T_BYTE; /* set section header */ sec->sh.sh_type = SHT_PROGBITS; - sec->sh.sh_entsize = sizeof(*funcs); + sec->sh.sh_entsize = entsize; sec->sh.sh_addralign = 8; sec->sh.sh_flags = SHF_ALLOC; sec->sh.sh_size = size; - /* create .rela.funcs */ - - /* allocate section resources */ + /* allocate rela section resources */ ALLOC_LINK(relasec, &kelf->sections); - relasec->name = ".rela.kpatch.funcs"; + relasec->name = relaname; relasec->base = sec; INIT_LIST_HEAD(&relasec->relas); @@ -1619,6 +1609,34 @@ void kpatch_create_patches_sections(struct kpatch_elf *kelf, relasec->sh.sh_entsize = sizeof(GElf_Rela); relasec->sh.sh_addralign = 8; + /* set text rela section pointer */ + sec->rela = relasec; + + return sec; +} + +void kpatch_create_patches_sections(struct kpatch_elf *kelf, + struct lookup_table *table, char *hint, + char *objname) +{ + int nr, index, objname_offset; + struct section *sec, *relasec; + struct symbol *sym, *strsym; + struct rela *rela; + struct lookup_result result; + struct kpatch_patch_func *funcs; + + /* count patched functions */ + nr = 0; + list_for_each_entry(sym, &kelf->symbols, list) + if (sym->type == STT_FUNC && sym->status == CHANGED) + nr++; + + /* create text/rela section pair */ + sec = create_section_pair(kelf, ".kpatch.funcs", sizeof(*funcs), nr); + relasec = sec->rela; + funcs = sec->data->d_buf; + /* lookup strings symbol */ strsym = find_symbol_by_name(&kelf->symbols, ".kpatch.strings"); if (!strsym) @@ -1697,7 +1715,7 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf, struct lookup_table *table, char *hint, char *objname) { - int nr, size, index, objname_offset; + int nr, index, objname_offset; struct section *sec, *sec2, *relasec; struct rela *rela, *dynrela, *safe; struct symbol *strsym; @@ -1718,46 +1736,10 @@ void kpatch_create_dynamic_rela_sections(struct kpatch_elf *kelf, nr++; /* upper bound on number of dynrelas */ } - /* create .kpatch.dynrelas*/ - - /* allocate section resources */ - ALLOC_LINK(sec, &kelf->sections); - size = nr * sizeof(*dynrelas); - dynrelas = malloc(size); - if (!dynrelas) - ERROR("malloc"); - sec->name = ".kpatch.dynrelas"; - - /* set data */ - sec->data = malloc(sizeof(*sec->data)); - if (!sec->data) - ERROR("malloc"); - sec->data->d_buf = dynrelas; - sec->data->d_type = ELF_T_BYTE; - - /* set section header */ - sec->sh.sh_type = SHT_PROGBITS; - sec->sh.sh_entsize = sizeof(*dynrelas); - sec->sh.sh_addralign = 8; - sec->sh.sh_flags = SHF_ALLOC; - - /* create .rela.kpatch.dynrelas*/ - - /* allocate section resources */ - ALLOC_LINK(relasec, &kelf->sections); - relasec->name = ".rela.kpatch.dynrelas"; - relasec->base = sec; - INIT_LIST_HEAD(&relasec->relas); - - /* set data, buffers generated by kpatch_rebuild_rela_section_data() */ - relasec->data = malloc(sizeof(*relasec->data)); - if (!relasec->data) - ERROR("malloc"); - - /* set section header */ - relasec->sh.sh_type = SHT_RELA; - relasec->sh.sh_entsize = sizeof(GElf_Rela); - relasec->sh.sh_addralign = 8; + /* create text/rela section pair */ + sec = create_section_pair(kelf, ".kpatch.dynrelas", sizeof(*dynrelas), nr); + relasec = sec->rela; + dynrelas = sec->data->d_buf; /* lookup strings symbol */ strsym = find_symbol_by_name(&kelf->symbols, ".kpatch.strings"); @@ -1903,7 +1885,7 @@ void kpatch_create_hooks_objname_rela(struct kpatch_elf *kelf, char *objname) */ void kpatch_create_mcount_sections(struct kpatch_elf *kelf) { - int nr, size, index; + int nr, index; struct section *sec, *relasec; struct symbol *sym; struct rela *rela; @@ -1915,48 +1897,10 @@ void kpatch_create_mcount_sections(struct kpatch_elf *kelf) if (sym->type == STT_FUNC && sym->status != SAME) nr++; - /* create __mcount_loc */ - - /* allocate section resources */ - ALLOC_LINK(sec, &kelf->sections); - size = nr * sizeof(*funcs); - funcs = malloc(size); - if (!funcs) - ERROR("malloc"); - sec->name = "__mcount_loc"; - - /* set data */ - sec->data = malloc(sizeof(*sec->data)); - if (!sec->data) - ERROR("malloc"); - sec->data->d_buf = funcs; - sec->data->d_size = size; - sec->data->d_type = ELF_T_BYTE; - - /* set section header */ - sec->sh.sh_type = SHT_PROGBITS; - sec->sh.sh_entsize = sizeof(*funcs); - sec->sh.sh_addralign = 8; - sec->sh.sh_flags = SHF_ALLOC; - sec->sh.sh_size = size; - - /* create .rela__mcount_loc */ - - /* allocate section resources */ - ALLOC_LINK(relasec, &kelf->sections); - relasec->name = ".rela__mcount_loc"; - relasec->base = sec; - INIT_LIST_HEAD(&relasec->relas); - - /* set data, buffers generated by kpatch_rebuild_rela_section_data() */ - relasec->data = malloc(sizeof(*relasec->data)); - if (!relasec->data) - ERROR("malloc"); - - /* set section header */ - relasec->sh.sh_type = SHT_RELA; - relasec->sh.sh_entsize = sizeof(GElf_Rela); - relasec->sh.sh_addralign = 8; + /* create text/rela section pair */ + sec = create_section_pair(kelf, "__mcount_loc", sizeof(*funcs), nr); + relasec = sec->rela; + funcs = sec->data->d_buf; /* populate sections */ index = 0;