mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 07:10:06 +00:00
(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:
parent
37d8d3629e
commit
c65c9d8ba0
29
elf/do-rel.h
29
elf/do-rel.h
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user