mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 14:50:05 +00:00
elf: Properly handle zero DT_RELA/DT_REL values
With DT_RELR, there may be no relocations in DT_RELA/DT_REL and their entry values are zero. Don't relocate DT_RELA/DT_REL and update the combined relocation start address if their entry values are zero.
This commit is contained in:
parent
e895cff59a
commit
60196d2ef2
@ -84,7 +84,9 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
|
||||
ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \
|
||||
\
|
||||
if ((map)->l_info[DT_##RELOC]) \
|
||||
/* With DT_RELR, DT_RELA/DT_REL can have zero value. */ \
|
||||
if ((map)->l_info[DT_##RELOC] != NULL \
|
||||
&& (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0) \
|
||||
{ \
|
||||
ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
|
||||
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
|
||||
@ -98,6 +100,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||
ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \
|
||||
ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
|
||||
\
|
||||
if (ranges[0].start == 0) \
|
||||
ranges[0].start = start; \
|
||||
if (ranges[0].start + ranges[0].size == (start + size)) \
|
||||
ranges[0].size -= size; \
|
||||
if (!(do_lazy) \
|
||||
|
@ -75,24 +75,36 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
|
||||
|
||||
# define ADJUST_DYN_INFO(tag) \
|
||||
do \
|
||||
if (info[tag] != NULL) \
|
||||
info[tag]->d_un.d_ptr += l_addr; \
|
||||
{ \
|
||||
if (info[tag] != NULL) \
|
||||
info[tag]->d_un.d_ptr += l_addr; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
ADJUST_DYN_INFO (DT_HASH);
|
||||
ADJUST_DYN_INFO (DT_PLTGOT);
|
||||
ADJUST_DYN_INFO (DT_STRTAB);
|
||||
ADJUST_DYN_INFO (DT_SYMTAB);
|
||||
ADJUST_DYN_INFO (DT_RELR);
|
||||
ADJUST_DYN_INFO (DT_JMPREL);
|
||||
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
|
||||
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
|
||||
# undef ADJUST_DYN_INFO
|
||||
|
||||
/* DT_RELA/DT_REL are mandatory. But they may have zero value if
|
||||
there is DT_RELR. Don't relocate them if they are zero. */
|
||||
# define ADJUST_DYN_INFO(tag) \
|
||||
do \
|
||||
if (info[tag] != NULL && info[tag]->d_un.d_ptr != 0) \
|
||||
info[tag]->d_un.d_ptr += l_addr; \
|
||||
while (0)
|
||||
|
||||
# if ! ELF_MACHINE_NO_RELA
|
||||
ADJUST_DYN_INFO (DT_RELA);
|
||||
# endif
|
||||
# if ! ELF_MACHINE_NO_REL
|
||||
ADJUST_DYN_INFO (DT_REL);
|
||||
# endif
|
||||
ADJUST_DYN_INFO (DT_RELR);
|
||||
ADJUST_DYN_INFO (DT_JMPREL);
|
||||
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
|
||||
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
|
||||
# undef ADJUST_DYN_INFO
|
||||
}
|
||||
if (info[DT_PLTREL] != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user