(elf_dynamic_do_rel): If not relocating lazily, don't call elf_machine_rel for the last DT_RELCOUNT relocations but instead elf_machine_rel_relative.

This commit is contained in:
Ulrich Drepper 2001-08-24 08:40:21 +00:00
parent 37d8d3629e
commit c65c9d8ba0
1 changed files with 25 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/* Do relocations for ELF dynamic linking.
Copyright (C) 1995,96,97,98,99,2000 Free Software Foundation, Inc.
Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -22,8 +22,11 @@
#ifdef DO_RELA
# define elf_dynamic_do_rel elf_dynamic_do_rela
# define RELCOUNT_IDX VERSYMIDX (DT_RELACOUNT)
# define Rel Rela
# define elf_machine_rel elf_machine_rela
#else
# define RELCOUNT_IDX VERSYMIDX (DT_RELCOUNT)
#endif
#ifndef VERSYMIDX
@ -42,11 +45,11 @@ elf_dynamic_do_rel (struct link_map *map,
{
const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
ElfW(Addr) l_addr = map->l_addr;
if (lazy)
{
/* Doing lazy PLT relocations; they need very little info. */
ElfW(Addr) l_addr = map->l_addr;
for (; r < end; ++r)
elf_machine_lazy_rel (map, l_addr, r);
}
@ -54,6 +57,10 @@ elf_dynamic_do_rel (struct link_map *map,
{
const ElfW(Sym) *const symtab =
(const void *) D_PTR (map, l_info[DT_SYMTAB]);
ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL
? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val);
const ElfW(Rel) *endrel = end;
end -= nrelative;
if (map->l_info[VERSYMIDX (DT_VERSYM)])
{
@ -65,13 +72,27 @@ elf_dynamic_do_rel (struct link_map *map,
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)];
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
&map->l_versions[ndx],
(void *) (map->l_addr + r->r_offset));
(void *) (l_addr + r->r_offset));
}
}
else
for (; r < end; ++r)
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (map->l_addr + r->r_offset));
(void *) (l_addr + r->r_offset));
#ifndef RTLD_BOOTSTRAP
/* This is defined in rtld.c, but nowhere in the static libc.a; make
the reference weak so static programs can still link. This
declaration cannot be done when compiling rtld.c (i.e. #ifdef
RTLD_BOOTSTRAP) because rtld.c contains the common defn for
_dl_rtld_map, which is incompatible with a weak decl in the same
file. */
weak_extern (_dl_rtld_map);
if (map != &_dl_rtld_map) /* Already done in rtld itself. */
#endif
for (; r < endrel; ++r)
elf_machine_rel_relative (l_addr, r,
(void *) (l_addr + r->r_offset));
}
}