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


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

[PATCH] Port hppa over to generic function descriptors.


libc-alpha,

I promise this patch makes more sense than my last.

Ported hppa over to the generic function descriptor code used by ia64.
Included here is the first set of changes. The second set encompass the
changes required to dl-machine.h, unfortunately that file has a lot of
changes that have been accrued over the years.

I opted to keep a modified version of _dl_symbol_address, and making it
a macro wasn't very pretty.

On hppa function calls are made through $$dyncall() a gcc function that 
checks to see if the PLABEL bit (address|~2) is set, if it is then, 
the ip/gp are loaded. We reserve the other bit (address|~1) for the ABI, 
it's currently unused.

Cheers,
Carlos.

---
 Makefile       |    5 +++--
 dl-fptr.h      |   35 +++++++++++++++++++++++++++++++++++
 dl-lookupcfg.h |   35 ++++++++++++++++++++++++++---------
 dl-symaddr.c   |   17 +++++++----------
 4 files changed, 71 insertions(+), 21 deletions(-)
---

2003-12-17  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the
	correct build strings.
	* sysdeps/hppa/dl-fptr.h: New.
	* sysdeps/hppa/dl-fptr.c: Removed.
	* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr,
	remove const qualifier for map.
	(_dl_function_address): Removed.
	* sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear
	PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and
	DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and
	DL_DT_FINI_ADDRESS use the previous two macros.

--- libc-orig/sysdeps/hppa/Makefile	2003-10-10 21:28:59.000000000 -0400
+++ libc/sysdeps/hppa/Makefile	2003-12-10 17:16:07.000000000 -0500
@@ -24,8 +24,9 @@
 
 ifeq ($(subdir),elf)
 CFLAGS-rtld.c += -mdisable-fpregs
-dl-routines += dl-symaddr dl-fptr
-rtld-routines += dl-symaddr dl-fptr
+sysdep-dl-routines += dl-symaddr dl-fptr
+sysdep_routines += $(sysdep-dl-routines)
+sysdep-rtld-routines += $(sysdep-dl-routines)
 endif
 
 ifeq ($(subdir),csu)
--- libc-orig/sysdeps/hppa/dl-fptr.h	1969-12-31 19:00:00.000000000 -0500
+++ libc/sysdeps/hppa/dl-fptr.h	2003-12-11 17:08:13.000000000 -0500
@@ -0,0 +1,35 @@
+/* Function descriptors.  HPPA version.
+   Copyright (C) 2003 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef dl_hppa_fptr_h
+#define dl_hppa_fptr_h 1
+
+#include <sysdeps/generic/dl-fptr.h>
+
+/* There are currently 20 dynamic symbols in ld.so.
+   ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big.  */
+#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN	200
+
+#define ELF_MACHINE_LOAD_ADDRESS(var, symbol)		\
+  asm ("	addil LT%%" #symbol ", %%r19\n"		\
+       "	ldw RT%%" #symbol "(%%sr0,%%r1), %0\n"	\
+      : "=&r" (var));
+
+
+#endif /* !dl_hppa_fptr_h */
--- libc-orig/sysdeps/hppa/dl-symaddr.c	2001-07-06 00:55:51.000000000 -0400
+++ libc/sysdeps/hppa/dl-symaddr.c	2003-12-17 16:21:56.000000000 -0500
@@ -21,19 +21,16 @@
 #include <dl-machine.h>
 
 void *
-_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref)
+_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
 {
+  /* Find the "ip" from the "map" and symbol "ref" */
   Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value;
 
-  /* On hppa, we have to return the pointer to function descriptor. */
-  if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC)
-    return (void *) __hppa_make_fptr (map, value, &__fptr_root, NULL);
+  /* On hppa, we have to return the pointer to function descriptor.
+     This involves an "| 2" to inform $$dyncall that this is a plabel32  */
+  if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC){
+    return (void *)((unsigned long)_dl_make_fptr (map, ref, value) | 2);
+  }
   else
     return (void *) value;
 }
-
-ElfW(Addr)
-_dl_function_address (const struct link_map *map, ElfW(Addr) start)
-{
-  return __hppa_make_fptr (map, start, &__fptr_root, NULL);
-}
--- libc-orig/sysdeps/hppa/dl-lookupcfg.h	2001-09-08 13:13:52.000000000 -0400
+++ libc/sysdeps/hppa/dl-lookupcfg.h	2003-12-17 19:30:09.000000000 -0500
@@ -26,27 +26,44 @@
 /* Forward declaration.  */
 struct link_map;
 
-void *_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref);
+void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
 
 #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
 
 Elf32_Addr _dl_lookup_address (const void *address);
 
-#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
+/* Clear the bottom two bits so generic code can find the fdesc entry */
+#define DL_LOOKUP_ADDRESS(addr) \
+  (_dl_lookup_address ((void *)((unsigned long)addr & ~3)))
 
 void _dl_unmap (struct link_map *map);
 
 #define DL_UNMAP(map) _dl_unmap (map)
 
-extern Elf32_Addr _dl_function_address (const struct link_map *map,
-					Elf32_Addr start);
+#define DL_AUTO_FUNCTION_ADDRESS(map, addr)				\
+({									\
+  unsigned int fptr[2];							\
+  fptr[0] = (unsigned int) (addr);					\
+  fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr;			\
+  /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */	\
+  (ElfW(Addr))((unsigned int)fptr | 2);					\
+})
+
+#define DL_STATIC_FUNCTION_ADDRESS(map, addr)				\
+({									\
+  static unsigned int fptr[2];						\
+  fptr[0] = (unsigned int) (addr);					\
+  fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr;			\
+  /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */	\
+  (ElfW(Addr))((unsigned int)fptr | 2);					\
+})
 
-#define DL_FUNCTION_ADDRESS(map, addr) _dl_function_address (map, addr)
 
 /* The test for "addr & 2" below is to accomodate old binaries which
    violated the ELF ABI by pointing DT_INIT and DT_FINI at a function
-   pointer.  */
+   descriptor.  */
 #define DL_DT_INIT_ADDRESS(map, addr) \
-  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
+  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
 #define DL_DT_FINI_ADDRESS(map, addr) \
-  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
+  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
+


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