diff --git a/opal/mca/patcher/linux/patcher_linux_module.c b/opal/mca/patcher/linux/patcher_linux_module.c index 4abb651c36e..2d74c4c9f0b 100644 --- a/opal/mca/patcher/linux/patcher_linux_module.c +++ b/opal/mca/patcher/linux/patcher_linux_module.c @@ -134,23 +134,31 @@ static void mca_patcher_linux_get_strtab(ElfW(Addr) base, const ElfW(Phdr) *pdyn table->size = (dyn == NULL) ? 0 : dyn->d_un.d_val; } -static void * mca_patcher_linux_get_got_entry(ElfW(Addr) base, const char *symbol, - const mca_patcher_linux_elf_jmprel_t *jmprel, - const mca_patcher_linux_elf_symtab_t *symtab, - const mca_patcher_linux_elf_strtab_t *strtab) +static void * mca_patcher_linux_get_got_entry (ElfW(Addr) base, const ElfW(Phdr) *phdr, int16_t phnum, + int phent, const char *symbol) { + mca_patcher_linux_elf_jmprel_t jmprel; + mca_patcher_linux_elf_symtab_t symtab; + mca_patcher_linux_elf_strtab_t strtab; ElfW(Rela) *rela, *relaend; + const ElfW(Phdr) *dphdr; const char *relsymname; uint32_t relsymidx; - relaend = (ElfW(Rela) *)((char *)jmprel->tab + jmprel->size); - for (rela = jmprel->tab; rela < relaend; ++rela) { + dphdr = mca_patcher_linux_get_phdr_dynamic (phdr, phnum, phent); + + mca_patcher_linux_get_jmprel (base, dphdr, &jmprel); + mca_patcher_linux_get_symtab (base, dphdr, &symtab); + mca_patcher_linux_get_strtab (base, dphdr, &strtab); + + relaend = (ElfW(Rela) *)((char *)jmprel.tab + jmprel.size); + for (rela = jmprel.tab; rela < relaend; ++rela) { #if SIZEOF_VOID_P == 8 relsymidx = ELF64_R_SYM(rela->r_info); #else relsymidx = ELF32_R_SYM(rela->r_info); #endif - relsymname = strtab->tab + symtab->tab[relsymidx].st_name; + relsymname = strtab.tab + symtab.tab[relsymidx].st_name; if (!strcmp(symbol, relsymname)) { return (void *)(base + rela->r_offset); } @@ -217,22 +225,12 @@ static int mca_patcher_linux_modify_got (ElfW(Addr) base, const ElfW(Phdr) *phdr, const char *phname, int16_t phnum, int phent, mca_patcher_linux_dl_iter_context_t *ctx) { - const ElfW(Phdr) *dphdr; - mca_patcher_linux_elf_jmprel_t jmprel; - mca_patcher_linux_elf_symtab_t symtab; - mca_patcher_linux_elf_strtab_t strtab; long page_size = opal_getpagesize (); void **entry; void *page; int ret; - dphdr = mca_patcher_linux_get_phdr_dynamic (phdr, phnum, phent); - - mca_patcher_linux_get_jmprel (base, dphdr, &jmprel); - mca_patcher_linux_get_symtab (base, dphdr, &symtab); - mca_patcher_linux_get_strtab (base, dphdr, &strtab); - - entry = mca_patcher_linux_get_got_entry (base, ctx->patch->super.patch_symbol, &jmprel, &symtab, &strtab); + entry = mca_patcher_linux_get_got_entry (base, phdr, phnum, phent, ctx->patch->super.patch_symbol); if (entry == NULL) { return OPAL_SUCCESS; } @@ -253,7 +251,8 @@ mca_patcher_linux_modify_got (ElfW(Addr) base, const ElfW(Phdr) *phdr, const cha } opal_output_verbose (MCA_BASE_VERBOSE_TRACE, opal_patcher_base_framework.framework_output, - "modifying got entry %p with original value %p\n", (void *) entry, *entry); + "patch %p (%s): modifying got entry %p. original value %p. new value %p\n", ctx->patch, + ctx->patch->super.patch_symbol, (void *) entry, *entry, (void *) ctx->patch->super.patch_value); patch_got->got_entry = entry; patch_got->got_orig = *entry; @@ -266,7 +265,7 @@ mca_patcher_linux_modify_got (ElfW(Addr) base, const ElfW(Phdr) *phdr, const cha if (*entry == (void *) ctx->patch->super.patch_value) { /* find the appropriate entry and restore the original value */ mca_patcher_linux_patch_got_t *patch_got; - OPAL_LIST_FOREACH(patch_got, &ctx->patch->patch_got_list, mca_patcher_linux_patch_got_t) { + OPAL_LIST_FOREACH_REV(patch_got, &ctx->patch->patch_got_list, mca_patcher_linux_patch_got_t) { if (patch_got->got_entry == entry) { opal_output_verbose (MCA_BASE_VERBOSE_TRACE, opal_patcher_base_framework.framework_output, "restoring got entry %p with original value %p\n", (void *) entry, patch_got->got_orig);