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:
mycroft 2002-09-05 20:08:14 +00:00
parent 48a1b3aab1
commit 74444a2ddb
14 changed files with 1051 additions and 992 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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));