consolidate new section pair creation

Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
Seth Jennings 2014-07-01 15:27:47 -05:00
parent fd637ce542
commit 1f17adec07

View File

@ -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;