My current ia64 patch for glibc 2.2.
H . J . Lu
hjl@valinux.com
Sat Sep 16 17:35:00 GMT 2000
This patch makes glibc 2.2 closer to my ia64 port of glibc 2.1. I will
see if there is anything else missing in glibc 2.2.
Thanks.
H.J.
----
2000-09-16 H.J. Lu <hjl@gnu.org>
* sysdeps/generic/ldsodefs.h (DL_LOOKUP_ADDRESS): New. Defined
if ELF_FUNCTION_PTR_IS_SPECIAL is not defined.
* sysdeps/ia64/dl-lookupcfg.h (_dl_lookup_address): New
prototype.
(DL_LOOKUP_ADDRESS): New. Defined as _dl_lookup_address.
* sysdeps/ia64/dl-fptr.c (_dl_lookup_address): New. Lookup
the memory location of a function from a function descriptor.
* sysdeps/ia64/Versions [ld] (GLIBC_2.2): Add
_dl_lookup_address.
* elf/dl-addr.c (_dl_addr): Use DL_LOOKUP_ADDRESS to get the
memory location.
2000-09-16 H.J. Lu <hjl@gnu.org>
* elf/rtld.c (ELF_MACHINE_ADJUST_ARGV): New macro. Do nothing
if not defined.
(_dl_start_final): Use ELF_MACHINE_ADJUST_ARGV to adjust
_dl_argv with _dl_skip_args.
* sysdeps/ia64/dl-machine.h (ELF_MACHINE_FIXED_STACK): Removed.
(ELF_MACHINE_ADJUST_ARGV): New.
2000-09-16 H.J. Lu <hjl@gnu.org>
* sysdeps/generic/ldsodefs.h (DL_UNMAP): New. Defined if
DL_UNMAP_IS_SPECIAL is not defined.
* sysdeps/ia64/dl-lookupcfg.h (DL_UNMAP_IS_SPECIAL): Defined.
(_dl_unmap): New prototype.
(DL_UNMAP): New. Defined as _dl_unmap.
* sysdeps/ia64/Versions [ld] (GLIBC_2.2): Add _dl_unmap.
* elf/dl-close.c (_dl_close): Replace __munmap with DL_UNMAP.
2000-08-27 H.J. Lu <hjl@gnu.org>
* sysdeps/unix/sysv/linux/ia64/fork.S: New.
* sysdeps/unix/sysv/linux/ia64/vfork.S: Likewise.
* sysdeps/unix/sysv/linux/ia64/clone.S: Make it dummy. No need
for it.
2000-08-24 H.J. Lu <hjl@gnu.org>
* elf/soinit.c (object): FIXME. Change it to
void * dummy [16];
for ia64.
Index: elf/dl-addr.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-addr.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 dl-addr.c
--- elf/dl-addr.c 2000/07/18 00:27:21 1.1.1.3
+++ elf/dl-addr.c 2000/09/16 22:21:26
@@ -26,7 +26,7 @@ int
internal_function
_dl_addr (const void *address, Dl_info *info)
{
- const ElfW(Addr) addr = (ElfW(Addr)) address;
+ const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
struct link_map *l, *match;
const ElfW(Sym) *symtab, *matchsym;
const char *strtab;
Index: elf/dl-close.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-close.c,v
retrieving revision 1.1.1.8
diff -u -p -r1.1.1.8 dl-close.c
--- elf/dl-close.c 2000/08/31 16:48:13 1.1.1.8
+++ elf/dl-close.c 2000/09/16 22:27:40
@@ -167,8 +167,7 @@ _dl_close (void *_map)
/* We can unmap all the maps at once. We determined the
start address and length when we loaded the object and
the `munmap' call does the rest. */
- __munmap ((void *) imap->l_map_start,
- imap->l_map_end - imap->l_map_start);
+ DL_UNMAP (imap);
/* Finally, unlink the data structure and free it. */
#ifdef SHARED
Index: elf/rtld.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/rtld.c,v
retrieving revision 1.1.1.11
diff -u -p -r1.1.1.11 rtld.c
--- elf/rtld.c 2000/09/16 06:40:17 1.1.1.11
+++ elf/rtld.c 2000/09/16 17:52:16
@@ -278,6 +278,12 @@ _dl_start_final (void *arg, struct link_
if (__builtin_expect (_dl_debug_statistics, 0))
print_statistics ();
+#ifndef ELF_MACHINE_ADJUST_ARGV
+# define ELF_MACHINE_ADJUST_ARGV(argv,skip) /* nothing */
+#endif
+
+ ELF_MACHINE_ADJUST_ARGV (_dl_argv, _dl_skip_args);
+
return *start_addr;
}
Index: elf/soinit.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/soinit.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 soinit.c
--- elf/soinit.c 2000/05/21 21:10:57 1.1.1.1
+++ elf/soinit.c 2000/08/25 00:27:01
@@ -25,12 +25,16 @@ static char __EH_FRAME_BEGIN__[]
/* This must match what's in frame.h in gcc. How can one do that? */
struct object
{
+#if 0
void *pc_begin;
void *pc_end;
void *fde_begin;
void *fde_array;
__SIZE_TYPE__ count;
struct object *next;
+#else
+ void * dummy [16];
+#endif
};
extern void __register_frame_info (const void *, struct object *);
extern void __deregister_frame_info (const void *);
Index: sysdeps/generic/ldsodefs.h
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/generic/ldsodefs.h,v
retrieving revision 1.1.1.10
diff -u -p -r1.1.1.10 ldsodefs.h
--- sysdeps/generic/ldsodefs.h 2000/08/31 16:48:50 1.1.1.10
+++ sysdeps/generic/ldsodefs.h 2000/09/16 22:29:42
@@ -69,6 +69,14 @@ typedef ElfW(Addr) lookup_t;
#ifndef ELF_FUNCTION_PTR_IS_SPECIAL
#define DL_SYMBOL_ADDRESS(map, ref) \
(void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
+#define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
+#endif
+
+/* Unmap a loaded object, called by _dl_close (). */
+#ifndef DL_UNMAP_IS_SPECIAL
+#define DL_UNMAP(map) \
+ __munmap ((void *) (map)->l_map_start, (map)->l_map_end \
+ - (map)->l_map_start)
#endif
/* For the version handling we need an array with only names and their
Index: sysdeps/ia64/Versions
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/ia64/Versions,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 Versions
--- sysdeps/ia64/Versions 2000/05/21 21:12:03 1.1.1.1
+++ sysdeps/ia64/Versions 2000/09/16 22:23:55
@@ -1,6 +1,7 @@
ld {
GLIBC_2.2 {
# ia64 specific functions in the dynamic linker, but used by libc.so.
- _dl_symbol_address;
+ _dl_symbol_address; _dl_unmap; _dl_lookup_address;
+
}
}
Index: sysdeps/ia64/dl-fptr.c
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/ia64/dl-fptr.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 dl-fptr.c
--- sysdeps/ia64/dl-fptr.c 2000/05/21 21:12:03 1.1.1.1
+++ sysdeps/ia64/dl-fptr.c 2000/09/16 23:43:10
@@ -184,3 +184,29 @@ _dl_unmap (struct link_map *map)
__ia64_fptr_lock = 0;
#endif
}
+
+Elf64_Addr
+_dl_lookup_address (const void *address)
+{
+ Elf64_Addr addr = (Elf64_Addr) address;
+ struct ia64_fptr *f;
+
+#ifdef _LIBC_REENTRANT
+ /* Make sure we are alone. */
+ while (testandset (&__ia64_fptr_lock));
+#endif
+
+ for (f = __fptr_root; f != NULL; f = f->next)
+ if (f == address)
+ {
+ addr = f->func;
+ break;
+ }
+
+#ifdef _LIBC_REENTRANT
+ /* Release the lock. */
+ __ia64_fptr_lock = 0;
+#endif
+
+ return addr;
+}
Index: sysdeps/ia64/dl-lookupcfg.h
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/ia64/dl-lookupcfg.h,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 dl-lookupcfg.h
--- sysdeps/ia64/dl-lookupcfg.h 2000/06/09 18:42:39 1.1.1.2
+++ sysdeps/ia64/dl-lookupcfg.h 2000/09/16 22:29:38
@@ -21,7 +21,16 @@
than just the address. */
#define DL_LOOKUP_RETURNS_MAP
#define ELF_FUNCTION_PTR_IS_SPECIAL
+#define DL_UNMAP_IS_SPECIAL
void *_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref);
#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
+
+Elf64_Addr _dl_lookup_address (const void *address);
+
+#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
+
+void _dl_unmap (struct link_map *map);
+
+#define DL_UNMAP(map) _dl_unmap (map)
Index: sysdeps/ia64/dl-machine.h
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/ia64/dl-machine.h,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 dl-machine.h
--- sysdeps/ia64/dl-machine.h 2000/06/09 18:42:39 1.1.1.2
+++ sysdeps/ia64/dl-machine.h 2000/09/16 17:52:14
@@ -403,7 +403,7 @@ _dl_start_user:
/* Since ia64's stack has to be 16byte aligned, we cannot arbitrarily
move the stack pointer. */
-#define ELF_MACHINE_FIXED_STACK 1
+#define ELF_MACHINE_ADJUST_ARGV(argv,skip) (argv) -= (skip);
/* Return the address of the entry point. */
extern ElfW(Addr) _dl_start_address (const struct link_map *map,
Index: sysdeps/unix/sysv/linux/ia64/clone.S
===================================================================
RCS file: /work/cvs/gnu/glibc/sysdeps/unix/sysv/linux/ia64/clone.S,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 clone.S
--- sysdeps/unix/sysv/linux/ia64/clone.S 2000/08/01 03:26:02 1.1.1.2
+++ sysdeps/unix/sysv/linux/ia64/clone.S 2000/08/01 03:32:58
@@ -1,76 +1 @@
-/* Copyright (C) 1999,2000 Free Software Foundation, Inc.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* clone is even more special than fork as it mucks with stacks
- and invokes a function in the right context after its all over. */
-
-#include <sysdep.h>
-
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
-
-/*
- * Used for both clone and fork system calls. Note that if fn is NULL
- * then clone was called from fork.
- */
-
-ENTRY(__clone)
- add r2 = -16, r33 // save space for fn and arg
- cmp.ne p6,p0 = 0,r33
- ;;
-(p6) add r33 = -16, r33
- add r12 = -16, r12
- ;;
-(p6) st8 [r2] = r32, 8 // save fn for child
- st8 [r12] = r32 // save fn for parent
- ;;
-(p6) st8 [r2] = r35 // save arg for child
- mov r32 = r34 // put flags in out0
- DO_CALL (SYS_ify (clone))
-1:
- ld8 r33 = [r12], 8 // recover fn
- ;;
- ld8 r32 = [r12], 8 // recover arg
-
- cmp.eq p6,p0=-1,r10
-(p6) br.cond.spnt.many __syscall_error // handle error
-
- cmp.ne p7,p0=0,r8
-(p7) ret // parent process, just return
-
- cmp.eq p8,p0=0,r33
-(p8) ret // fork call, return
-
- alloc loc0 = ar.pfs,2,2,2,0
- ;;
- ld8 r2 = [in1], 8 // get address of fn
- mov out0 = in0
- mov loc1 = gp // save gp across indirect call
- ;;
- ld8 gp = [in1] // set new gp
- mov b6 = r2
- br.call.sptk b0 = b6 // call thread routine
- ;;
-
- mov ar.pfs = loc0
- mov gp = loc1
- mov r32 = r8 // exit value
- ;;
- br.call.sptk b0 = _exit // we're out of here
-
-PSEUDO_END(__clone)
-
-weak_alias (__clone, clone)
+/* clone doesn't work on ia64. clone2 is ok. */
--- /dev/null Wed Aug 16 09:35:32 2000
+++ sysdeps/unix/sysv/linux/ia64/fork.S Wed Jul 12 18:35:04 2000
@@ -0,0 +1,44 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#include <sysdep.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* pid_t fork(void); */
+/* Implemented as a clone system call with parameters SIGCHLD and 0 */
+
+ENTRY(__libc_fork)
+ alloc r2=ar.pfs,0,0,2,0
+ mov out0=SIGCHLD /* Return SIGCHLD when child finishes */
+ /* no other clone flags; nothing shared */
+ mov out1=0 /* Standard sp value. */
+ ;;
+ flushrs /* For fork, it might suffice to flush */
+ /* in the kernel, but for uniformity... */
+ // DELETED STOP BITS - UNNECESSARY
+ DO_CALL (SYS_ify (clone))
+ cmp.eq p6,p0=-1,r10
+ ;;
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__libc_fork)
+
+weak_alias (__libc_fork, __fork)
+weak_alias (__libc_fork, fork)
+
--- /dev/null Wed Aug 16 09:35:32 2000
+++ sysdeps/unix/sysv/linux/ia64/vfork.S Sat Jul 15 14:45:20 2000
@@ -0,0 +1,50 @@
+/* Copyright (C) 2000 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+
+#include <sysdep.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* The following are defined in linux/sched.h, which unfortunately */
+/* is not safe for inclusion in an assembly file. */
+#define CLONE_VM 0x00000100 /* set if VM shared between processes */
+#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
+
+/* pid_t vfork(void); */
+/* Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */
+
+ENTRY(__vfork)
+ alloc r2=ar.pfs,0,0,2,0
+ mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
+ mov out1=0 /* Standard sp value. */
+ ;;
+ flushrs /* I don't think this is necessary */
+ /* here either. Otherwise the child */
+ /* may save additional registers, */
+ /* which will become visible in the */
+ /* parent. But that should be fine. */
+ // DELETED STOP BITS - UNNECESSARY
+ DO_CALL (SYS_ify (clone))
+ cmp.eq p6,p0=-1,r10
+ ;;
+(p6) br.cond.spnt.few __syscall_error
+ ret
+PSEUDO_END(__vfork)
+
+weak_alias (__vfork, vfork)
+
More information about the Libc-hacker
mailing list