summaryrefslogtreecommitdiff
path: root/elf/dynamic-link.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2022-01-04 05:47:21 -0800
committerH.J. Lu <hjl.tools@gmail.com>2022-04-26 10:16:11 -0700
commit60196d2ef2850f222c7c93818ccb4d9cdbd77276 (patch)
tree2e2d678662bc8bcd7aa9075505dd8c792cdde348 /elf/dynamic-link.h
parente895cff59aa562cad83fa0fdd187bfe4b45312d5 (diff)
downloadglibc-60196d2ef2850f222c7c93818ccb4d9cdbd77276.tar.gz
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.
Diffstat (limited to 'elf/dynamic-link.h')
-rw-r--r--elf/dynamic-link.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 019088f248..debbb8c9f7 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -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) \