ia64/pv_ops/bp/module: support binary patching for kernel module.
support binary patching for kernel module. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
03f511dd02
commit
ee158fcd09
2 changed files with 38 additions and 0 deletions
|
@ -16,6 +16,12 @@ struct mod_arch_specific {
|
|||
struct elf64_shdr *got; /* global offset table */
|
||||
struct elf64_shdr *opd; /* official procedure descriptors */
|
||||
struct elf64_shdr *unwind; /* unwind-table section */
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
struct elf64_shdr *paravirt_bundles;
|
||||
/* paravirt_alt_bundle_patch table */
|
||||
struct elf64_shdr *paravirt_insts;
|
||||
/* paravirt_alt_inst_patch table */
|
||||
#endif
|
||||
unsigned long gp; /* global-pointer for module */
|
||||
|
||||
void *core_unw_table; /* core unwind-table cookie returned by unwinder */
|
||||
|
|
|
@ -446,6 +446,14 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
|
|||
mod->arch.opd = s;
|
||||
else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
|
||||
mod->arch.unwind = s;
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
else if (strcmp(".paravirt_bundles",
|
||||
secstrings + s->sh_name) == 0)
|
||||
mod->arch.paravirt_bundles = s;
|
||||
else if (strcmp(".paravirt_insts",
|
||||
secstrings + s->sh_name) == 0)
|
||||
mod->arch.paravirt_insts = s;
|
||||
#endif
|
||||
|
||||
if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
|
||||
printk(KERN_ERR "%s: sections missing\n", mod->name);
|
||||
|
@ -921,6 +929,30 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo
|
|||
DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
|
||||
if (mod->arch.unwind)
|
||||
register_unwind_table(mod);
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
if (mod->arch.paravirt_bundles) {
|
||||
struct paravirt_patch_site_bundle *start =
|
||||
(struct paravirt_patch_site_bundle *)
|
||||
mod->arch.paravirt_bundles->sh_addr;
|
||||
struct paravirt_patch_site_bundle *end =
|
||||
(struct paravirt_patch_site_bundle *)
|
||||
(mod->arch.paravirt_bundles->sh_addr +
|
||||
mod->arch.paravirt_bundles->sh_size);
|
||||
|
||||
paravirt_patch_apply_bundle(start, end);
|
||||
}
|
||||
if (mod->arch.paravirt_insts) {
|
||||
struct paravirt_patch_site_inst *start =
|
||||
(struct paravirt_patch_site_inst *)
|
||||
mod->arch.paravirt_insts->sh_addr;
|
||||
struct paravirt_patch_site_inst *end =
|
||||
(struct paravirt_patch_site_inst *)
|
||||
(mod->arch.paravirt_insts->sh_addr +
|
||||
mod->arch.paravirt_insts->sh_size);
|
||||
|
||||
paravirt_patch_apply_inst(start, end);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue