mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 04:50:07 +00:00
Fix potential problem with skipping relocations
We never seem to have hit this problem but way relative relocations were skipped was wrong. There are relative relocations only in the DT_REL/DT_RELA section. The elf_dynamic_do_##reloc function skipped the entries in all calls, though.
This commit is contained in:
parent
79b195b55a
commit
e453f6cd0c
@ -1,3 +1,12 @@
|
||||
2011-10-16 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
* elf/do-rel.h: Add another parameter nrelative, replacing the
|
||||
local variable with the same name. Change name of the function
|
||||
to end in Rel or Rela (uppercase).
|
||||
* elf/dynamic-link.h (_ELF_DYNAMIC_DO_RELOC): Add new element
|
||||
nrelative to ranges. Only nonzero for DT_REL/DT_RELA. Pass to the
|
||||
elf_dynamic_do_##reloc function.
|
||||
|
||||
2011-10-15 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
* sysdeps/i386/i686/fpu/e_log.S: No need for the fyl2xp1 use, fyl2x
|
||||
|
17
elf/do-rel.h
17
elf/do-rel.h
@ -21,13 +21,10 @@
|
||||
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
|
||||
|
||||
#ifdef DO_RELA
|
||||
# define elf_dynamic_do_rel elf_dynamic_do_rela
|
||||
# define RELCOUNT_IDX VERSYMIDX (DT_RELACOUNT)
|
||||
# define elf_dynamic_do_Rel elf_dynamic_do_Rela
|
||||
# define Rel Rela
|
||||
# define elf_machine_rel elf_machine_rela
|
||||
# define elf_machine_rel_relative elf_machine_rela_relative
|
||||
#else
|
||||
# define RELCOUNT_IDX VERSYMIDX (DT_RELCOUNT)
|
||||
#endif
|
||||
|
||||
#ifndef DO_ELF_MACHINE_REL_RELATIVE
|
||||
@ -50,9 +47,9 @@
|
||||
than fully resolved now. */
|
||||
|
||||
auto inline void __attribute__ ((always_inline))
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
elf_dynamic_do_Rel (struct link_map *map,
|
||||
ElfW(Addr) reladdr, ElfW(Addr) relsize,
|
||||
int lazy, int skip_ifunc)
|
||||
ElfW(Word) nrelative, int lazy, int skip_ifunc)
|
||||
{
|
||||
const ElfW(Rel) *r = (const void *) reladdr;
|
||||
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
|
||||
@ -73,10 +70,8 @@ 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) *relative = r;
|
||||
r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));
|
||||
r += nrelative;
|
||||
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
/* This is defined in rtld.c, but nowhere in the static libc.a; make
|
||||
@ -131,9 +126,9 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
}
|
||||
}
|
||||
|
||||
#undef elf_dynamic_do_rel
|
||||
#undef elf_dynamic_do_Rel
|
||||
#undef Rel
|
||||
#undef elf_machine_rel
|
||||
#undef elf_machine_rel_relative
|
||||
#undef DO_ELF_MACHINE_REL_RELATIVE
|
||||
#undef RELCOUNT_IDX
|
||||
#undef DO_RELA
|
||||
|
@ -258,17 +258,23 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
# ifdef ELF_MACHINE_PLTREL_OVERLAP
|
||||
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
|
||||
do { \
|
||||
struct { ElfW(Addr) start, size; int lazy; } ranges[3]; \
|
||||
struct { ElfW(Addr) start, size; ElfW(Word) nrelative; int lazy; } \
|
||||
ranges[3]; \
|
||||
int ranges_index; \
|
||||
\
|
||||
ranges[0].lazy = ranges[2].lazy = 0; \
|
||||
ranges[1].lazy = 1; \
|
||||
ranges[0].size = ranges[1].size = ranges[2].size = 0; \
|
||||
ranges[0].nrelative = ranges[1].nrelative = ranges[2].nrelative = 0; \
|
||||
\
|
||||
if ((map)->l_info[DT_##RELOC]) \
|
||||
{ \
|
||||
ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
|
||||
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
|
||||
if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
|
||||
ranges[0].nrelative \
|
||||
= MIN (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val, \
|
||||
ranges[0].size / sizeof (ElfW(reloc))); \
|
||||
} \
|
||||
\
|
||||
if ((do_lazy) \
|
||||
@ -286,21 +292,24 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
elf_dynamic_do_##reloc ((map), \
|
||||
ranges[ranges_index].start, \
|
||||
ranges[ranges_index].size, \
|
||||
ranges[ranges_index].nrelative, \
|
||||
ranges[ranges_index].lazy, \
|
||||
skip_ifunc); \
|
||||
} while (0)
|
||||
# else
|
||||
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
|
||||
do { \
|
||||
struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \
|
||||
ranges[0].lazy = 0; \
|
||||
ranges[0].size = ranges[1].size = 0; \
|
||||
ranges[0].start = 0; \
|
||||
struct { ElfW(Addr) start, size; ElfW(Word) nrelative; int lazy; } \
|
||||
ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \
|
||||
\
|
||||
if ((map)->l_info[DT_##RELOC]) \
|
||||
{ \
|
||||
ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
|
||||
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
|
||||
if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
|
||||
ranges[0].nrelative \
|
||||
= MIN (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val, \
|
||||
ranges[0].size / sizeof (ElfW(reloc))); \
|
||||
} \
|
||||
if ((map)->l_info[DT_PLTREL] \
|
||||
&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
|
||||
@ -312,7 +321,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
/* This test does not only detect whether the relocation \
|
||||
sections are in the right order, it also checks whether \
|
||||
there is a DT_REL/DT_RELA section. */ \
|
||||
|| ranges[0].start + ranges[0].size != start)) \
|
||||
|| __builtin_expect (ranges[0].start + ranges[0].size \
|
||||
!= start, 0))) \
|
||||
{ \
|
||||
ranges[1].start = start; \
|
||||
ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
|
||||
@ -327,8 +337,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
} \
|
||||
\
|
||||
if (ELF_DURING_STARTUP) \
|
||||
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0, \
|
||||
skip_ifunc); \
|
||||
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
|
||||
ranges[0].nrelative, 0, skip_ifunc); \
|
||||
else \
|
||||
{ \
|
||||
int ranges_index; \
|
||||
@ -336,6 +346,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
elf_dynamic_do_##reloc ((map), \
|
||||
ranges[ranges_index].start, \
|
||||
ranges[ranges_index].size, \
|
||||
ranges[ranges_index].nrelative, \
|
||||
ranges[ranges_index].lazy, \
|
||||
skip_ifunc); \
|
||||
} \
|
||||
@ -351,7 +362,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
# if ! ELF_MACHINE_NO_REL
|
||||
# include "do-rel.h"
|
||||
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
|
||||
_ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||
# else
|
||||
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */
|
||||
# endif
|
||||
@ -360,7 +371,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
# define DO_RELA
|
||||
# include "do-rel.h"
|
||||
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
|
||||
_ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||
# else
|
||||
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */
|
||||
# endif
|
||||
|
Loading…
Reference in New Issue
Block a user