This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix LD_BIND_NOT and LD_PROFILE on ia64


This patch fixes PR677.  Instead of returning a pointer to a function
descriptor fixup and profile_fixup now return the descriptor itself.  This
is required for LD_BIND_NOT to work since we never actually write the
resolved descriptor to memory in this case, and for the relocation cache
used by profile_fixup.

HPPA probably has the same problem, and most likely can use the same
solution, but that needs to be looked at by someone who knows more about
HPPA.

Andreas.

2005-01-21  Andreas Schwab  <schwab@suse.de>

	[BZ #677]
	* sysdeps/ia64/dl-machine.h (elf_machine_fixup_plt)
	(elf_machine_plt_value): Change return type and type of value
	parameter to struct fdesc.
	(elf_machine_profile_fixup_plt, elf_machine_profile_plt): Remove,
	unused.
	(elf_machine_rela): Use DL_FIXUP_MAKE_VALUE to construct argument
	for elf_machine_fixup_plt.
	(TRAMPOLINE_TEMPLATE): Adapt to new return type of fixup and
	profile_fixup.
	* sysdeps/ia64/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE)
	(DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR): Define.
	* sysdeps/generic/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE)
	(DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR): Define.
	* sysdeps/hppa/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE)
	(DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR): Define.
	* sysdeps/powerpc/powerpc64/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE)
	(DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR): Define.
	* include/link.h (struct link_map): Use DL_FIXUP_VALUE_TYPE for
	l_reloc_result.
	* elf/dl-runtime.c (fixup, profile_fixup): Change return type to
	DL_FIXUP_VALUE_TYPE.  Use DL_FIXUP_VALUE_TYPE, DL_FIXUP_MAKE_VALUE
	and DL_FIXUP_VALUE_CODE_ADDR for relocation values.
	* elf/dl-reloc.c (_dl_relocate_object): Use DL_FIXUP_VALUE_TYPE
	for l_reloc_result.

Index: elf/dl-reloc.c
===================================================================
RCS file: /cvs/glibc/libc/elf/dl-reloc.c,v
retrieving revision 1.96
diff -u -a -p -r1.96 dl-reloc.c
--- elf/dl-reloc.c	7 Mar 2004 05:21:01 -0000	1.96
+++ elf/dl-reloc.c	21 Jan 2005 10:26:02 -0000
@@ -1,5 +1,5 @@
 /* Relocate a shared object and resolve its references to other loaded objects.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005 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
@@ -284,8 +284,8 @@ _dl_relocate_object (struct link_map *l,
 	  }
 
 	l->l_reloc_result =
-	  (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)),
-				 l->l_info[DT_PLTRELSZ]->d_un.d_val);
+	  (DL_FIXUP_VALUE_TYPE *) calloc (sizeof (DL_FIXUP_VALUE_TYPE),
+					  l->l_info[DT_PLTRELSZ]->d_un.d_val);
 	if (l->l_reloc_result == NULL)
 	  {
 	    errstring = N_("\
Index: elf/dl-runtime.c
===================================================================
RCS file: /cvs/glibc/libc/elf/dl-runtime.c,v
retrieving revision 1.65
diff -u -a -p -r1.65 dl-runtime.c
--- elf/dl-runtime.c	9 Mar 2004 07:42:59 -0000	1.65
+++ elf/dl-runtime.c	21 Jan 2005 10:26:02 -0000
@@ -1,5 +1,5 @@
 /* On-demand PLT fixup for shared objects.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005 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
@@ -51,7 +51,7 @@
    function.  */
 
 #ifndef ELF_MACHINE_NO_PLT
