summary refs log tree commit diff
path: root/elf/dl-runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-runtime.c')
-rw-r--r--elf/dl-runtime.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 088ff64c6e..08c605cd0f 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -1,5 +1,5 @@
 /* On-demand PLT fixup for shared objects.
-   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
@@ -74,15 +74,19 @@ _dl_object_relocation_scope (struct link_map *l)
 #define elf_machine_rel 1
 #define elf_machine_rela 2
 #if elf_machine_relplt == elf_machine_rel
-#define PLTREL ElfW(Rel)
+# define PLTREL ElfW(Rel)
 #elif elf_machine_relplt == elf_machine_rela
-#define PLTREL ElfW(Rela)
+# define PLTREL ElfW(Rela)
 #else
-#error "dl-machine.h bug: elf_machine_relplt not rel or rela"
+# error "dl-machine.h bug: elf_machine_relplt not rel or rela"
 #endif
 #undef elf_machine_rel
 #undef elf_machine_rela
 
+#ifndef VERSYMIDX
+# define VERSYMIDX(sym)	(DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
+#endif
+
 /* We need to define the function as a local symbol so that the reference
    in the trampoline code will be a local PC-relative call.  Tell the
    compiler not to worry that the function appears not to be called.  */
@@ -122,13 +126,28 @@ fixup (
 
   {
     /* This macro is used as a callback from the elf_machine_relplt code.  */
-#define RESOLVE(ref, flags) \
-  (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
-		      l->l_name, flags))
+#define RESOLVE(ref, version, flags) \
+  ((version) != NULL && (version)->hash != 0				      \
+   ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope,     \
+				  l->l_name, (version), (flags))	      \
+   : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope,		      \
+			l->l_name, (flags)))
 #include "dynamic-link.h"
 
     /* Perform the specified relocation.  */
-    elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)]);
+    if (l->l_info[VERSYMIDX (DT_VERNEEDNUM)])
+      {
+	const ElfW(Half) * version =
+	  (const ElfW(Half) *) (l->l_addr +
+				l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+	ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
+
+	elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
+			    &l->l_versions[ndx]);
+      }
+    else
+      elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
+			  NULL);
   }
 
   *_dl_global_scope_end = NULL;