Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}