-static ElfW(Addr)
+static DL_FIXUP_VALUE_TYPE
 __attribute ((used, noinline)) ARCH_FIXUP_ATTRIBUTE
 fixup (
 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
@@ -70,7 +70,7 @@ fixup (
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
   lookup_t result;
-  ElfW(Addr) value;
+  DL_FIXUP_VALUE_TYPE value;
 
   /* Sanity check that we're really looking at a PLT relocation.  */
   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
@@ -102,13 +102,14 @@ fixup (
       /* Currently result contains the base load address (or link map)
 	 of the object that defines sym.  Now add in the symbol
 	 offset.  */
-      value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
+      value = DL_FIXUP_MAKE_VALUE (sym ? (LOOKUP_VALUE_ADDRESS (result)
+					  + sym->st_value) : 0, result);
     }
   else
     {
       /* We already found the symbol.  The module (and therefore its load
 	 address) is also known.  */
-      value = l->l_addr + sym->st_value;
+      value = DL_FIXUP_MAKE_VALUE (l->l_addr + sym->st_value, l);
 #ifdef DL_LOOKUP_RETURNS_MAP
       result = l;
 #endif
@@ -127,7 +128,7 @@ fixup (
 
 #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
 
-static ElfW(Addr)
+static DL_FIXUP_VALUE_TYPE
 __attribute ((used, noinline)) ARCH_FIXUP_ATTRIBUTE
 profile_fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
@@ -136,16 +137,16 @@ profile_fixup (
        struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
-  ElfW(Addr) *resultp;
+  DL_FIXUP_VALUE_TYPE *resultp;
   lookup_t result;
-  ElfW(Addr) value;
+  DL_FIXUP_VALUE_TYPE value;
 
   /* This is the address in the array where we store the result of previous
      relocations.  */
   resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
 
   value = *resultp;
-  if (value == 0)
+  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
     {
       /* This is the first time we have to relocate this object.  */
       const ElfW(Sym) *const symtab
@@ -187,13 +188,14 @@ profile_fixup (
 	  /* Currently result contains the base load address (or link map)
 	     of the object that defines sym.  Now add in the symbol
 	     offset.  */
-	  value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
+	  value = DL_FIXUP_MAKE_VALUE (sym ? (LOOKUP_VALUE_ADDRESS (result)
+					      + sym->st_value) : 0, result);
 	}
       else
 	{
 	  /* We already found the symbol.  The module (and therefore its load
 	     address) is also known.  */
-	  value = l->l_addr + sym->st_value;
+	  value = DL_FIXUP_MAKE_VALUE (l->l_addr + sym->st_value, l);
 #ifdef DL_LOOKUP_RETURNS_MAP
 	  result = l;
 #endif
@@ -206,7 +208,7 @@ profile_fixup (
 	*resultp = value;
     }
 
-  (*mcount_fct) (retaddr, value);
+  (*mcount_fct) (retaddr, DL_FIXUP_VALUE_CODE_ADDR (value));
 
   return value;
 }
Index: include/link.h
===================================================================
RCS file: /cvs/glibc/libc/include/link.h,v
retrieving revision 1.33
diff -u -a -p -r1.33 link.h
--- include/link.h	14 Oct 2004 01:57:54 -0000	1.33
+++ include/link.h	21 Jan 2005 10:26:02 -0000
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005 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
@@ -207,7 +207,7 @@ struct link_map
     struct r_search_path_struct l_rpath_dirs;
 
     /* Collected results of relocation while profiling.  */
-    ElfW(Addr) *l_reloc_result;
+    DL_FIXUP_VALUE_TYPE *l_reloc_result;
 
     /* Pointer to the version information if available.  */
     ElfW(Versym) *l_versyms;
Index: sysdeps/generic/dl-lookupcfg.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/generic/dl-lookupcfg.h,v
retrieving revision 1.4
diff -u -a -p -r1.4 dl-lookupcfg.h
--- sysdeps/generic/dl-lookupcfg.h	11 Oct 2002 12:19:50 -0000	1.4
+++ sysdeps/generic/dl-lookupcfg.h	21 Jan 2005 10:26:03 -0000
@@ -1,5 +1,5 @@
 /* Configuration of lookup functions.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005 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
@@ -30,3 +30,11 @@
 #else
 # undef DL_LOOKUP_RETURNS_MAP
 #endif
+
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a
+   link map.  */
+#define DL_FIXUP_MAKE_VALUE(v, t) v
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.  */
+#define DL_FIXUP_VALUE_CODE_ADDR(v) v
Index: sysdeps/hppa/dl-lookupcfg.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/hppa/dl-lookupcfg.h,v
retrieving revision 1.5
diff -u -a -p -r1.5 dl-lookupcfg.h
--- sysdeps/hppa/dl-lookupcfg.h	18 Dec 2003 03:53:47 -0000	1.5
+++ sysdeps/hppa/dl-lookupcfg.h	21 Jan 2005 10:26:03 -0000
@@ -1,5 +1,5 @@
 /* Configuration of lookup functions.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2005 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
@@ -67,3 +67,10 @@ void _dl_unmap (struct link_map *map);
 #define DL_DT_FINI_ADDRESS(map, addr) \
   ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
 
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a
+   link map.  */
+#define DL_FIXUP_MAKE_VALUE(v, t) v
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.  */
+#define DL_FIXUP_VALUE_CODE_ADDR(v) v
Index: sysdeps/ia64/dl-lookupcfg.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/dl-lookupcfg.h,v
retrieving revision 1.10
diff -u -a -p -r1.10 dl-lookupcfg.h
--- sysdeps/ia64/dl-lookupcfg.h	27 Mar 2003 01:15:24 -0000	1.10
+++ sysdeps/ia64/dl-lookupcfg.h	21 Jan 2005 10:26:03 -0000
@@ -1,5 +1,5 @@
 /* Configuration of lookup functions.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2005 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
@@ -59,3 +59,12 @@ extern void _dl_unmap (struct link_map *
 
 #define DL_DT_INIT_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
 #define DL_DT_FINI_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
+
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE struct fdesc
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a
+   link map.  */
+#define DL_FIXUP_MAKE_VALUE(v, t) \
+  ((struct fdesc) { (v), (t)->l_info[DT_PLTGOT]->d_un.d_ptr })
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.  */
+#define DL_FIXUP_VALUE_CODE_ADDR(v) (v).ip
Index: sysdeps/ia64/dl-machine.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/dl-machine.h,v
retrieving revision 1.36
diff -u -a -p -r1.36 dl-machine.h
--- sysdeps/ia64/dl-machine.h	15 Dec 2004 08:54:00 -0000	1.36
+++ sysdeps/ia64/dl-machine.h	21 Jan 2005 10:26:03 -0000
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  IA-64 version.
-   Copyright (C) 1995-1997, 2000-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 2000-2003, 2004, 2005 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
@@ -206,9 +206,9 @@ elf_machine_runtime_setup (struct link_m
 "	  br.call.sptk.many b0 = " #fixup_name "#\n"			     \
 "	}\n"								     \
 "	{ .mii\n"							     \
-"	  ld8 r9 = [ret0], 8\n"						     \
 "	  adds r2 = 16, r12\n"						     \
 "	  adds r3 = 32, r12\n"						     \
+"	  mov b6 = ret0\n"						     \
 "	  ;;\n"								     \
 "	}\n"								     \
 "	{ .mmi\n"							     \
@@ -220,7 +220,7 @@ elf_machine_runtime_setup (struct link_m
 "	{ .mmi\n"							     \
 "	  ldf.fill f10 = [r2], 32\n"					     \
 "	  ldf.fill f11 = [r3], 32\n"					     \
-"	  mov b6 = r9\n"						     \
+"	  mov gp = ret1\n"						     \
 "	  ;;\n"								     \
 "	}\n"								     \
 "	{ .mmi\n"							     \
@@ -242,7 +242,6 @@ elf_machine_runtime_setup (struct link_m
 "	  mov r11 = loc5	/* restore language specific register */\n"  \
 "	}\n"								     \
 "	{ .mii\n"							     \
-"	  ld8 gp = [ret0]\n"						     \
 "	  mov r8 = loc2		/* restore struct value register */\n"	     \
 "	  ;;\n"								     \
 "	}\n"								     \
@@ -454,34 +453,29 @@ elf_machine_runtime_setup (struct link_m
 #define ELF_MACHINE_START_ADDRESS(map, start)	\
   DL_STATIC_FUNCTION_ADDRESS (map, start)
 
-#define elf_machine_profile_fixup_plt(l, reloc, rel_addr, value) \
-  elf_machine_fixup_plt (l, reloc, rel_addr, value)
-
-#define elf_machine_profile_plt(reloc_addr) ((Elf64_Addr) (reloc_addr))
-
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
-static inline Elf64_Addr __attribute__ ((always_inline))
+static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *l, lookup_t t,
 		       const Elf64_Rela *reloc,
-		       Elf64_Addr *reloc_addr, Elf64_Addr value)
+		       Elf64_Addr *reloc_addr, struct fdesc value)
 {
   /* l is the link_map for the caller, t is the link_map for the object
    * being called */
   /* got has already been relocated in elf_get_dynamic_info() */
-  reloc_addr[1] = t->l_info[DT_PLTGOT]->d_un.d_ptr;
+  reloc_addr[1] = value.gp;
   /* we need a "release" here to ensure that the gp is visible before
      the code entry point is updated: */
-  ((volatile Elf64_Addr *) reloc_addr)[0] = value;
-  return (Elf64_Addr) reloc_addr;
+  ((volatile Elf64_Addr *) reloc_addr)[0] = value.ip;
+  return value;
 }
 
 /* Return the final value of a plt relocation.  */
-static inline Elf64_Addr
+static inline struct fdesc
 elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
-		       Elf64_Addr value)
+		       struct fdesc value)
 {
   /* No need to handle rel vs rela since IA64 is rela only */
-  return value + reloc->r_addend;
+  return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
 }
 
 #endif /* !dl_machine_h */
@@ -552,7 +546,8 @@ elf_machine_rela (struct link_map *map,
 	    ;/* No adjustment.  */
 	  else if (r_type == R_IA64_IPLTLSB)
 	    {
-	      elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
+	      elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr,
+				     DL_FIXUP_MAKE_VALUE (value, sym_map));
 	      return;
 	    }
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_FPTR64LSB))
Index: sysdeps/powerpc/powerpc64/dl-lookupcfg.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/powerpc/powerpc64/dl-lookupcfg.h,v
retrieving revision 1.1
diff -u -a -p -r1.1 dl-lookupcfg.h
--- sysdeps/powerpc/powerpc64/dl-lookupcfg.h	17 Sep 2002 23:50:02 -0000	1.1
+++ sysdeps/powerpc/powerpc64/dl-lookupcfg.h	21 Jan 2005 10:26:03 -0000
@@ -1,5 +1,5 @@
 /* Configuration of lookup functions.  PowerPC64 version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005 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
@@ -20,3 +20,11 @@
 /* Return the symbol map from the symbol lookup function.  */
 
 #define DL_LOOKUP_RETURNS_MAP 1
+
+/* The type of the return value of fixup/profile_fixup.  */
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a
+   link map.  */
+#define DL_FIXUP_MAKE_VALUE(v, t) v
+/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.  */
+#define DL_FIXUP_VALUE_CODE_ADDR(v) v

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]