static inline int _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *tp) { Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset); Elf_Addr new_value; const Elf_Sym *def; const Obj_Entry *defobj; unsigned long info = rela->r_info; assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT)); def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL); if (__predict_false(def == NULL)) return -1; if (__predict_false(def == &_rtld_sym_zero)) return 0; new_value = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend); rdbg(("bind now/fixup in %s --> old=%p new=%p", defobj->strtab + def->st_name, (void *)*where, (void *)new_value)); if (*where != new_value) *where = new_value; if (tp) *tp = new_value - rela->r_addend; return 0; }
static int _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel, Elf_Addr *tp) { Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset); Elf_Addr new_value; const Elf_Sym *def; const Obj_Entry *defobj; unsigned long info = rel->r_info; assert(ELF_R_TYPE(info) == R_TYPE(JUMP_SLOT)); def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL); if (__predict_false(def == NULL)) return -1; if (__predict_false(def == &_rtld_sym_zero)) return 0; if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { if (tp == NULL) return 0; new_value = _rtld_resolve_ifunc(defobj, def); } else { new_value = (Elf_Addr)(defobj->relocbase + def->st_value); } rdbg(("bind now/fixup in %s --> old=%p new=%p", defobj->strtab + def->st_name, (void *)*where, (void *)new_value)); if (*where != new_value) *where = new_value; if (tp) *tp = new_value; return 0; }
static inline int _rtld_relocate_plt_object(const Obj_Entry *obj, Elf_Word sym, Elf_Addr *tp) { Elf_Addr *got = obj->pltgot; const Elf_Sym *def; const Obj_Entry *defobj; Elf_Addr new_value; def = _rtld_find_plt_symdef(sym, obj, &defobj, tp != NULL); if (__predict_false(def == NULL)) return -1; if (__predict_false(def == &_rtld_sym_zero)) return 0; if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { if (tp == NULL) return 0; new_value = _rtld_resolve_ifunc(defobj, def); } else { new_value = (Elf_Addr)(defobj->relocbase + def->st_value); } rdbg(("bind now/fixup in %s --> new=%p", defobj->strtab + def->st_name, (void *)new_value)); got[obj->local_gotno + sym - obj->gotsym] = new_value; if (tp) *tp = new_value; return 0; }