aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/aix/start.c
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/unix/sysv/aix/start.c
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/unix/sysv/aix/start.c')
-rw-r--r--sysdeps/unix/sysv/aix/start.c290
1 files changed, 290 insertions, 0 deletions
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);
+}
+