aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-04-04 01:54:59 +0000
committerUlrich Drepper <drepper@redhat.com>2001-04-04 01:54:59 +0000
commit468946739b3f7e6031d4843fc9a9d5a6e8a16114 (patch)
treeed9798b68f273f0c295d89fec150292fd6688fb7 /sysdeps
parent194c5f8d0f6da9d84211b479adb58e118f302ae3 (diff)
downloadglibc-468946739b3f7e6031d4843fc9a9d5a6e8a16114.zip
glibc-468946739b3f7e6031d4843fc9a9d5a6e8a16114.tar.gz
glibc-468946739b3f7e6031d4843fc9a9d5a6e8a16114.tar.bz2
Update.
2001-03-29 Michael Keezer <mkeezer@redhat.com> * posix/tst-gnuglob.c: Added ifdef _DIRENT_HAVE_D_TYPE. * login/tst-utmp.c: Handle case where ut_tv is not available but ut_time is. * sysdeps/unix/sysv/aix/utmpx.h: New file. * sysdeps/unix/sysv/aix/bits/utmpx.h: Added _HAVE_UT_TYPE/PID/ID/TV/HOST defines. * sysdeps/unix/sysv/aix/libc-start.c: Removed temp code and made stub. * sysdeps/unix/sysv/aix/gettimeofday.c: New file added routines to access RTCU timer reg. * sysdeps/unix/sysv/aix/Makefile: Remove /usr/lib/crt0.o added dl-libc, dl-open,dl-sym, dl-close to misc. * sysdeps/unix/sysv/aix/start.c: New file. Start code. * sysdeps/unix/sysv/aix/dlldr.h: New file. AIX __loadx defines. * sysdeps/unix/sysv/aix/dl-close.c: New file. AIX dl-close. * sysdeps/unix/sysv/aix/dl-open.c: New file. AIX dl-open. * sysdeps/unix/sysv/aix/dl-sym.c: New file. AIX dl-sym. * sysdeps/unix/sysv/aix/dl-libc.c: New file. libc_dl-xxx support. * sysdeps/generic/strtoll.c: Added SHLIB_COMPAT(libc,GLIBC_2_0, GLIBC_2_2). * sysdeps/generic/strtoull.c: Likewise. * sysdeps/powerpc/ppc-mcount.S: Added nop after bl instruction. * sysdeps/unix/sysv/aix/powerpc/memset.c: New file to include sysdeps/generic/memset.c. * sysdeps/unix/sysv/aix/getpeername.c: Define __getpeername.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/strtoll.c3
-rw-r--r--sysdeps/generic/strtoull.c3
-rw-r--r--sysdeps/powerpc/ppc-mcount.S1
-rw-r--r--sysdeps/unix/sysv/aix/Makefile8
-rw-r--r--sysdeps/unix/sysv/aix/bits/utmpx.h7
-rw-r--r--sysdeps/unix/sysv/aix/dl-close.c47
-rw-r--r--sysdeps/unix/sysv/aix/dl-libc.c1
-rw-r--r--sysdeps/unix/sysv/aix/dl-open.c132
-rw-r--r--sysdeps/unix/sysv/aix/dl-sym.c57
-rw-r--r--sysdeps/unix/sysv/aix/dlldr.h112
-rw-r--r--sysdeps/unix/sysv/aix/getpeername.c3
-rw-r--r--sysdeps/unix/sysv/aix/gettimeofday.c94
-rw-r--r--sysdeps/unix/sysv/aix/libc-start.c21
-rw-r--r--sysdeps/unix/sysv/aix/powerpc/memset.c21
-rw-r--r--sysdeps/unix/sysv/aix/start.c290
-rw-r--r--sysdeps/unix/sysv/aix/utmpx.h89
16 files changed, 850 insertions, 39 deletions
diff --git a/sysdeps/generic/strtoll.c b/sysdeps/generic/strtoll.c
index 0163a758..aee524c 100644
--- a/sysdeps/generic/strtoll.c
+++ b/sysdeps/generic/strtoll.c
@@ -25,7 +25,10 @@
# ifdef SHARED
# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
compat_symbol (libc, __strtoll_internal, __strtoq_internal, GLIBC_2_0);
+# endif
+
# endif
weak_alias (strtoll, strtoq)
#endif
diff --git a/sysdeps/generic/strtoull.c b/sysdeps/generic/strtoull.c
index 465eb0a..2a9b5c5 100644
--- a/sysdeps/generic/strtoull.c
+++ b/sysdeps/generic/strtoull.c
@@ -25,7 +25,10 @@
# ifdef SHARED
# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
compat_symbol (libc, __strtoull_internal, __strtouq_internal, GLIBC_2_0);
+# endif
+
# endif
weak_alias (strtoull, strtouq)
#endif
diff --git a/sysdeps/powerpc/ppc-mcount.S b/sysdeps/powerpc/ppc-mcount.S
index ce5a04e..3aa8fa7 100644
--- a/sysdeps/powerpc/ppc-mcount.S
+++ b/sysdeps/powerpc/ppc-mcount.S
@@ -63,6 +63,7 @@ ENTRY(_mcount)
stw r4, 44(r1)
stw r5, 8(r1)
bl JUMPTARGET(__mcount_internal)
+ nop
/* Restore the registers... */
lwz r6, 8(r1)
lwz r0, 44(r1)
diff --git a/sysdeps/unix/sysv/aix/Makefile b/sysdeps/unix/sysv/aix/Makefile
index 9aa48d1..dc91f8f 100644
--- a/sysdeps/unix/sysv/aix/Makefile
+++ b/sysdeps/unix/sysv/aix/Makefile
@@ -2,18 +2,16 @@
# This is a hack until the import/export stuff is worked out.
+postctor += /lib/syscalls.exp
-# XXX This is a hack until we have the possibility to generate out own crt0.
-static-start-installed-name = /usr/lib/crt0.o
-
ifeq ($(subdir),misc)
-sysdep_routines += dl-open dl-sym dl-close uitrunc
+sysdep_routines += dl-libc dl-open dl-sym dl-close uitrunc
endif
ifeq ($(subdir),login)
sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
pututxline utmpxname
-sysdep_headers += utmpx.h bits/utmpx.h
+#sysdep_headers += utmpx.h bits/utmpx.h
+#sysdep_headers += bits/utmp.h bits/utmpx.h
endif
# Don't compile the ctype glue code, since there is no old non-GNU C library.
diff --git a/sysdeps/unix/sysv/aix/bits/utmpx.h b/sysdeps/unix/sysv/aix/bits/utmpx.h
index 7a7bce2..f8bd665 100644
--- a/sysdeps/unix/sysv/aix/bits/utmpx.h
+++ b/sysdeps/unix/sysv/aix/bits/utmpx.h
@@ -65,3 +65,10 @@ struct utmpx
#ifdef __USE_GNU
# define ACCOUNTING 9 /* System accounting. */
#endif
+
+#define _HAVE_UT_TYPE 1
+#define _HAVE_UT_PID 1
+#define _HAVE_UT_ID 1
+#define _HAVE_UT_TV 1
+#define _HAVE_UT_HOST 1
+
diff --git a/sysdeps/unix/sysv/aix/dl-close.c b/sysdeps/unix/sysv/aix/dl-close.c
index a9a492a..50986d5 100644
--- a/sysdeps/unix/sysv/aix/dl-close.c
+++ b/sysdeps/unix/sysv/aix/dl-close.c
@@ -1,9 +1,46 @@
-/* XXX The implementation of dlopen should somehow use the __loadx system
- call but how? */
+/* Copyright (C) 2001 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 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 <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
#include <dlfcn.h>
+#include <dlldr.h>
-int
-__libc_dlclose (void *handle)
+extern int _dl_numso;
+extern DL_SODATA *_dl_sotable;
+
+void
+_dl_close (void *handle)
{
- return 0;
+ if ((int) handle < 0 || (int) handle >= _dl_numso || _dl_sotable == NULL)
+ {
+ errno = EINVAL;
+ return;
+ }
+
+ if (_dl_sotable[(int) handle].handle != 0)
+ __unload (_dl_sotable[(int) handle].handle);
+
+ _dl_sotable[(int) handle].index = 0;
+ _dl_sotable[(int) handle].dataorg = 0;
+ _dl_sotable[(int) handle].handle = 0;
+ _dl_sotable[(int) handle].type = 0;
}
+
diff --git a/sysdeps/unix/sysv/aix/dl-libc.c b/sysdeps/unix/sysv/aix/dl-libc.c
new file mode 100644
index 0000000..9a25fc8
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/dl-libc.c
@@ -0,0 +1 @@
+#include <elf/dl-libc.c>
diff --git a/sysdeps/unix/sysv/aix/dl-open.c b/sysdeps/unix/sysv/aix/dl-open.c
index 50fd712..0189ab4 100644
--- a/sysdeps/unix/sysv/aix/dl-open.c
+++ b/sysdeps/unix/sysv/aix/dl-open.c
@@ -1,9 +1,133 @@
-/* XXX The implementation of dlopen should somehow use the __loadx system
- call but how? */
+/* Copyright (C) 1999, 2000, 2001 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 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 <malloc.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
#include <dlfcn.h>
+#include <dlldr.h>
+
+#define NUM_SHARED_OBJECTS 32
+
+int _dl_numso = NUM_SHARED_OBJECTS;
+DL_SODATA *_dl_sotable = NULL;
void *
-__libc_dlopen (const char *file)
+_dl_open (const char *file, int mode, const void *caller)
{
- return (void *) 0;
+ DL_SODATA *new_so;
+ void *handle;
+ int entry;
+ int bsize = _dl_numso * sizeof (DL_INFO);
+ DL_INFO *dl_info = malloc (bsize);
+
+ if (dl_info == NULL)
+ return NULL;
+
+ /* 1st time thru initial shared object data table. */
+ if (_dl_sotable == NULL)
+ {
+ _dl_sotable = (DL_SODATA *) calloc (_dl_numso, sizeof (DL_SODATA));
+ if (_dl_sotable == NULL)
+ return NULL;
+
+ __loadx (DL_POSTLOADQ, dl_info, bsize, NULL);
+ while (!(dl_info[0].dlinfo_xflags & DL_INFO_OK)
+ || dl_info[0].dlinfo_arraylen == 0)
+ {
+ bsize *= 2;
+ dl_info = realloc (dl_info, bsize);
+ if (dl_info == NULL)
+ return NULL;
+
+ __loadx (DL_POSTLOADQ, dl_info, bsize, NULL);
+ }
+ }
+
+ /* Validate mode bits. */
+ if (!(mode & RTLD_NOW) && !(mode & RTLD_LAZY))
+ {
+ free (dl_info);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Load the module. */
+ handle = (void *) __loadx (DL_LOAD | DL_LOAD_RTL | DL_LOAD_LDX1,
+ dl_info, bsize, file, NULL);
+ if (handle == NULL)
+ {
+ free (dl_info);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Was dl_info buffer to small to get info. */
+ while (!(dl_info[0].dlinfo_xflags & DL_INFO_OK)
+ || dl_info[0].dlinfo_arraylen == 0)
+ {
+ bsize *= 2;
+ dl_info = realloc (dl_info, bsize);
+ if (new_dl_info == NULL)
+ {
+ (void) __unload ((void *) handle);
+ errno = ENOMEM;
+ return NULL;
+ }
+ __loadx (DL_POSTLOADQ | DL_LOAD_RTL, dl_info, bsize, handle);
+ }
+
+ /* Get an empty entry in the shared object table. */
+ for (entry = 0; entry < _dl_numso; ++entry)
+ if (_dl_sotable[entry].type == 0)
+ break;
+
+ /* See if the table needs to be increased. */
+ if (entry == _dl_numso)
+ {
+ new_so = (DL_SODATA *) realloc (_dl_sotable,
+ _dl_numso * 2 * sizeof (DL_SODATA));
+ if (new_so == NULL)
+ return NULL;
+
+ memset (new_so + _dl_numso, '\0', _dl_numso * sizeof (DL_SODATA));
+ _dl_numso *= 2;
+ _dl_sotable = new_so;
+ }
+
+ /* See if this is syscall (look for /unix in file). */
+ if (strcmp ("/unix", file) == 0)
+ {
+ _dl_sotable[entry].index = dl_info[1].dlinfo_index;
+ _dl_sotable[entry].dataorg = dl_info[1].dlinfo_dataorg;
+ _dl_sotable[entry].handle = handle;
+ _dl_sotable[entry].type = DL_UNIX_SYSCALL;
+ }
+ else
+ {
+ _dl_sotable[entry].index = dl_info[1].dlinfo_index;
+ _dl_sotable[entry].dataorg = dl_info[1].dlinfo_dataorg;
+ _dl_sotable[entry].handle = handle;
+ _dl_sotable[entry].type = DL_GETSYM;
+ }
+
+ free (dl_info);
+ return (void *) entry;
}
diff --git a/sysdeps/unix/sysv/aix/dl-sym.c b/sysdeps/unix/sysv/aix/dl-sym.c
index 7e10ba1..642c2e2 100644
--- a/sysdeps/unix/sysv/aix/dl-sym.c
+++ b/sysdeps/unix/sysv/aix/dl-sym.c
@@ -1,9 +1,58 @@
-/* XXX The implementation of dlopen should somehow use the __loadx system
- call but how? */
+/* Copyright (C) 2001 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 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 <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
#include <dlfcn.h>
+#include <dlldr.h>
+
+extern int _dl_numso;
+extern DL_SODATA *_dl_sotable;
void *
-__libc_dlsym (void *handle, const char *name)
+_dl_sym (void *handle, const char *symbol, void *who)
{
- return (void *) 0;
+ void *rt_function;
+
+ if ((int) handle < 0 || (int) handle >= _dl_numso || _dl_sotable == NULL)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ switch (_dl_sotable[(int) handle].type)
+ {
+ case DL_UNIX_SYSCALL:
+ rt_function = (void *) __loadx (DL_UNIX_SYSCALL, (void *) symbol);
+ break;
+
+ case DL_GETSYM:
+ rt_function = (void *) __loadx (DL_GETSYM, (void *) symbol,
+ _dl_sotable[(int) handle].index,
+ _dl_sotable[(int) handle].dataorg);
+ break;
+
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return rt_function;
}
diff --git a/sysdeps/unix/sysv/aix/dlldr.h b/sysdeps/unix/sysv/aix/dlldr.h
new file mode 100644
index 0000000..d729244
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/dlldr.h
@@ -0,0 +1,112 @@
+/* Copyright (C) 2001 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 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.
+*/
+
+
+/*
+
+ int __loadx(flag, module, arg1, arg2, arg3)
+
+ The __loadx() is a call to ld_loadutil() kernel function, which
+ does the real work. Note ld_loadutil() is not exported an cannot be
+ called directly from user space.
+
+ void *ld_loadutil() call is a utility function used for loader extensions
+ supporting run-time linking and dl*() functions.
+
+ void * - will return the modules entry point if it succeds of NULL
+ on failure.
+
+ int flag - the flag field performas a dual role: the top 8 bits specify
+ the work for __loadx() to perform, the bottom 8 bits are
+ used to pass flags to the work routines, all other bits are
+ reserved.
+
+*/
+
+#define DL_LOAD 0x1000000 /* __loadx(flag,buf, buf_len, filename, libr_path) */
+#define DL_POSTLOADQ 0x2000000 /* __loadx(flag,buf, buf_len, module_handle) */
+#define DL_EXECQ 0x3000000 /* __loadx(flag,buf, buf_len) */
+#define DL_EXITQ 0x4000000 /* __loadx(flag,buf, buf_len) */
+#define DL_PREUNLOADQ 0x5000000 /* __loadx(flag,buf, buf_len, module_handle) */
+#define DL_INIT 0x6000000 /* __loadx(flag,NULL) */
+#define DL_GETSYM 0x7000000 /* __loadx(flag,symbol, index, modules_data_origin) */
+#define DL_SETDEPEND 0x8000000 /* __loadx(flag,import_data_org, import_index, */
+ /* export_data_org, export_index) */
+#define DL_DELDEPEND 0x9000000 /* __loadx(flag,import_data_org, import_index, */
+ /* export_data_org, export_index) */
+#define DL_GLOBALSYM 0xA000000 /* __loadx(flag,symbol_name, ptr_to_rec_index, */
+ /* ptr_to_rec_data_org) */
+#define DL_UNIX_SYSCALL 0xB000000 /* __loadx(flag,syscall_symbol_name) */
+
+#define DL_FUNCTION_MASK 0xFF000000
+#define DL_SRCHDEPENDS 0x00100000
+#define DL_SRCHMODULE 0x00080000
+#define DL_SRCHLOADLIST 0x00040000
+#define DL_LOAD_LDX1 0x00040000
+#define DL_LOAD_RTL 0x00020000
+#define DL_HASHSTRING 0x00020000
+#define DL_INFO_OK 0x00010000
+#define DL_LOAD_DLINFO 0x00010000
+#define DL_UNLOADED 0x00020000
+
+typedef union _dl_info
+{
+ struct {
+ uint _xflags; /* flag bits in the array */
+ uint _size; /* size of this structure */
+ uint _arraylen; /* number of following elements */
+ } _dl_stat;
+ struct {
+ caddr_t _textorg; /* start of loaded program image */
+ caddr_t _dataorg; /* start of data instance */
+ uint _datasize; /* size of data instance */
+ ushort _index; /* index of this le in la_dynlist */
+ ushort _mflags; /* info about module from load() */
+ } _dl_array;
+} DL_INFO;
+
+#define dlinfo_xflags _dl_stat._xflags
+#define dlinfo_arraylen _dl_stat._arraylen
+#define dlinfo_size _dl_stat._size
+
+#define dlinfo_textorg _dl_array._textorg
+#define dlinfo_datasize _dl_array._datasize
+#define dlinfo_dataorg _dl_array._dataorg
+#define dlinfo_index _dl_array._index
+#define dlinfo_flags _dl_array._mflags
+
+#define DL_HAS_RTINIT 0x1 /* indicates the module __rtinit symbols */
+#define DL_IS_NEW 0x2 /* indicates that the module is newly loaded */
+
+struct _xArgs
+{
+ char *libpath;
+ DL_INFO *info;
+ uint infosize;
+};
+
+/* Shared Object DATA used for dl-open,dl-sym & dl-close support */
+typedef struct
+{
+ void *handle; /* handle for __loadx */
+ uint type; /* type of __loadx flag */
+ ushort index; /* dlinfo_index */
+ caddr_t dataorg; /* dlinfo_dataorg */
+} DL_SODATA;
+
diff --git a/sysdeps/unix/sysv/aix/getpeername.c b/sysdeps/unix/sysv/aix/getpeername.c
index d227e28..82a9941 100644
--- a/sysdeps/unix/sysv/aix/getpeername.c
+++ b/sysdeps/unix/sysv/aix/getpeername.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001 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
@@ -25,3 +25,4 @@ getpeername (int fd, __SOCKADDR_ARG addr, socklen_t *len)
{
return ngetpeername (fd, addr.__sockaddr__, len);
}
+weak_alias (getpeername,__getpeername)
diff --git a/sysdeps/unix/sysv/aix/gettimeofday.c b/sysdeps/unix/sysv/aix/gettimeofday.c
new file mode 100644
index 0000000..6b5bd48
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/gettimeofday.c
@@ -0,0 +1,94 @@
+/* Copyright (C) 1991, 92, 94, 95, 96, 97 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 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 <errno.h>
+#include <time.h>
+#include <sys/time.h>
+
+#ifndef HAVE_GNU_LD
+#define __daylight daylight
+#define __timezone timezone
+#define __tzname tzname
+#endif
+
+/* Assembler Routines to access the timer registers */
+asm("
+.rtc_upper: mfspr 3,4 # copy RTCU to return register
+ blr
+
+.rtc_lower: mfspr 3,5 # copy RTCL to return register
+ blr
+");
+
+/* Get the current time of day and timezone information,
+ putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
+ Returns 0 on success, -1 on errors. */
+int
+__gettimeofday (tv, tz)
+ struct timeval *tv;
+ struct timezone *tz;
+{
+ int ts, tl, tu;
+
+ if (tv == NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ ts = rtc_upper(); /* seconds */
+ tl = rtc_lower(); /* nanoseconds */
+ tu = rtc_upper(); /* Check for a carry from */
+ if (ts != tu) /* the lower reg to the upper */
+ tl = rtc_lower(); /* Recover from the race condition */
+
+ tv->tv_sec = (long int) (tu + (double)tl/1000000000);
+ tv->tv_usec = (long int) ((double)tl/1000);
+
+#if 0
+ if (tz != NULL)
+ {
+ const time_t timer = tv->tv_sec;
+ struct tm tm;
+ const struct tm *tmp;
+
+ const long int save_timezone = __timezone;
+ const long int save_daylight = __daylight;
+ char *save_tzname[2];
+ save_tzname[0] = __tzname[0];
+ save_tzname[1] = __tzname[1];
+
+ tmp = localtime_r (&timer, &tm);
+
+ tz->tz_minuteswest = __timezone / 60;
+ tz->tz_dsttime = __daylight;
+
+ __timezone = save_timezone;
+ __daylight = save_daylight;
+ __tzname[0] = save_tzname[0];
+ __tzname[1] = save_tzname[1];
+
+ if (tmp == NULL)
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+weak_alias (__gettimeofday, gettimeofday)
diff --git a/sysdeps/unix/sysv/aix/libc-start.c b/sysdeps/unix/sysv/aix/libc-start.c
index f7eb65e..2dfc025 100644
--- a/sysdeps/unix/sysv/aix/libc-start.c
+++ b/sysdeps/unix/sysv/aix/libc-start.c
@@ -1,20 +1 @@
-/* We don't need the usual code since we are using the AIX crt code. */
-
-/* This function is called in the AIX crt0. */
-void
-__mod_init (void)
-{
- /* XXX What has to be done? */
-}
-
-/* This variable is reference in the AIX crt0 code.
- XXX Since I don't know how it is used make it a pointer to a function. */
-void *__crt0v = __mod_init;
-
-
-/* XXX Another weird function from the C library. I have no idea what
- it does but it is needed by libgcc. */
-void
-_savef14 (void)
-{
-}
+/* stub libc-start.c */
diff --git a/sysdeps/unix/sysv/aix/powerpc/memset.c b/sysdeps/unix/sysv/aix/powerpc/memset.c
new file mode 100644
index 0000000..ef04283
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/powerpc/memset.c
@@ -0,0 +1,21 @@
+/* Copyright (C) 2001 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 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. */
+
+
+/* Until the cache line issues are resolved use the generic implementation. */
+#include <sysdeps/generic/memset.c>
diff --git a/sysdeps/unix/sysv/aix/start.c b/sysdeps/unix/sysv/aix/start.c
new file mode 100644
index 0000000..d854a55
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/start.c
@@ -0,0 +1,290 @@
+/* Copyright (C) 1991, 93, 1995-1998, 2000 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 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.
+*/
+
+
+/* Old compatibility names for C types. */
+typedef unsigned char uchar; /* sb in libc/posix/types.h */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <xcoff.h>
+#include <rtinit.h>
+#include <dlldr.h>
+#include <bits/libc-lock.h>
+
+/* The first piece of initialized data. */
+int __data_start = 0;
+
+extern int errno;
+
+/* extern __pthread_init; */
+
+typedef void (*FPV)(void);
+
+typedef struct crt0_info
+{
+ int *p_argc;
+ FPV threads_init;
+} INFO;
+
+
+INFO crt0_info;
+int argc;
+char **argv;
+char **__environ;
+int module_count;
+caddr_t text_origin;
+caddr_t data_origin;
+
+asm("
+ .toc
+LL..0: .tc argc[TC],argc
+LL..1: .tc argv[TC],argv
+LL..2: .tc __environ[TC],__environ
+LL..3: .tc module_count[TC],module_count
+LL..4: .tc text_origin[TC],text_origin
+LL..5: .tc data_origin[TC],data_origin
+");
+
+int main (int argc,char **argv,char **__environ);
+int modinit(int argc,INFO *crt0_info, int module_count,
+ caddr_t text_origin, caddr_t data_origin);
+
+void mod_init1(void *handler,__RTINIT *rti);
+
+__RTINIT *find_rtinit(caddr_t text_origin,caddr_t data_origin, int module_count);
+
+extern int *__loadx();
+
+void __start(void)
+{
+#ifdef __64BIT__
+asm("
+ ld 17,LL..0(2) # argc
+ std 14,0(17) # copy reg14 to argc
+ ld 17,LL..1(2) # argv
+ std 15,0(17) # copy reg15 to argv
+ ld 17,LL..2(2) # envp
+ std 16,0(17) # copy reg16 to envp
+ ld 17,LL..3(2) # module_count
+ std 30,0(17) # copy reg30 to module_count
+ ld 17,LL..4(2) # text_origin
+ std 29,0(17) # copy reg29 to text_origin
+ ld 17,LL..5(2) # data_origin
+ std 28,0(17) # copy reg28 to data_origin
+");
+#else
+asm("
+ lwz 17,LL..0(2) # argc
+ stw 3,0(17) # copy reg3 to argc
+ lwz 17,LL..1(2) # argv
+ stw 4,0(17) # copy reg4 to argv
+ lwz 17,LL..2(2) # envp
+ stw 5,0(17) # copy reg5 to envp
+ lwz 17,LL..3(2) # module_count
+ stw 30,0(17) # copy reg30 to module_count
+ lwz 17,LL..4(2) # text_origin
+ stw 29,0(17) # copy reg29 to text_origin
+ lwz 17,LL..5(2) # data_origin
+ stw 28,0(17) # copy reg28 to data_origin
+");
+#endif
+ crt0_info.p_argc = (int*)&argc;
+
+/* crt0_info.threads_init = (FPV) &__pthread_init; */
+
+ /*
+ * Do run-time linking, if enabled and call the init()
+ * for all loaded modules.
+ */
+ argc = modinit(argc,&crt0_info,module_count,text_origin,data_origin);
+
+ errno=0;
+ /*
+ * Call the user program.
+ */
+ exit (main (argc, argv, __environ));
+}
+
+/*
+ * The modinit() function performs run-time linking,
+ * if enabled, and calling the init() function for
+ * all loaded modules.
+ *
+ * int modinit(argc,crt0_info,module_count,text,data)
+ *
+ * argc - current value of argc.
+ * info - crt0 information passed
+ * module_count - number of modules loaded.
+ * text - Beginning of text address
+ * data - Beginning of data address
+ */
+
+#define DL_BUFFER_SIZE 1000
+
+int modinit(int argc,INFO *crt0_info, int module_count,
+ caddr_t text_origin, caddr_t data_origin)
+{
+ int *handler = 0;
+ __RTINIT *rtinit_info = 0;
+ int flag;
+ DL_INFO dl_buffer[DL_BUFFER_SIZE];
+ DL_INFO *dl_info = dl_buffer;
+ int i;
+ FPV p;
+ __libc_lock_define_initialized(static,modinit_lock);
+
+ /*
+ * try to find __rtinit symbols
+ */
+ rtinit_info = find_rtinit(text_origin,data_origin,module_count);
+
+ flag = DL_EXECQ;
+ if (rtinit_info && rtinit_info->rtl) flag |= DL_LOAD_RTL;
+
+ /*
+ * get a list of modules that have __rtinit
+ */
+ if (__loadx(flag, dl_info, sizeof(dl_buffer))) exit(0x90);
+
+ if (( dl_info[0].dlinfo_xflags & DL_INFO_OK))
+ {
+ rtinit_info = find_rtinit(dl_info[1].dlinfo_textorg,
+ dl_info[1].dlinfo_dataorg,
+ module_count);
+ if ((rtinit_info != NULL) & (rtinit_info->rtl != NULL))
+ {
+ if((*rtinit_info->rtl)(dl_info,0)) exit(0x90);
+ }
+ }
+
+ /*
+ * initialize threads in case any init
+ * functions need thread functions
+ */
+ if (crt0_info->threads_init)
+ (*crt0_info->threads_init)();
+
+ p = (FPV) __loadx(DL_GLOBALSYM | DL_SRCHLOADLIST,"pthread_init");
+ if (p)
+ (*p)();
+
+ __libc_lock_lock(modinit_lock);
+
+ /*
+ * initialization each module loaded that has __rtinit.
+ */
+ if (( dl_info[0].dlinfo_xflags & DL_INFO_OK))
+ {
+ for (i=1; i < dl_info[0].dlinfo_arraylen + 1; i++)
+ {
+ if (dl_info[i].dlinfo_flags & DL_HAS_RTINIT)
+ {
+ rtinit_info = find_rtinit(dl_info[i].dlinfo_textorg,
+ dl_info[i].dlinfo_dataorg,
+ module_count);
+ if (rtinit_info)
+ {
+ mod_init1(handler,rtinit_info);
+ }
+ }
+ }
+ }
+
+ __libc_lock_unlock(modinit_lock);
+ /*
+ * reload argc if needed.
+ */
+ return((int) (*crt0_info->p_argc));
+}
+
+/*
+ * The mod_init1 calls every initialization function
+ * for a given module.
+ *
+ * void mod_init1(handler, rti)
+ *
+ * void *handler - if NULL init funtions for modules loaded at exec time
+ * are being executed. Otherwise, the handler points to the
+ * module loaded.
+ *
+ * __RTINIT *rti - pointer to __rtinit data structure (with rti->init_offset
+ * not equal to zero)
+ */
+
+void mod_init1(void *handler,__RTINIT *rtl)
+{
+ __RTINIT_DESCRIPTOR *descriptor;
+
+ descriptor =(__RTINIT_DESCRIPTOR *) ((caddr_t)&rtl->rtl + rtl->init_offset);
+ while (descriptor->f)
+ {
+ if (!(descriptor->flags & _RT_CALLED))
+ {
+ descriptor->flags |= _RT_CALLED;
+ ( descriptor->f )(handler,rtl,descriptor); /* execute init/fini */
+ }
+ descriptor = (__RTINIT_DESCRIPTOR *) ((caddr_t)descriptor +
+ rtl->__rtinit_descriptor_size);
+ }
+}
+
+
+/*
+ * Find __rtinit symbol
+ *
+ * __RTINIT *find_rtinit(caddr_t text_origin)
+ *
+ * caddr_t text_origin - Beginning of text area
+ * caddr_t data_origin - Beginning of data area
+ * int module_count - Number of modules loaded
+ * __RTINIT *rti - pointer to __rtinit data structure
+ */
+
+__RTINIT *find_rtinit(caddr_t text_origin, caddr_t data_origin, int module_count)
+{
+ struct xcoffhdr *xcoff_hdr;
+ SCNHDR *sec_hdr;
+ SCNHDR *ldr_sec_hdr;
+ SCNHDR *data_sec_hdr;
+ LDSYM *ldsym_hdr;
+ __RTINIT *rtl;
+
+ xcoff_hdr = (struct xcoffhdr *) text_origin;
+ sec_hdr = (SCNHDR *) ((caddr_t)&xcoff_hdr->aouthdr +
+ xcoff_hdr->filehdr.f_opthdr);
+ ldr_sec_hdr = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_snloader - 1));
+ ldsym_hdr = (LDSYM *) ((caddr_t)xcoff_hdr + ldr_sec_hdr->s_scnptr +
+ LDHDRSZ);
+
+ if ( module_count <= 0)
+ {
+ if ( !(ldr_sec_hdr->s_scnptr) ) return ((__RTINIT *) 0);
+
+ if ( memcmp(ldsym_hdr,RTINIT_NAME,sizeof(RTINIT_NAME)-1))
+ return ((__RTINIT *) 0);
+ }
+
+ data_sec_hdr = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_sndata - 1));
+ rtl = (__RTINIT *) (ldsym_hdr->l_value +
+ (data_origin - data_sec_hdr->s_vaddr));
+ return(rtl);
+}
+
diff --git a/sysdeps/unix/sysv/aix/utmpx.h b/sysdeps/unix/sysv/aix/utmpx.h
new file mode 100644
index 0000000..f7a7a3e
--- /dev/null
+++ b/sysdeps/unix/sysv/aix/utmpx.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 1997, 1998, 1999 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 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. */
+
+#ifndef _UTMPX_H
+#define _UTMPX_H 1
+
+#include <features.h>
+#include <sys/time.h>
+
+/* Required according to Unix98. */
+#ifndef __pid_t_defined
+typedef __pid_t pid_t;
+# define __pid_t_defined
+#endif
+
+/* Get system dependent values and data structures. */
+#include <bits/utmpx.h>
+
+#ifdef __USE_GNU
+/* Compatibility names for the strings of the canonical file names. */
+# define UTMPX_FILE _PATH_UTMPX
+# define UTMPX_FILENAME _PATH_UTMPX
+# define WTMPX_FILE _PATH_WTMPX
+# define WTMPX_FILENAME _PATH_WTMPX
+#endif
+
+/* For the getutmp{,x} functions we need the `struct utmp'. */
+#ifdef __USE_GNU
+struct utmp;
+#endif
+
+
+__BEGIN_DECLS
+
+/* Open user accounting database. */
+extern void setutxent (void) __THROW;
+
+/* Close user accounting database. */
+extern void endutxent (void) __THROW;
+
+/* Get the next entry from the user accounting database. */
+extern struct utmpx *getutxent (void) __THROW;
+
+/* Get the user accounting database entry corresponding to ID. */
+extern struct utmpx *getutxid (__const struct utmpx *__id) __THROW;
+
+/* Get the user accounting database entry corresponding to LINE. */
+extern struct utmpx *getutxline (__const struct utmpx *__line) __THROW;
+
+/* Write the entry UTMPX into the user accounting database. */
+extern struct utmpx *pututxline (__const struct utmpx *__utmpx) __THROW;
+
+
+#ifdef __USE_GNU
+/* Change name of the utmpx file to be examined. */
+extern int utmpxname (__const char *__file) __THROW;
+
+/* Append entry UTMP to the wtmpx-like file WTMPX_FILE. */
+extern void updwtmpx (__const char *__wtmpx_file,
+ __const struct utmpx *__utmpx) __THROW;
+
+
+/* Copy the information in UTMPX to UTMP. */
+extern void getutmp (__const struct utmpx *__utmpx,
+ struct utmp *__utmp) __THROW;
+
+/* Copy the information in UTMP to UTMPX. */
+extern void getutmpx (__const struct utmp *__utmp,
+ struct utmpx *__utmpx) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* utmpx.h */