summaryrefslogtreecommitdiff
path: root/elf/do-rel.h
diff options
context:
space:
mode:
Diffstat (limited to 'elf/do-rel.h')
-rw-r--r--elf/do-rel.h36
1 files changed, 28 insertions, 8 deletions
diff --git a/elf/do-rel.h b/elf/do-rel.h
index a7b7a60c66..66f135916c 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -1,5 +1,5 @@
/* Do relocations for ELF dynamic linking.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997 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
@@ -21,11 +21,14 @@
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
#ifdef DO_RELA
-#define elf_dynamic_do_rel elf_dynamic_do_rela
-#define Rel Rela
-#define elf_machine_rel elf_machine_rela
+# define elf_dynamic_do_rel elf_dynamic_do_rela
+# define Rel Rela
+# define elf_machine_rel elf_machine_rela
#endif
+#ifndef VERSYMIDX
+# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
+#endif
/* Perform the relocations in MAP on the running program image as specified
by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
@@ -37,8 +40,6 @@ elf_dynamic_do_rel (struct link_map *map,
int reltag, int sztag,
int lazy)
{
- const ElfW(Sym) *const symtab
- = (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
const ElfW(Rel) *r
= (const ElfW(Rel) *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr);
const ElfW(Rel) *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
@@ -48,8 +49,27 @@ elf_dynamic_do_rel (struct link_map *map,
for (; r < end; ++r)
elf_machine_lazy_rel (map, r);
else
- for (; r < end; ++r)
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)]);
+ {
+ const ElfW(Sym) *const symtab =
+ (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
+
+ if (map->l_info[VERSYMIDX (DT_VERNEEDNUM)])
+ {
+ const ElfW(Half) *const version =
+ (const ElfW(Half) *) (map->l_addr
+ + map->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+
+ for (; r < end; ++r)
+ {
+ 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]);
+ }
+ }
+ else
+ for (; r < end; ++r)
+ elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL);
+ }
}
#undef elf_dynamic_do_rel