create-klp-module: group .kpatch.symbols with like-scope

From Oracle's Linker and Libraries Guide [1]:

"The symbols in a symbol table are written in the following order ...
The global symbols immediately follow the local symbols in the symbol
table. The first global symbol is identified by the symbol table sh_info
value. Local and global symbols are always kept separate in this manner,
and cannot be mixed together."

[1] https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter6-79797/index.html

Fixes #854.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
This commit is contained in:
Joe Lawrence 2018-05-29 10:50:46 -04:00
parent ba5f3a9900
commit de10550fae
2 changed files with 22 additions and 2 deletions

View File

@ -81,7 +81,7 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
return sym;
}
ALLOC_LINK(sym, &kelf->symbols);
ALLOC_LINK(sym, NULL);
sym->name = strdup(buf);
if (!sym->name)
ERROR("strdup");
@ -93,6 +93,25 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
*/
sym->sym.st_shndx = SHN_LIVEPATCH;
sym->sym.st_info = GELF_ST_INFO(sym->bind, sym->type);
/*
* Figure out where to put the new symbol:
* a) locals need to be grouped together, before globals
* b) globals can be tacked into the end of the list
*/
if (is_local_sym(sym)) {
struct list_head *head;
struct symbol *s;
head = &kelf->symbols;
list_for_each_entry(s, &kelf->symbols, list) {
if (!is_local_sym(s))
break;
head = &s->list;
}
list_add_tail(&sym->list, head);
} else {
list_add_tail(&sym->list, &kelf->symbols);
}
return sym;
}

View File

@ -128,6 +128,7 @@ struct rela *find_rela_by_offset(struct section *relasec, unsigned int offset);
ERROR("malloc"); \
memset((_new), 0, sizeof(*(_new))); \
INIT_LIST_HEAD(&(_new)->list); \
if (_list) \
list_add_tail(&(_new)->list, (_list)); \
}