aboutsummaryrefslogtreecommitdiff
path: root/elf/get-dynamic-info.h
diff options
context:
space:
mode:
Diffstat (limited to 'elf/get-dynamic-info.h')
-rw-r--r--elf/get-dynamic-info.h26
1 files changed, 21 insertions, 5 deletions
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index f9c5b84..02ba549 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -49,7 +49,12 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
while (dyn->d_tag != DT_NULL)
{
- if ((d_tag_utype) dyn->d_tag < DT_NUM)
+ /* Google-local: b/208156916. See ELF_DYNAMIC_DO_RELR. */
+ if (dyn->d_tag == DT_RELR)
+ info[VERSYMIDX (DT_VERSYM + 1)] = dyn;
+ else if (dyn->d_tag == DT_RELRSZ)
+ info[VERSYMIDX (DT_VERSYM + 2)] = dyn;
+ else if ((d_tag_utype) dyn->d_tag < DT_NUM)
info[dyn->d_tag] = dyn;
else if (dyn->d_tag >= DT_LOPROC &&
dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
@@ -104,16 +109,27 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
ADJUST_DYN_INFO (DT_PLTGOT);
ADJUST_DYN_INFO (DT_STRTAB);
ADJUST_DYN_INFO (DT_SYMTAB);
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM + 1)); /* DT_RELR */
+ ADJUST_DYN_INFO (DT_JMPREL);
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+ ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
+# 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_JMPREL);
- ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
- ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
assert (cnt <= DL_RO_DYN_TEMP_CNT);
}