Rename _rtld_relocate_nonplt_object() to _rtld_relocate_nonplt_objects(),
and push the outer loop into it. This actually shaves a couple % off startup time at least on PCs.
This commit is contained in:
parent
48a1b3aab1
commit
74444a2ddb
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: alpha_reloc.c,v 1.5 2002/09/05 18:25:46 mycroft Exp $ */
|
||||
/* $NetBSD: alpha_reloc.c,v 1.6 2002/09/05 20:08:16 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
@ -109,96 +109,103 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
case R_TYPE(REFQUAD):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
*where + rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("REFQUAD %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
case R_TYPE(REFQUAD):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
*where + rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("REFQUAD %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
case R_TYPE(RELATIVE):
|
||||
{
|
||||
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
||||
extern Elf_Addr _GOT_END_[];
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
/* This is the ...iffy hueristic. */
|
||||
if (!dodebug ||
|
||||
(caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
|
||||
(caddr_t)where >= (caddr_t)_GOT_END_) {
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
} else
|
||||
rdbg(dodebug, ("RELATIVE in %s stays at %p",
|
||||
obj->path, (void *)*where));
|
||||
break;
|
||||
}
|
||||
case R_TYPE(RELATIVE):
|
||||
{
|
||||
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
||||
extern Elf_Addr _GOT_END_[];
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
/* This is the ...iffy hueristic. */
|
||||
if (!dodebug ||
|
||||
(caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
|
||||
(caddr_t)where >= (caddr_t)_GOT_END_) {
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p",
|
||||
obj->path, (void *)*where));
|
||||
} else
|
||||
rdbg(dodebug, ("RELATIVE in %s stays at %p",
|
||||
obj->path, (void *)*where));
|
||||
break;
|
||||
}
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,110 +12,118 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rel *rel;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rel = obj->rel; rel < obj->rellim; rel++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
|
||||
|
||||
switch (ELF_R_TYPE(rel->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
#if 1 /* XXX should not occur */
|
||||
case R_TYPE(PC24): { /* word32 S - P + A */
|
||||
Elf32_Sword addend;
|
||||
case R_TYPE(PC24): { /* word32 S - P + A */
|
||||
Elf32_Sword addend;
|
||||
|
||||
/*
|
||||
* Extract addend and sign-extend if needed.
|
||||
*/
|
||||
addend = *where;
|
||||
if (addend & 0x00800000)
|
||||
addend |= 0xff000000;
|
||||
/*
|
||||
* Extract addend and sign-extend if needed.
|
||||
*/
|
||||
addend = *where;
|
||||
if (addend & 0x00800000)
|
||||
addend |= 0xff000000;
|
||||
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp = (Elf_Addr)obj->relocbase + def->st_value
|
||||
- (Elf_Addr)where + (addend << 2);
|
||||
if ((tmp & 0xfe000000) != 0xfe000000 &&
|
||||
(tmp & 0xfe000000) != 0) {
|
||||
_rtld_error(
|
||||
"%s: R_ARM_PC24 relocation @ %p to %s failed "
|
||||
"(displacement %ld (%#lx) out of range)",
|
||||
obj->path, where, defobj->strtab + def->st_name,
|
||||
(long) tmp, (long) tmp);
|
||||
return -1;
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp = (Elf_Addr)obj->relocbase + def->st_value
|
||||
- (Elf_Addr)where + (addend << 2);
|
||||
if ((tmp & 0xfe000000) != 0xfe000000 &&
|
||||
(tmp & 0xfe000000) != 0) {
|
||||
_rtld_error(
|
||||
"%s: R_ARM_PC24 relocation @ %p to %s failed "
|
||||
"(displacement %ld (%#lx) out of range)",
|
||||
obj->path, where,
|
||||
defobj->strtab + def->st_name, (long) tmp,
|
||||
(long) tmp);
|
||||
return -1;
|
||||
}
|
||||
tmp >>= 2;
|
||||
*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
|
||||
rdbg(dodebug, ("PC24 %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
}
|
||||
tmp >>= 2;
|
||||
*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
|
||||
rdbg(dodebug, ("PC24 %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case R_TYPE(ABS32): /* word32 B + S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where += (Elf_Addr)defobj->relocbase + def->st_value;
|
||||
rdbg(dodebug, ("ABS32 %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
case R_TYPE(ABS32): /* word32 B + S + A */
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where += (Elf_Addr)defobj->relocbase + def->st_value;
|
||||
rdbg(dodebug, ("ABS32 %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(GLOB_DAT): /* word32 B + S */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where = (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
case R_TYPE(GLOB_DAT): /* word32 B + S */
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where = (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p @ %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p @ %p", obj->path,
|
||||
(void *)*where, where));
|
||||
break;
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p @ %p", obj->path,
|
||||
(void *)*where, where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rel->r_info),
|
||||
(u_long)ELF_R_TYPE(rel->r_info),
|
||||
(void *)rel->r_offset, (void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rel->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hppa_reloc.c,v 1.4 2002/09/05 18:25:46 mycroft Exp $ */
|
||||
/* $NetBSD: hppa_reloc.c,v 1.5 2002/09/05 20:08:16 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -335,144 +335,152 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
case R_TYPE(DIR32):
|
||||
if (ELF_R_SYM(rela->r_info)) {
|
||||
/*
|
||||
* This is either a DIR32 against a symbol
|
||||
* (def->st_name != 0), or against a local
|
||||
* section (def->st_name == 0).
|
||||
*/
|
||||
def = obj->symtab + ELF_R_SYM(rela->r_info);
|
||||
defobj = obj;
|
||||
if (def->st_name != 0)
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
case R_TYPE(DIR32):
|
||||
if (ELF_R_SYM(rela->r_info)) {
|
||||
/*
|
||||
* This is either a DIR32 against a symbol
|
||||
* (def->st_name != 0), or against a local
|
||||
* section (def->st_name == 0).
|
||||
*/
|
||||
def = obj->symtab + ELF_R_SYM(rela->r_info);
|
||||
defobj = obj;
|
||||
if (def->st_name != 0)
|
||||
/*
|
||||
* While we're relocating self,
|
||||
* _rtld_objlist is NULL, so we just
|
||||
* pass in self.
|
||||
*/
|
||||
def = _rtld_find_symdef(rela->r_info,
|
||||
obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase +
|
||||
def->st_value + rela->r_addend);
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("DIR32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
} else {
|
||||
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
||||
extern Elf_Addr _GOT_END_[];
|
||||
|
||||
tmp = (Elf_Addr)(obj->relocbase +
|
||||
rela->r_addend);
|
||||
|
||||
/* This is the ...iffy hueristic. */
|
||||
if (!dodebug ||
|
||||
(caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
|
||||
(caddr_t)where >= (caddr_t)_GOT_END_) {
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("DIR32 in %s --> %p",
|
||||
obj->path, (void *)*where));
|
||||
} else
|
||||
rdbg(dodebug, ("DIR32 in %s stays at %p",
|
||||
obj->path, (void *)*where));
|
||||
}
|
||||
break;
|
||||
|
||||
case R_TYPE(PLABEL32):
|
||||
if (ELF_R_SYM(rela->r_info)) {
|
||||
/*
|
||||
* While we're relocating self, _rtld_objlist
|
||||
* is NULL, so we just pass in self.
|
||||
*/
|
||||
def = _rtld_find_symdef(rela->r_info, obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
tmp = _rtld_function_descriptor_alloc(defobj, def,
|
||||
rela->r_addend);
|
||||
if (tmp == (Elf_Addr)-1)
|
||||
return -1;
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("DIR32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
} else {
|
||||
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
||||
extern Elf_Addr _GOT_END_[];
|
||||
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
|
||||
/* This is the ...iffy hueristic. */
|
||||
if (!dodebug ||
|
||||
(caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
|
||||
(caddr_t)where >= (caddr_t)_GOT_END_) {
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("DIR32 in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
} else
|
||||
rdbg(dodebug, ("DIR32 in %s stays at %p",
|
||||
rdbg(dodebug, ("PLABEL32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
} else {
|
||||
/*
|
||||
* This is a PLABEL for a static function, and
|
||||
* the dynamic linker has both allocated a PLT
|
||||
* entry for this function and told us where it
|
||||
* is. We can safely use the PLT entry as the
|
||||
* PLABEL because there should be no other
|
||||
* PLABEL reloc referencing this function.
|
||||
* This object should also have an IPLT
|
||||
* relocation to initialize the PLT entry.
|
||||
*
|
||||
* The dynamic linker should also have ensured
|
||||
* that the addend has the
|
||||
* next-least-significant bit set; the
|
||||
* $$dyncall millicode uses this to distinguish
|
||||
* a PLABEL pointer from a plain function
|
||||
* pointer.
|
||||
*/
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("PLABEL32 in %s --> %p",
|
||||
obj->path, (void *)*where));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_TYPE(PLABEL32):
|
||||
if (ELF_R_SYM(rela->r_info)) {
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* While we're relocating self, _rtld_objlist
|
||||
* is NULL, so we just pass in self.
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = _rtld_function_descriptor_alloc(defobj, def,
|
||||
rela->r_addend);
|
||||
if (tmp == (Elf_Addr)-1)
|
||||
return -1;
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("PLABEL32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
} else {
|
||||
/*
|
||||
* This is a PLABEL for a static function, and the
|
||||
* dynamic linker has both allocated a PLT entry
|
||||
* for this function and told us where it is. We
|
||||
* can safely use the PLT entry as the PLABEL
|
||||
* because there should be no other PLABEL reloc
|
||||
* referencing this function. This object should
|
||||
* also have an IPLT relocation to initialize the
|
||||
* PLT entry.
|
||||
*
|
||||
* The dynamic linker should also have ensured
|
||||
* that the addend has the next-least-significant
|
||||
* bit set; the $$dyncall millicode uses this to
|
||||
* distinguish a PLABEL pointer from a plain
|
||||
* function pointer.
|
||||
*/
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("PLABEL32 in %s --> %p",
|
||||
obj->path, (void *)*where));
|
||||
}
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,86 +12,92 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rel *rel;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rel = obj->rel; rel < obj->rellim; rel++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
|
||||
|
||||
switch (ELF_R_TYPE(rel->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
#if 1 /* XXX should not occur */
|
||||
case R_TYPE(PC32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(PC32):
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value) -
|
||||
(Elf_Addr)where;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value) -
|
||||
(Elf_Addr)where;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(GOT32):
|
||||
case R_TYPE(GOT32):
|
||||
#endif
|
||||
case R_TYPE(32):
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(32):
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
*where);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(RELATIVE):
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
case R_TYPE(RELATIVE):
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rel->r_info),
|
||||
(u_long)ELF_R_TYPE(rel->r_info),
|
||||
(void *)rel->r_offset, (void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rel->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,88 +12,95 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
#if 1 /* XXX should not occur */
|
||||
case R_TYPE(PC32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(PC32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend) - (Elf_Addr)where;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend) - (Elf_Addr)where;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(GOT32):
|
||||
case R_TYPE(GOT32):
|
||||
#endif
|
||||
case R_TYPE(32):
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(32):
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(RELATIVE):
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
case R_TYPE(RELATIVE):
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mips_reloc.c,v 1.8 2002/09/05 17:58:04 mycroft Exp $ */
|
||||
/* $NetBSD: mips_reloc.c,v 1.9 2002/09/05 20:08:17 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
|
||||
@ -133,86 +133,93 @@ _rtld_setup_pltgot(obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
const Elf_Rel *rel;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rel = obj->rel; rel < obj->rellim; rel++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
|
||||
|
||||
case R_TYPE(REL32):
|
||||
/* 32-bit PC-relative reference */
|
||||
def = obj->symtab + ELF_R_SYM(rela->r_info);
|
||||
switch (ELF_R_TYPE(rel->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
if (ELF_ST_BIND(def->st_info) == STB_LOCAL &&
|
||||
(ELF_ST_TYPE(def->st_info) == STT_SECTION ||
|
||||
ELF_ST_TYPE(def->st_info) == STT_NOTYPE)) {
|
||||
/*
|
||||
* XXX: ABI DIFFERENCE!
|
||||
*
|
||||
* Old NetBSD binutils would generate shared libs
|
||||
* with section-relative relocations being already
|
||||
* adjusted for the start address of the section.
|
||||
*
|
||||
* New binutils, OTOH, generate shared libs with
|
||||
* the same relocations being based at zero, so we
|
||||
* need to add in the start address of the section.
|
||||
*
|
||||
* We assume that all section-relative relocs with
|
||||
* contents less than the start of the section need
|
||||
* to be adjusted; this should work with both old
|
||||
* and new shlibs.
|
||||
*
|
||||
* --rkb, Oct 6, 2001
|
||||
*/
|
||||
if (def->st_info == STT_SECTION &&
|
||||
(*where < def->st_value))
|
||||
*where += (Elf_Addr) def->st_value;
|
||||
case R_TYPE(REL32):
|
||||
/* 32-bit PC-relative reference */
|
||||
def = obj->symtab + ELF_R_SYM(rel->r_info);
|
||||
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
if (ELF_ST_BIND(def->st_info) == STB_LOCAL &&
|
||||
(ELF_ST_TYPE(def->st_info) == STT_SECTION ||
|
||||
ELF_ST_TYPE(def->st_info) == STT_NOTYPE)) {
|
||||
/*
|
||||
* XXX: ABI DIFFERENCE!
|
||||
*
|
||||
* Old NetBSD binutils would generate shared
|
||||
* libs with section-relative relocations being
|
||||
* already adjusted for the start address of
|
||||
* the section.
|
||||
*
|
||||
* New binutils, OTOH, generate shared libs
|
||||
* with the same relocations being based at
|
||||
* zero, so we need to add in the start address
|
||||
* of the section.
|
||||
*
|
||||
* We assume that all section-relative relocs
|
||||
* with contents less than the start of the
|
||||
* section need to be adjusted; this should
|
||||
* work with both old and new shlibs.
|
||||
*
|
||||
* --rkb, Oct 6, 2001
|
||||
*/
|
||||
if (def->st_info == STT_SECTION &&
|
||||
(*where < def->st_value))
|
||||
*where += (Elf_Addr) def->st_value;
|
||||
|
||||
rdbg(dodebug, ("REL32 %s in %s --> %p in %s",
|
||||
obj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, obj->path));
|
||||
} else {
|
||||
/* XXX maybe do something re: bootstrapping? */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
rdbg(dodebug, ("REL32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
|
||||
rdbg(dodebug, ("REL32 %s in %s --> %p in %s",
|
||||
obj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, obj->path));
|
||||
} else {
|
||||
/* XXX maybe do something re: bootstrapping? */
|
||||
def = _rtld_find_symdef(rel->r_info, obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
*where += (Elf_Addr)(defobj->relocbase +
|
||||
def->st_value);
|
||||
rdbg(dodebug, ("REL32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rel->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rel->r_info),
|
||||
(u_long)ELF_R_TYPE(rel->r_info),
|
||||
(void *)rel->r_offset, (void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rel->r_info));
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_plt_object(obj, rela, addrp, bind_now, dodebug)
|
||||
_rtld_relocate_plt_objects(obj, rela, addrp, bind_now, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
caddr_t *addrp;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ppc_reloc.c,v 1.13 2002/09/05 18:25:47 mycroft Exp $ */
|
||||
/* $NetBSD: ppc_reloc.c,v 1.14 2002/09/05 20:08:18 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1998 Tsubai Masanari
|
||||
@ -183,73 +183,79 @@ _rtld_setup_pltgot(obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
case R_TYPE(32): /* word32 S + A */
|
||||
case R_TYPE(GLOB_DAT): /* word32 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
case R_TYPE(32): /* word32 S + A */
|
||||
case R_TYPE(GLOB_DAT): /* word32 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,113 +12,122 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
#if 1 /* XXX should not occur */
|
||||
case R_TYPE(GOT32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(GOT32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GOT32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GOT32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(REL32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(REL32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend) - (Elf_Addr)where;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend) - (Elf_Addr)where;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
#endif
|
||||
|
||||
case R_TYPE(DIR32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(DIR32):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
rdbg(dodebug, ("32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
*where += (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
rdbg(dodebug, ("32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
case R_TYPE(GLOB_DAT):
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
|
||||
rela->r_addend;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(RELATIVE):
|
||||
if (rela->r_addend)
|
||||
*where = (Elf_Addr)obj->relocbase + rela->r_addend;
|
||||
else
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
case R_TYPE(RELATIVE):
|
||||
if (rela->r_addend)
|
||||
*where = (Elf_Addr)obj->relocbase + rela->r_addend;
|
||||
else
|
||||
*where += (Elf_Addr)obj->relocbase;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mdreloc.c,v 1.13 2002/09/05 18:25:47 mycroft Exp $ */
|
||||
/* $NetBSD: mdreloc.c,v 1.14 2002/09/05 20:08:18 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
@ -240,102 +240,110 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
|
||||
Elf_Word type, value, mask;
|
||||
const Elf_Sym *def = NULL;
|
||||
const Obj_Entry *defobj = NULL;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
type = ELF_R_TYPE(rela->r_info);
|
||||
if (type == R_TYPE(NONE))
|
||||
return (0);
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
Elf_Word type, value, mask;
|
||||
const Elf_Sym *def = NULL;
|
||||
const Obj_Entry *defobj = NULL;
|
||||
|
||||
/* We do JMP_SLOTs in relocate_plt_object() below */
|
||||
if (type == R_TYPE(JMP_SLOT))
|
||||
return (0);
|
||||
where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
|
||||
|
||||
/* COPY relocs are also handled elsewhere */
|
||||
if (type == R_TYPE(COPY))
|
||||
return (0);
|
||||
type = ELF_R_TYPE(rela->r_info);
|
||||
if (type == R_TYPE(NONE))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We use the fact that relocation types are an `enum'
|
||||
* Note: R_SPARC_6 is currently numerically largest.
|
||||
*/
|
||||
if (type > R_TYPE(6))
|
||||
return (-1);
|
||||
/* We do JMP_SLOTs in relocate_plt_object() below */
|
||||
if (type == R_TYPE(JMP_SLOT))
|
||||
return (0);
|
||||
|
||||
value = rela->r_addend;
|
||||
/* COPY relocs are also handled elsewhere */
|
||||
if (type == R_TYPE(COPY))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Handle relative relocs here, because we might not
|
||||
* be able to access globals yet.
|
||||
*/
|
||||
if (!dodebug && type == R_TYPE(RELATIVE)) {
|
||||
*where += (Elf_Addr)(obj->relocbase + value);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
|
||||
/* Find the symbol */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
/*
|
||||
* We use the fact that relocation types are an `enum'
|
||||
* Note: R_SPARC_6 is currently numerically largest.
|
||||
*/
|
||||
if (type > R_TYPE(6))
|
||||
return (-1);
|
||||
|
||||
/* Add in the symbol's absolute address */
|
||||
value += (Elf_Word)(defobj->relocbase + def->st_value);
|
||||
}
|
||||
value = rela->r_addend;
|
||||
|
||||
if (RELOC_PC_RELATIVE(type)) {
|
||||
value -= (Elf_Word)where;
|
||||
}
|
||||
|
||||
if (RELOC_BASE_RELATIVE(type)) {
|
||||
/*
|
||||
* Note that even though sparcs use `Elf_rela' exclusively
|
||||
* we still need the implicit memory addend in relocations
|
||||
* referring to GOT entries. Undoubtedly, someone f*cked
|
||||
* this up in the distant past, and now we're stuck with
|
||||
* it in the name of compatibility for all eternity..
|
||||
*
|
||||
* In any case, the implicit and explicit should be mutually
|
||||
* exclusive. We provide a check for that here.
|
||||
* Handle relative relocs here, because we might not
|
||||
* be able to access globals yet.
|
||||
*/
|
||||
if (!dodebug && type == R_TYPE(RELATIVE)) {
|
||||
*where += (Elf_Addr)(obj->relocbase + value);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
|
||||
/* Find the symbol */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return (-1);
|
||||
|
||||
/* Add in the symbol's absolute address */
|
||||
value += (Elf_Word)(defobj->relocbase + def->st_value);
|
||||
}
|
||||
|
||||
if (RELOC_PC_RELATIVE(type)) {
|
||||
value -= (Elf_Word)where;
|
||||
}
|
||||
|
||||
if (RELOC_BASE_RELATIVE(type)) {
|
||||
/*
|
||||
* Note that even though sparcs use `Elf_rela'
|
||||
* exclusively we still need the implicit memory addend
|
||||
* in relocations referring to GOT entries.
|
||||
* Undoubtedly, someone f*cked this up in the distant
|
||||
* past, and now we're stuck with it in the name of
|
||||
* compatibility for all eternity..
|
||||
*
|
||||
* In any case, the implicit and explicit should be
|
||||
* mutually exclusive. We provide a check for that
|
||||
* here.
|
||||
*/
|
||||
#define DIAGNOSTIC
|
||||
#ifdef DIAGNOSTIC
|
||||
if (value != 0 && *where != 0) {
|
||||
xprintf("BASE_REL(%s): where=%p, *where 0x%x, "
|
||||
"addend=0x%x, base %p\n",
|
||||
obj->path, where, *where,
|
||||
rela->r_addend, obj->relocbase);
|
||||
if (value != 0 && *where != 0) {
|
||||
xprintf("BASE_REL(%s): where=%p, *where 0x%x, "
|
||||
"addend=0x%x, base %p\n",
|
||||
obj->path, where, *where,
|
||||
rela->r_addend, obj->relocbase);
|
||||
}
|
||||
#endif
|
||||
value += (Elf_Word)(obj->relocbase + *where);
|
||||
}
|
||||
|
||||
mask = RELOC_VALUE_BITMASK(type);
|
||||
value >>= RELOC_VALUE_RIGHTSHIFT(type);
|
||||
value &= mask;
|
||||
|
||||
/* We ignore alignment restrictions here */
|
||||
*where &= ~mask;
|
||||
*where |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
rdbg(dodebug, ("%s %s in %s --> %p %s",
|
||||
reloc_names[type],
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
}
|
||||
else {
|
||||
rdbg(dodebug, ("%s --> %p", reloc_names[type],
|
||||
(void *)*where));
|
||||
}
|
||||
#endif
|
||||
value += (Elf_Word)(obj->relocbase + *where);
|
||||
}
|
||||
|
||||
mask = RELOC_VALUE_BITMASK(type);
|
||||
value >>= RELOC_VALUE_RIGHTSHIFT(type);
|
||||
value &= mask;
|
||||
|
||||
/* We ignore alignment restrictions here */
|
||||
*where &= ~mask;
|
||||
*where |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
rdbg(dodebug, ("%s %s in %s --> %p %s",
|
||||
reloc_names[type],
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
}
|
||||
else {
|
||||
rdbg(dodebug, ("%s --> %p", reloc_names[type],
|
||||
(void *)*where));
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mdreloc.c,v 1.8 2002/09/05 18:25:47 mycroft Exp $ */
|
||||
/* $NetBSD: mdreloc.c,v 1.9 2002/09/05 20:08:19 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Eduardo Horvath.
|
||||
@ -521,137 +521,145 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
|
||||
Elf_Word type;
|
||||
Elf_Addr value = 0, mask;
|
||||
const Elf_Sym *def = NULL;
|
||||
const Obj_Entry *defobj = NULL;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
type = ELF_R_TYPE(rela->r_info);
|
||||
if (type == R_TYPE(NONE))
|
||||
return (0);
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
Elf_Word type;
|
||||
Elf_Addr value = 0, mask;
|
||||
const Elf_Sym *def = NULL;
|
||||
const Obj_Entry *defobj = NULL;
|
||||
|
||||
/* We do JMP_SLOTs in relocate_plt_object() below */
|
||||
if (type == R_TYPE(JMP_SLOT))
|
||||
return (0);
|
||||
where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
|
||||
|
||||
/* COPY relocs are also handled elsewhere */
|
||||
if (type == R_TYPE(COPY))
|
||||
return (0);
|
||||
type = ELF_R_TYPE(rela->r_info);
|
||||
if (type == R_TYPE(NONE))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* We use the fact that relocation types are an `enum'
|
||||
* Note: R_SPARC_UA16 is currently numerically largest.
|
||||
*/
|
||||
if (type > R_TYPE(UA16))
|
||||
return (-1);
|
||||
/* We do JMP_SLOTs in relocate_plt_object() below */
|
||||
if (type == R_TYPE(JMP_SLOT))
|
||||
return (0);
|
||||
|
||||
value = rela->r_addend;
|
||||
/* COPY relocs are also handled elsewhere */
|
||||
if (type == R_TYPE(COPY))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Handle relative relocs here, because we might not
|
||||
* be able to access globals yet.
|
||||
*/
|
||||
if (!dodebug && type == R_TYPE(RELATIVE)) {
|
||||
/* XXXX -- apparently we ignore the preexisting value */
|
||||
*where = (Elf_Addr)(obj->relocbase + value);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
|
||||
/* Find the symbol */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
/*
|
||||
* We use the fact that relocation types are an `enum'
|
||||
* Note: R_SPARC_UA16 is currently numerically largest.
|
||||
*/
|
||||
if (type > R_TYPE(UA16))
|
||||
return (-1);
|
||||
|
||||
/* Add in the symbol's absolute address */
|
||||
value += (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
}
|
||||
value = rela->r_addend;
|
||||
|
||||
if (RELOC_PC_RELATIVE(type)) {
|
||||
value -= (Elf_Addr)where;
|
||||
}
|
||||
|
||||
if (RELOC_BASE_RELATIVE(type)) {
|
||||
/*
|
||||
* Note that even though sparcs use `Elf_rela' exclusively
|
||||
* we still need the implicit memory addend in relocations
|
||||
* referring to GOT entries. Undoubtedly, someone f*cked
|
||||
* this up in the distant past, and now we're stuck with
|
||||
* it in the name of compatibility for all eternity..
|
||||
*
|
||||
* In any case, the implicit and explicit should be mutually
|
||||
* exclusive. We provide a check for that here.
|
||||
* Handle relative relocs here, because we might not
|
||||
* be able to access globals yet.
|
||||
*/
|
||||
if (!dodebug && type == R_TYPE(RELATIVE)) {
|
||||
/* XXXX -- apparently we ignore the preexisting value */
|
||||
*where = (Elf_Addr)(obj->relocbase + value);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
|
||||
/* Find the symbol */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return (-1);
|
||||
|
||||
/* Add in the symbol's absolute address */
|
||||
value += (Elf_Addr)(defobj->relocbase + def->st_value);
|
||||
}
|
||||
|
||||
if (RELOC_PC_RELATIVE(type)) {
|
||||
value -= (Elf_Addr)where;
|
||||
}
|
||||
|
||||
if (RELOC_BASE_RELATIVE(type)) {
|
||||
/*
|
||||
* Note that even though sparcs use `Elf_rela'
|
||||
* exclusively we still need the implicit memory addend
|
||||
* in relocations referring to GOT entries.
|
||||
* Undoubtedly, someone f*cked this up in the distant
|
||||
* past, and now we're stuck with it in the name of
|
||||
* compatibility for all eternity..
|
||||
*
|
||||
* In any case, the implicit and explicit should be
|
||||
* mutually exclusive. We provide a check for that
|
||||
* here.
|
||||
*/
|
||||
#ifdef DIAGNOSTIC
|
||||
if (value != 0 && *where != 0) {
|
||||
xprintf("BASE_REL(%s): where=%p, *where 0x%lx, "
|
||||
"addend=0x%lx, base %p\n",
|
||||
obj->path, where, *where,
|
||||
rela->r_addend, obj->relocbase);
|
||||
if (value != 0 && *where != 0) {
|
||||
xprintf("BASE_REL(%s): where=%p, *where 0x%lx, "
|
||||
"addend=0x%lx, base %p\n",
|
||||
obj->path, where, *where,
|
||||
rela->r_addend, obj->relocbase);
|
||||
}
|
||||
#endif
|
||||
/* XXXX -- apparently we ignore the preexisting value */
|
||||
value += (Elf_Addr)(obj->relocbase);
|
||||
}
|
||||
|
||||
mask = RELOC_VALUE_BITMASK(type);
|
||||
value >>= RELOC_VALUE_RIGHTSHIFT(type);
|
||||
value &= mask;
|
||||
|
||||
if (RELOC_UNALIGNED(type)) {
|
||||
/* Handle unaligned relocations. */
|
||||
Elf_Addr tmp = 0;
|
||||
char *ptr = (char *)where;
|
||||
int i, size = RELOC_TARGET_SIZE(type)/8;
|
||||
|
||||
/* Read it in one byte at a time. */
|
||||
for (i=0; i<size; i++)
|
||||
tmp = (tmp << 8) | ptr[i];
|
||||
|
||||
tmp &= ~mask;
|
||||
tmp |= value;
|
||||
|
||||
/* Write it back out. */
|
||||
for (i=0; i<size; i++)
|
||||
ptr[i] = ((tmp >> (8*i)) & 0xff);
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)tmp;
|
||||
#endif
|
||||
|
||||
} else if (RELOC_TARGET_SIZE(type) > 32) {
|
||||
*where &= ~mask;
|
||||
*where |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)*where;
|
||||
#endif
|
||||
} else {
|
||||
Elf32_Addr *where32 = (Elf32_Addr *)where;
|
||||
|
||||
*where32 &= ~mask;
|
||||
*where32 |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)*where32;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
rdbg(dodebug, ("%s %s in %s --> %p %s",
|
||||
reloc_names[type],
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)value, defobj->path));
|
||||
}
|
||||
else {
|
||||
rdbg(dodebug, ("%s --> %p", reloc_names[type],
|
||||
(void *)value));
|
||||
}
|
||||
#endif
|
||||
/* XXXX -- apparently we ignore the preexisting value */
|
||||
value += (Elf_Addr)(obj->relocbase);
|
||||
}
|
||||
|
||||
mask = RELOC_VALUE_BITMASK(type);
|
||||
value >>= RELOC_VALUE_RIGHTSHIFT(type);
|
||||
value &= mask;
|
||||
|
||||
if (RELOC_UNALIGNED(type)) {
|
||||
/* Handle unaligned relocations. */
|
||||
Elf_Addr tmp = 0;
|
||||
char *ptr = (char *)where;
|
||||
int i, size = RELOC_TARGET_SIZE(type)/8;
|
||||
|
||||
/* Read it in one byte at a time. */
|
||||
for (i=0; i<size; i++)
|
||||
tmp = (tmp << 8) | ptr[i];
|
||||
|
||||
tmp &= ~mask;
|
||||
tmp |= value;
|
||||
|
||||
/* Write it back out. */
|
||||
for (i=0; i<size; i++)
|
||||
ptr[i] = ((tmp >> (8*i)) & 0xff);
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)tmp;
|
||||
#endif
|
||||
|
||||
} else if (RELOC_TARGET_SIZE(type) > 32) {
|
||||
*where &= ~mask;
|
||||
*where |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)*where;
|
||||
#endif
|
||||
} else {
|
||||
Elf32_Addr *where32 = (Elf32_Addr *)where;
|
||||
|
||||
*where32 &= ~mask;
|
||||
*where32 |= value;
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
value = (Elf_Addr)*where32;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
if (RELOC_RESOLVE_SYMBOL(type)) {
|
||||
rdbg(dodebug, ("%s %s in %s --> %p %s",
|
||||
reloc_names[type],
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)value, defobj->path));
|
||||
}
|
||||
else {
|
||||
rdbg(dodebug, ("%s --> %p", reloc_names[type],
|
||||
(void *)value));
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -12,74 +12,80 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(obj, rela, dodebug)
|
||||
_rtld_relocate_nonplt_objects(obj, dodebug)
|
||||
Obj_Entry *obj;
|
||||
const Elf_Rela *rela;
|
||||
bool dodebug;
|
||||
{
|
||||
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf_Addr *where;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf_Addr tmp;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
|
||||
|
||||
case R_TYPE(32): /* word32 S + A */
|
||||
case R_TYPE(GLOB_DAT): /* word32 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
case R_TYPE(32): /* word32 S + A */
|
||||
case R_TYPE(GLOB_DAT): /* word32 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where, defobj->path));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the COPY
|
||||
* relocation is not in a shared library. They are allowed
|
||||
* only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
case R_TYPE(RELATIVE): /* word32 B + A */
|
||||
tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where != tmp)
|
||||
*where = tmp;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
/*
|
||||
* These are deferred until all other relocations have
|
||||
* been done. All we do here is make sure that the
|
||||
* COPY relocation is not in a shared library. They
|
||||
* are allowed only in executable files.
|
||||
*/
|
||||
if (!obj->mainprog) {
|
||||
_rtld_error(
|
||||
"%s: Unexpected R_COPY relocation in shared library",
|
||||
obj->path);
|
||||
obj->path);
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
rdbg(dodebug, ("COPY (avoid in main)"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mdreloc.c,v 1.8 2002/09/05 18:25:48 mycroft Exp $ */
|
||||
/* $NetBSD: mdreloc.c,v 1.9 2002/09/05 20:08:20 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
@ -138,102 +138,111 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_relocate_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, bool dodebug)
|
||||
_rtld_relocate_nonplt_objects(Obj_Entry *obj, bool dodebug)
|
||||
{
|
||||
Elf64_Addr *where64;
|
||||
Elf32_Addr *where32;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf64_Addr tmp64;
|
||||
Elf32_Addr tmp32;
|
||||
const Elf_Rela *rela;
|
||||
|
||||
where64 = (Elf64_Addr *)(obj->relocbase + rela->r_offset);
|
||||
where32 = (Elf32_Addr *)where64;
|
||||
for (rela = obj->rela; rela < obj->relalim; rela++) {
|
||||
Elf64_Addr *where64;
|
||||
Elf32_Addr *where32;
|
||||
const Elf_Sym *def;
|
||||
const Obj_Entry *defobj;
|
||||
Elf64_Addr tmp64;
|
||||
Elf32_Addr tmp32;
|
||||
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
where64 = (Elf64_Addr *)(obj->relocbase + rela->r_offset);
|
||||
where32 = (Elf32_Addr *)where64;
|
||||
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
switch (ELF_R_TYPE(rela->r_info)) {
|
||||
case R_TYPE(NONE):
|
||||
break;
|
||||
|
||||
case R_TYPE(32): /* word32 S + A, truncate */
|
||||
case R_TYPE(32S): /* word32 S + A, signed truncate */
|
||||
case R_TYPE(GOT32): /* word32 G + A (XXX can we see these?) */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
case R_TYPE(32): /* word32 S + A, truncate */
|
||||
case R_TYPE(32S): /* word32 S + A, signed truncate */
|
||||
case R_TYPE(GOT32): /* word32 G + A (XXX can we see these?) */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase +
|
||||
def->st_value + rela->r_addend);
|
||||
|
||||
if (*where32 != tmp32)
|
||||
*where32 = tmp32;
|
||||
rdbg(dodebug, ("32/32S %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)(unsigned long)*where32, defobj->path));
|
||||
break;
|
||||
case R_TYPE(64): /* word64 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("64 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where64, defobj->path));
|
||||
break;
|
||||
case R_TYPE(PC32): /* word32 S + A - P */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase +
|
||||
def->st_value + rela->r_addend -
|
||||
(Elf64_Addr)where64);
|
||||
if (*where32 != tmp32)
|
||||
*where32 = tmp32;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)(unsigned long)*where32, defobj->path));
|
||||
break;
|
||||
case R_TYPE(GLOB_DAT): /* word64 S */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value);
|
||||
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("64 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where64, defobj->path));
|
||||
break;
|
||||
case R_TYPE(RELATIVE): /* word64 B + A */
|
||||
tmp64 = (Elf64_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where64));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
rdbg(dodebug, ("COPY"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj,
|
||||
true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where64,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
|
||||
if (*where32 != tmp32)
|
||||
*where32 = tmp32;
|
||||
rdbg(dodebug, ("32/32S %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)(unsigned long)*where32, defobj->path));
|
||||
break;
|
||||
case R_TYPE(64): /* word64 S + A */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend);
|
||||
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("64 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where64, defobj->path));
|
||||
break;
|
||||
case R_TYPE(PC32): /* word32 S + A - P */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
tmp32 = (Elf32_Addr)(u_long)(defobj->relocbase + def->st_value +
|
||||
rela->r_addend - (Elf64_Addr)where64);
|
||||
if (*where32 != tmp32)
|
||||
*where32 = tmp32;
|
||||
rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)(unsigned long)*where32, defobj->path));
|
||||
break;
|
||||
case R_TYPE(GLOB_DAT): /* word64 S */
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp64 = (Elf64_Addr)(defobj->relocbase + def->st_value);
|
||||
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("64 %s in %s --> %p in %s",
|
||||
defobj->strtab + def->st_name, obj->path,
|
||||
(void *)*where64, defobj->path));
|
||||
break;
|
||||
case R_TYPE(RELATIVE): /* word64 B + A */
|
||||
tmp64 = (Elf64_Addr)(obj->relocbase + rela->r_addend);
|
||||
if (*where64 != tmp64)
|
||||
*where64 = tmp64;
|
||||
rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
|
||||
(void *)*where64));
|
||||
break;
|
||||
|
||||
case R_TYPE(COPY):
|
||||
rdbg(dodebug, ("COPY"));
|
||||
break;
|
||||
|
||||
default:
|
||||
def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
|
||||
rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
|
||||
"addend = %p, contents = %p, symbol = %s",
|
||||
(u_long)ELF_R_SYM(rela->r_info),
|
||||
(u_long)ELF_R_TYPE(rela->r_info),
|
||||
(void *)rela->r_offset, (void *)rela->r_addend,
|
||||
(void *)*where64,
|
||||
def ? defobj->strtab + def->st_name : "??"));
|
||||
_rtld_error("%s: Unsupported relocation type %ld "
|
||||
"in non-PLT relocations\n",
|
||||
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: reloc.c,v 1.59 2002/09/05 18:25:45 mycroft Exp $ */
|
||||
/* $NetBSD: reloc.c,v 1.60 2002/09/05 20:08:14 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -306,37 +306,8 @@ _rtld_relocate_objects(first, bind_now, dodebug)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (obj->rel != NULL) {
|
||||
/* Process the non-PLT relocations. */
|
||||
const Elf_Rel *rel;
|
||||
for (rel = obj->rel; rel < obj->rellim; ++rel) {
|
||||
Elf_Rela ourrela;
|
||||
ourrela.r_info = rel->r_info;
|
||||
ourrela.r_offset = rel->r_offset;
|
||||
#if defined(__mips__)
|
||||
/* rel->r_offset is not valid on mips? */
|
||||
if (ELF_R_TYPE(ourrela.r_info) == R_TYPE(NONE))
|
||||
ourrela.r_addend = 0;
|
||||
else
|
||||
#endif
|
||||
ourrela.r_addend =
|
||||
*(Elf_Word *)(obj->relocbase +
|
||||
rel->r_offset);
|
||||
|
||||
if (_rtld_relocate_nonplt_object(obj, &ourrela,
|
||||
dodebug) < 0)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (obj->rela != NULL) {
|
||||
/* Process the non-PLT relocations. */
|
||||
const Elf_Rela *rela;
|
||||
for (rela = obj->rela; rela < obj->relalim; ++rela) {
|
||||
if (_rtld_relocate_nonplt_object(obj, rela,
|
||||
dodebug) < 0)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (_rtld_relocate_nonplt_objects(obj, dodebug) < 0)
|
||||
ok = 0;
|
||||
if (obj->textrel) { /* Re-protected the text segment. */
|
||||
if (mprotect(obj->mapbase, obj->textsize,
|
||||
PROT_READ | PROT_EXEC) == -1) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.h,v 1.37 2002/09/05 16:33:57 junyoung Exp $ */
|
||||
/* $NetBSD: rtld.h,v 1.38 2002/09/05 20:08:15 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -271,8 +271,7 @@ void _rtld_process_hints __P((Search_Path **, Library_Xform **, const char *,
|
||||
int _rtld_do_copy_relocations __P((const Obj_Entry *, bool));
|
||||
caddr_t _rtld_bind __P((Obj_Entry *, Elf_Word));
|
||||
int _rtld_relocate_objects __P((Obj_Entry *, bool, bool));
|
||||
int _rtld_relocate_nonplt_object __P((Obj_Entry *,
|
||||
const Elf_Rela *, bool));
|
||||
int _rtld_relocate_nonplt_objects __P((Obj_Entry *, bool));
|
||||
int _rtld_relocate_plt_object __P((Obj_Entry *, const Elf_Rela *,
|
||||
caddr_t *, bool, bool));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user