From 84aafa9199e43623f55800898f9364e839525cdf Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 8 Sep 2001 17:45:32 +0000 Subject: [PATCH] Update. 2001-09-07 Tom Rix * sysdeps/unix/sysv/aix/sysv_termio.h: New file. 2001-08-26 Tom Rix * sysdeps/unix/sysv/aix/Makefile (aix-syscalls.o): More linker command line options. * sysdeps/unix/sysv/aix/start.s: New file, rework of start.c * sysdeps/unix/sysv/aix/start.c: Removed. * sysdeps/unix/sysv/aix/start-libc.c: New file. * sysdeps/unix/sysv/aix/init-first.c: New file. * sysdeps/unix/sysv/aix/fcntl.c: Alias __libc_fcntl to __fcntl. 2001-09-08 Ben Collins * sysdeps/arm/dl-machine.h: Fix usage of new _dl_signal_error() format. * sysdeps/generic/dl-machine.h: Likewise. * sysdeps/hppa/dl-fptr.c: Likewise. * sysdeps/ia64/dl-fptr.c: Likewise. * sysdeps/mach/hurd/dl-sysdep.c: Likewise. * sysdeps/mips/dl-machine.h: Likewise. * sysdeps/mips/mips64/dl-machine.h: Likewise. * sysdeps/powerpc/dl-machine.c: Likewise. 2001-09-07 Ben Collins * sysdeps/sparc/sparc32/dl-machine.h: Fix typo. * sysdeps/hppa/dl-lookupcfg.h: Forward declare struct link_map. * elf/dl-lookup.c (add_dependency): Bump l_opencount of all dependencies if necessary. --- ChangeLog | 34 ++++ elf/dl-lookup.c | 11 +- elf/reldep2.c | 4 +- sysdeps/arm/dl-machine.h | 2 +- sysdeps/generic/dl-machine.h | 2 +- sysdeps/hppa/dl-fptr.c | 4 +- sysdeps/hppa/dl-lookupcfg.h | 3 + sysdeps/ia64/dl-fptr.c | 6 +- sysdeps/mach/hurd/dl-sysdep.c | 2 +- sysdeps/mips/dl-machine.h | 2 +- sysdeps/mips/mips64/dl-machine.h | 2 +- sysdeps/powerpc/dl-machine.c | 2 +- sysdeps/sparc/sparc32/dl-machine.h | 2 +- sysdeps/unix/sysv/aix/Makefile | 5 +- sysdeps/unix/sysv/aix/fcntl.c | 3 +- sysdeps/unix/sysv/aix/init-first.c | 107 ++++++++++ sysdeps/unix/sysv/aix/start-libc.c | 271 +++++++++++++++++++++++++ sysdeps/unix/sysv/aix/start.c | 294 ---------------------------- sysdeps/unix/sysv/aix/start.s | 109 +++++++++++ sysdeps/unix/sysv/aix/sysv_termio.h | 155 +++++++++++++++ 20 files changed, 706 insertions(+), 314 deletions(-) create mode 100644 sysdeps/unix/sysv/aix/init-first.c create mode 100644 sysdeps/unix/sysv/aix/start-libc.c delete mode 100644 sysdeps/unix/sysv/aix/start.c create mode 100644 sysdeps/unix/sysv/aix/start.s create mode 100644 sysdeps/unix/sysv/aix/sysv_termio.h diff --git a/ChangeLog b/ChangeLog index 81ba6caab6..afaa0d8da9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,39 @@ +2001-09-07 Tom Rix + + * sysdeps/unix/sysv/aix/sysv_termio.h: New file. + +2001-08-26 Tom Rix + + * sysdeps/unix/sysv/aix/Makefile (aix-syscalls.o): More linker + command line options. + * sysdeps/unix/sysv/aix/start.s: New file, rework of start.c + * sysdeps/unix/sysv/aix/start.c: Removed. + * sysdeps/unix/sysv/aix/start-libc.c: New file. + * sysdeps/unix/sysv/aix/init-first.c: New file. + * sysdeps/unix/sysv/aix/fcntl.c: Alias __libc_fcntl to __fcntl. + +2001-09-08 Ben Collins + + * sysdeps/arm/dl-machine.h: Fix usage of new _dl_signal_error() format. + * sysdeps/generic/dl-machine.h: Likewise. + * sysdeps/hppa/dl-fptr.c: Likewise. + * sysdeps/ia64/dl-fptr.c: Likewise. + * sysdeps/mach/hurd/dl-sysdep.c: Likewise. + * sysdeps/mips/dl-machine.h: Likewise. + * sysdeps/mips/mips64/dl-machine.h: Likewise. + * sysdeps/powerpc/dl-machine.c: Likewise. + +2001-09-07 Ben Collins + + * sysdeps/sparc/sparc32/dl-machine.h: Fix typo. + + * sysdeps/hppa/dl-lookupcfg.h: Forward declare struct link_map. + 2001-09-08 Ulrich Drepper + * elf/dl-lookup.c (add_dependency): Bump l_opencount of all + dependencies if necessary. + * elf/dl-close.c (_dl_close): If object has no r_list (i.e., wasn't loaded directly) determine length if l_initfini list by iterating over its elements. Minor optimizations. diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 26c839caa7..5fa50fc457 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -151,8 +151,15 @@ add_dependency (struct link_map *undef_map, struct link_map *map) if (__builtin_expect (act < undef_map->l_reldepsmax, 1)) undef_map->l_reldeps[undef_map->l_reldepsact++] = map; - /* And increment the counter in the referenced object. */ - ++map->l_opencount; + if (map->l_searchlist.r_list != NULL) + /* And increment the counter in the referenced object. */ + ++map->l_opencount; + else + /* We have to bump the counts for all dependencies since so far + this object was only a normal or transitive dependency. + Now it might be closed with _dl_close() directly. */ + for (list = map->l_initfini; *list != NULL; ++list) + ++(*list)->l_opencount; /* Display information if we are debugging. */ if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) diff --git a/elf/reldep2.c b/elf/reldep2.c index aadb0cbfdb..ba5ab222f9 100644 --- a/elf/reldep2.c +++ b/elf/reldep2.c @@ -53,8 +53,8 @@ main (void) exit (1); } - /* Now close the first object. If must still be around since we have - a implicit dependency. */ + /* Now close the first object. It must still be around since we have + an implicit dependency. */ if (dlclose (h1) != 0) { printf ("closing h1 failed: %s\n", dlerror ()); diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 2a4ce9fb01..6abac52c90 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -501,7 +501,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, topbits = newvalue & 0xfe000000; if (topbits != 0xfe000000 && topbits != 0x00000000) { - _dl_signal_error (0, map->l_name, + _dl_signal_error (0, map->l_name, NULL, "R_ARM_PC24 relocation out of range"); } } diff --git a/sysdeps/generic/dl-machine.h b/sysdeps/generic/dl-machine.h index 963c95d88d..8b4425cea4 100644 --- a/sysdeps/generic/dl-machine.h +++ b/sysdeps/generic/dl-machine.h @@ -95,7 +95,7 @@ elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM], int noplt)) { _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on " - ELF_MACHINE_NAME); + NULL, ELF_MACHINE_NAME); } diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c index 6cf8d37275..4f8cc8b5d1 100644 --- a/sysdeps/hppa/dl-fptr.c +++ b/sysdeps/hppa/dl-fptr.c @@ -101,7 +101,7 @@ __hppa_make_fptr (const struct link_map *sym_map, Elf32_Addr value, if (_dl_zerofd == -1) { __close (fd); - _dl_signal_error (errno, NULL, + _dl_signal_error (errno, NULL, NULL, "cannot open zero fill device"); } } @@ -110,7 +110,7 @@ __hppa_make_fptr (const struct link_map *sym_map, Elf32_Addr value, __fptr_next = __mmap (0, _dl_pagesize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, ANONFD, 0); if (__fptr_next == MAP_FAILED) - _dl_signal_error(errno, NULL, "cannot map page for fptr"); + _dl_signal_error(errno, NULL, NULL, "cannot map page for fptr"); __fptr_count = _dl_pagesize / sizeof (struct hppa_fptr); } f = __fptr_next++; diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h index d15732b56d..d76ea1221d 100644 --- a/sysdeps/hppa/dl-lookupcfg.h +++ b/sysdeps/hppa/dl-lookupcfg.h @@ -23,6 +23,9 @@ #define ELF_FUNCTION_PTR_IS_SPECIAL #define DL_UNMAP_IS_SPECIAL +/* Forward declaration. */ +struct link_map; + void *_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref); #define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref) diff --git a/sysdeps/ia64/dl-fptr.c b/sysdeps/ia64/dl-fptr.c index c31de86079..6916635281 100644 --- a/sysdeps/ia64/dl-fptr.c +++ b/sysdeps/ia64/dl-fptr.c @@ -109,7 +109,7 @@ new_fdesc_table (struct local *l) new_table = __mmap (0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (new_table == MAP_FAILED) - _dl_signal_error (errno, NULL, "cannot map pages for fdesc table"); + _dl_signal_error (errno, NULL, NULL, "cannot map pages for fdesc table"); new_table->len = (size - sizeof (*new_table)) / sizeof (struct ia64_fdesc); fdesc = &new_table->fdesc[0]; @@ -182,7 +182,7 @@ make_fptr_table (struct link_map *map) fptr_table = __mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (fptr_table == MAP_FAILED) - _dl_signal_error (errno, NULL, "cannot map pages for fptr table"); + _dl_signal_error (errno, NULL, NULL, "cannot map pages for fptr table"); map->l_mach.fptr_table_len = len; map->l_mach.fptr_table = fptr_table; @@ -203,7 +203,7 @@ __ia64_make_fptr (struct link_map *map, const Elf64_Sym *sym, Elf64_Addr ip) symidx = sym - symtab; if (symidx >= map->l_mach.fptr_table_len) - _dl_signal_error (0, NULL, + _dl_signal_error (0, NULL, NULL, "internal error: symidx out of range of fptr table"); if (!ftab[symidx]) diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 6442347890..a17e92aff3 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -615,7 +615,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, /* Return an empty array. Hurd has no hardware capabilities. */ result = (struct r_strlenpair *) malloc (sizeof (*result)); if (result == NULL) - _dl_signal_error (ENOMEM, NULL, "cannot create capability list"); + _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list"); result[0].str = (char *) result; /* Does not really matter. */ result[0].len = 0; diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index e066aad015..da9a5d3279 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -239,7 +239,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) } } - _dl_signal_error (0, NULL, "cannot find runtime link map"); + _dl_signal_error (0, NULL, NULL, "cannot find runtime link map"); return NULL; } diff --git a/sysdeps/mips/mips64/dl-machine.h b/sysdeps/mips/mips64/dl-machine.h index 34a81615bb..d51f1e3cb1 100644 --- a/sysdeps/mips/mips64/dl-machine.h +++ b/sysdeps/mips/mips64/dl-machine.h @@ -311,7 +311,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) } } - _dl_signal_error (0, NULL, "cannot find runtime link map"); + _dl_signal_error (0, NULL, NULL, "cannot find runtime link map"); return NULL; } diff --git a/sysdeps/powerpc/dl-machine.c b/sysdeps/powerpc/dl-machine.c index c9c4fe00d5..0e3164f70d 100644 --- a/sysdeps/powerpc/dl-machine.c +++ b/sysdeps/powerpc/dl-machine.c @@ -391,7 +391,7 @@ dl_reloc_overflow (struct link_map *map, t = stpcpy (t, "'"); } t = stpcpy (t, " out of range"); - _dl_signal_error (0, map->l_name, buffer); + _dl_signal_error (0, map->l_name, NULL, buffer); } void diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index a44ddbbd57..d98848b5dd 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -355,7 +355,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, weak_extern (_dl_rtld_map); #endif -#if !define RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0)) { # if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC diff --git a/sysdeps/unix/sysv/aix/Makefile b/sysdeps/unix/sysv/aix/Makefile index 3fcf4bb3e9..2da5311091 100644 --- a/sysdeps/unix/sysv/aix/Makefile +++ b/sysdeps/unix/sysv/aix/Makefile @@ -11,11 +11,11 @@ sysdep_routines += aix-syscalls $(objpfx)aix-syscalls.o : /lib/syscalls.exp echo "static int a;" > foo.c $(CC) -c foo.c - ld -bM:SRE -bnoentry -bI:/lib/syscalls.exp -bE:/lib/syscalls.exp foo.o -o $@ + ld -bM:SRE -bpT:0x00000000 -bpD:0x00000000 -bnoentry -bI:/lib/syscalls.exp -bE:/lib/syscalls.exp foo.o -o $@ rm foo.c foo.o -endif +endif ifeq ($(subdir),misc) sysdep_routines += dl-error dl-support dl-libc dl-open dl-sym \ @@ -39,4 +39,3 @@ inhibit-glue = yes ifeq ($(subdir),timezone) CPPFLAGS-zic.c = -Dunix endif - diff --git a/sysdeps/unix/sysv/aix/fcntl.c b/sysdeps/unix/sysv/aix/fcntl.c index 196bbf52cd..8c5ba154c2 100644 --- a/sysdeps/unix/sysv/aix/fcntl.c +++ b/sysdeps/unix/sysv/aix/fcntl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* 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 @@ -38,3 +38,4 @@ __fcntl (int fdes, int cmd, ...) return res; } strong_alias (__fcntl, fcntl) +strong_alias (__fcntl, __libc_fcntl) diff --git a/sysdeps/unix/sysv/aix/init-first.c b/sysdeps/unix/sysv/aix/init-first.c new file mode 100644 index 0000000000..2c8e0b1900 --- /dev/null +++ b/sysdeps/unix/sysv/aix/init-first.c @@ -0,0 +1,107 @@ +/* Initialization code run first thing by the XCOFF startup code. AIX version. + 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 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. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SHARED +# include +# include "dl-osinfo.h" +#endif + +extern void __libc_init (int, char **, char **); + +/* The function is called from assembly stubs the compiler can't see. */ +static void init (int, char **, char **) __attribute__ ((unused)); + +extern int _dl_starting_up; +weak_extern (_dl_starting_up) + +extern fpu_control_t _dl_fpu_control; +extern int _dl_fpu_control_set; + +/* Set nonzero if we have to be prepared for more then one libc being + used in the process. Safe assumption if initializer never runs. */ +int __libc_multiple_libcs = 1; + +/* Remember the command line argument and enviroment contents for + later calls of initializers for dynamic libraries. */ +int __libc_argc; +char **__libc_argv; + + +static void +init (int argc, char **argv, char **envp) +{ + extern void __getopt_clean_environment (char **); + /* The next variable is only here to work around a bug in gcc <= 2.7.2.2. + If the address would be taken inside the expression the optimizer + would try to be too smart and throws it away. Grrr. */ + + /* XXX disable dl for now + int *dummy_addr = &_dl_starting_up; + + __libc_multiple_libcs = dummy_addr && !_dl_starting_up; */ + + /* Save the command-line arguments. */ + __libc_argc = argc; + __libc_argv = argv; + __environ = envp; + +#ifndef SHARED + __libc_init_secure (); +#endif + + __libc_init (argc, argv, envp); + + /* This is a hack to make the special getopt in GNU libc working. */ + __getopt_clean_environment (envp); + +#ifdef SHARED + __libc_global_ctors (); +#endif +} + +#ifdef SHARED + +strong_alias (init, _init); + +extern void __libc_init_first (void); + +void +__libc_init_first (void) +{ +} + +#else +extern void __libc_init_first (int argc, char **argv, char **envp); + +void +__libc_init_first (int argc, char **argv, char **envp) +{ + init (argc, argv, envp); +} +#endif diff --git a/sysdeps/unix/sysv/aix/start-libc.c b/sysdeps/unix/sysv/aix/start-libc.c new file mode 100644 index 0000000000..e3582e3892 --- /dev/null +++ b/sysdeps/unix/sysv/aix/start-libc.c @@ -0,0 +1,271 @@ +/* Initialization code run first thing by the XCOFF startup code. AIX version. + 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 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. */ + +#include +#include +#include + +/* hack to use uchar's */ +typedef unsigned char uchar; +#include +#include +#include +#include + +extern void __libc_init_first (int argc, char **argv, char **envp); + +/* XXX disable for now +extern int _dl_starting_up; +weak_extern (_dl_starting_up) +extern int __libc_multiple_libcs; */ + +/* XXX normally defined in generic/dl-sydep.c, hack it into existance +extern void *__libc_stack_end; */ +void *__libc_stack_end; + +struct __libc_start_data_rec +{ + void *stack; + void *toc; + int argc; + char **argv; + char **envp; + char *data; + char *text; + unsigned int mcount; + unsigned int special; + int (*main) (int, char **, char **); + void (*init) (void); + void (*fini) (void); + void (*rtld_fini) (void); +}; + +extern struct __libc_start_data_rec __libc_start_data; +extern int errno; + +/* The first piece of initialized data. */ +int __data_start = 0; + +#ifndef HAVE_ELF +/* Since gcc/crtstuff.c won't define it unless the ELF format is used + we will need to define it here. */ +void *__dso_handle = NULL; +#endif + +/* AIX kernel function */ +extern int __loadx (int flag, void *module, void *arg1, void *arg2, + void *arg3); +/* Needed by setenv */ +char **__environ; + +/* Needed by dl-support.c */ +/* XXX stubbing out dl-support.c for now.. + size_t _dl_pagesize = 0; */ + +/* + Find __rtinit symbol + + __RTINIT *find_rtinit() + + __RTINIT *rti - pointer to __rtinit data structure + */ + +static __RTINIT * +find_rtinit (void) +{ + struct xcoffhdr *xcoff_hdr; + SCNHDR *sec_hdr; + SCNHDR *ldr_sec_hdr; + SCNHDR *data_sec_hdr; + LDSYM *ldsym_hdr; + __RTINIT *rtl; + + xcoff_hdr = (struct xcoffhdr *) __libc_start_data.text; + 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 ( __libc_start_data.mcount <= 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 + + (__libc_start_data.data - data_sec_hdr->s_vaddr)); + return rtl; +} + +/* + 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) + */ + +static void +mod_init1 (void *handler,__RTINIT *rtl) +{ + __RTINIT_DESCRIPTOR *descriptor; + + descriptor = (__RTINIT_DESCRIPTOR *) ((caddr_t) &rtl->rtl + + rtl->init_offset); + while (descriptor->f != NULL) + { + 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); + } +} + +/* The modinit() function performs run-time linking, if enabled, and calling + the init() function for all loaded modules. */ + +#define DL_BUFFER_SIZE 1000 + +static int +modinit (void) +{ + int *handler = 0; + __RTINIT *rtinit_info = 0; + int flag; + DL_INFO dl_buffer[DL_BUFFER_SIZE]; + DL_INFO *dl_info = dl_buffer; + int i; + + /* Find __rtinit symbols */ + rtinit_info = find_rtinit (); + + 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, (void *) sizeof (dl_buffer), NULL, NULL)) + exit (0x90); + + if (dl_info[0].dlinfo_xflags & DL_INFO_OK) + { + rtinit_info = find_rtinit (); + if ((rtinit_info != NULL) & (rtinit_info->rtl != NULL)) + { + if ((*rtinit_info->rtl) (dl_info, 0)) + exit (0x90); + } + } + + /* 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_rtini t(); + if (rtinit_info) + mod_init1 (handler, rtinit_info); + } + } + + return 0; +} + + +void +__libc_start_init (void) +{ + /* Do run-time linking, if enabled and call the init() + for all loaded modules. */ + if (__libc_start_data.mcount != __libc_start_data.special) + modinit (); +} + +/* For now these are just stubs. */ +void +__libc_start_fini (void) +{ +} + +void +__libc_start_rtld_fini (void) +{ +} + + +int +__libc_start_main (void) +{ + /* Store the lowest stack address. */ + __libc_stack_end = __libc_start_data.stack; + + /* Used by setenv */ + __environ = __libc_start_data.envp; + +#ifndef SHARED + /* Clear errno. */ + errno = 0; + + /* Some security at this point. Prevent starting a SUID binary where + the standard file descriptors are not opened. We have to do this + only for statically linked applications since otherwise the dynamic + loader did the work already. */ + if (__builtin_expect (__libc_enable_secure, 0)) + __libc_check_standard_fds (); + +#endif + + /* Register the destructor of the dynamic linker if there is any. */ + if (__builtin_expect (__libc_start_data.rtld_fini != NULL, 1)) + __cxa_atexit ((void (*) (void *)) __libc_start_data.rtld_fini, NULL, NULL); + + /* Call the initializer of the libc. This is only needed here if we + are compiling for the static library in which case we haven't + run the constructors in `_dl_start_user'. */ +#ifndef SHARED + __libc_init_first (__libc_start_data.argc, __libc_start_data.argv, + __libc_start_data.envp); +#endif + + /* Register the destructor of the program, if any. */ + if (__libc_start_data.fini) + __cxa_atexit ((void (*) (void *)) __libc_start_data.fini, NULL, NULL); + + /* Call the initializer of the program, if any. */ + if (__libc_start_data.init) + (*__libc_start_data.init) (); + + exit ((*__libc_start_data.main) (__libc_start_data.argc, + __libc_start_data.argv, + __libc_start_data.envp)); +} diff --git a/sysdeps/unix/sysv/aix/start.c b/sysdeps/unix/sysv/aix/start.c deleted file mode 100644 index fd4d695eaa..0000000000 --- a/sysdeps/unix/sysv/aix/start.c +++ /dev/null @@ -1,294 +0,0 @@ -/* Copyright (C) 1991, 93, 1995-1998, 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 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. */ - - -/* Old compatibility names for C types. */ -typedef unsigned char uchar; /* sb in libc/posix/types.h */ - -#include -#include -#include -#include -#include -#include -#include - -/* The first piece of initialized data. */ -int __data_start = 0; - -#ifndef HAVE_ELF -/* Since gcc/crtstuff.c won't define it unless the ELF format is used - we will need to define it here. */ -void *__dso_handle = NULL; -#endif - -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/start.s b/sysdeps/unix/sysv/aix/start.s new file mode 100644 index 0000000000..bf17b8ce5c --- /dev/null +++ b/sysdeps/unix/sysv/aix/start.s @@ -0,0 +1,109 @@ +/* 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 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. */ + + .file "start.s" + .toc +T.lsd: .tc __libc_start_data[tc], __libc_start_data[rw] +T.main: .tc main[tc], main[rw] +T.init: .tc __libc_start_init[tc], __libc_start_init[rw] +T.fini: .tc __libc_start_fini[tc], __libc_start_init[rw] +T.rtld_fini : .tc __libc_start_rtld_fini[tc], __libc_start_rtld_fini[rw] + + .globl __start + .globl .__start + .globl __libc_start_data + + .extern .__libc_start_main + .extern .main + .extern main + .extern __libc_start_init + .extern __libc_start_fini + .extern __libc_start_rtld_fini + +/* Text */ + + .csect __start[ds] +__start: + .long .__start, TOC[tc0], 0 + + .csect .text[pr] +.__start: + +/* No prologue needed, __start does not have to follow the ABI. + + Input from kernel/loader + r1 : stack + r2 : TOC + r3 : argc + r4 : argv + r5 : envp + r28 : data origin + r29 : text origin + r30 : module count + r31 : default processing flag + + If r31 == r30, no special processing is needed, ie r28, r29 & r30 + are not used + + Save input in __libc_start_data */ + l 16, T.lsd(2) + st 1, 0(16) /* stack */ + st 2, 4(16) /* toc */ + st 3, 8(16) /* argc */ + st 4, 12(16) /* argv */ + st 5, 16(16) /* envp */ + st 28, 20(16) /* data origin */ + st 29, 24(16) /* text origin */ + st 30, 28(16) /* module count */ + st 31, 32(16) /* special */ + +/* Call __libc_start_main() */ + + bl .__libc_start_main + nop + +/* No epilog needed, __start does not have to follow the ABI */ + +/* Trace back */ +TB.__start: + .long 0x0 + .long 0xc2040 + .long 0x0 + .long TB.__start - .__start + .short 7 + .byte "__start" + .byte 0,0,0 + +/* Data + __libc_start_data + Space to keep libc initialization information */ + + .csect __libc_start_data[rw] +__libc_start_data: +/* For kernel/loader input args */ + .space 36 + +/* Externs */ + .long main +init: + .long __libc_start_init +fini: + .long __libc_start_fini +rtld_fini: + .long __libc_start_rtld_fini + .space 0x1000 + (4 + rtld_fini - __libc_start_data) diff --git a/sysdeps/unix/sysv/aix/sysv_termio.h b/sysdeps/unix/sysv/aix/sysv_termio.h new file mode 100644 index 0000000000..f314c0e16f --- /dev/null +++ b/sysdeps/unix/sysv/aix/sysv_termio.h @@ -0,0 +1,155 @@ +/* Copyright (C) 1992, 1997, 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 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. */ + +/* In various parts of this file we define the System V values for + things as _SYSV_. Those are the values that System V + uses for termio, and also (SVR4) termios. Not necessarily the + same as the GNU termios that the library user sees. */ + +/* Number of elements of c_cc. termio only. */ +#define _SYSV_NCC 8 + +#define _SYSV_VINTR 0 +#define _SYSV_VQUIT 1 +#define _SYSV_VERASE 2 +#define _SYSV_VKILL 3 +#define _SYSV_VEOF 4 +/* This field means VEOF if ICANON, VMIN if not. */ +#define _SYSV_VMIN 4 +#define _SYSV_VEOL 5 +/* This field means VEOL if ICANON, VTIME if not. */ +#define _SYSV_VTIME 5 +#define _SYSV_VEOL2 6 + +/* Flags in c_iflag. */ +#define _SYSV_IGNBRK 1 +#define _SYSV_BRKINT 2 +#define _SYSV_IGNPAR 4 +#define _SYSV_PARMRK 8 +#define _SYSV_INPCK 0x10 +#define _SYSV_ISTRIP 0x20 +#define _SYSV_INLCR 0x40 +#define _SYSV_IGNCR 0x80 +#define _SYSV_ICRNL 0x100 +#define _SYSV_IUCLC 0x200 +#define _SYSV_IXON 0x400 +#define _SYSV_IXANY 0x800 +#define _SYSV_IXOFF 0x1000 +#define _SYSV_IMAXBEL 0x2000 + +/* Flags in c_cflag. */ +#define _SYSV_CBAUD 0xf +#define _SYSV_CIBAUD 0xf0000 /* termios only. */ +#define _SYSV_IBSHIFT 16 +/* Values for CBAUD and CIBAUD. */ +#define _SYSV_B0 0 +#define _SYSV_B50 1 +#define _SYSV_B75 2 +#define _SYSV_B110 3 +#define _SYSV_B134 4 +#define _SYSV_B150 5 +#define _SYSV_B200 6 +#define _SYSV_B300 7 +#define _SYSV_B600 8 +#define _SYSV_B1200 9 +#define _SYSV_B1800 10 +#define _SYSV_B2400 11 +#define _SYSV_B4800 12 +#define _SYSV_B9600 13 +#define _SYSV_B19200 14 +#define _SYSV_B38400 15 + +#define _SYSV_CS5 0 +#define _SYSV_CS6 0x10 +#define _SYSV_CS7 0x20 +#define _SYSV_CS8 0x30 +#define _SYSV_CSIZE 0x30 +#define _SYSV_CSTOPB 0x40 +#define _SYSV_CREAD 0x80 +#define _SYSV_PARENB 0x100 +#define _SYSV_PARODD 0x200 +#define _SYSV_HUPCL 0x400 +#define _SYSV_CLOCAL 0x800 + +/* Flags in c_lflag. */ +#define _SYSV_ISIG 1 +#define _SYSV_ICANON 2 +#define _SYSV_ECHO 8 +#define _SYSV_ECHOE 0x10 +#define _SYSV_ECHOK 0x20 +#define _SYSV_ECHONL 0x40 +#define _SYSV_NOFLSH 0x80 +#define _SYSV_TOSTOP 0x100 +#define _SYSV_ECHOCTL 0x200 +#define _SYSV_ECHOPRT 0x400 +#define _SYSV_ECHOKE 0x800 +#define _SYSV_FLUSHO 0x2000 +#define _SYSV_PENDIN 0x4000 +#define _SYSV_IEXTEN 0x8000 + +/* Flags in c_oflag. */ +#define _SYSV_OPOST 1 +#define _SYSV_OLCUC 2 +#define _SYSV_ONLCR 4 +#define _SYSV_NLDLY 0x100 +#define _SYSV_NL0 0 +#define _SYSV_NL1 0x100 +#define _SYSV_CRDLY 0x600 +#define _SYSV_CR0 0 +#define _SYSV_CR1 0x200 +#define _SYSV_CR2 0x400 +#define _SYSV_CR3 0x600 +#define _SYSV_TABDLY 0x1800 +#define _SYSV_TAB0 0 +#define _SYSV_TAB1 0x0800 +#define _SYSV_TAB2 0x1000 +/* TAB3 is an obsolete name for XTABS. But we provide it since some + programs expect it to exist. */ +#define _SYSV_TAB3 0x1800 +#define _SYSV_XTABS 0x1800 +#define _SYSV_BSDLY 0x2000 +#define _SYSV_BS0 0 +#define _SYSV_BS1 0x2000 +#define _SYSV_VTDLY 0x4000 +#define _SYSV_VT0 0 +#define _SYSV_VT1 0x4000 +#define _SYSV_FFDLY 0x8000 +#define _SYSV_FF0 0 +#define _SYSV_FF1 0x8000 + +/* ioctl's. */ + +#define _TCGETA 0x5405 +#define _TCSETA 0x5406 +#define _TCSETAW 0x5407 +#define _TCSETAF 0x5408 +#define _TCSBRK 0x5409 +#define _TCXONC 0x540B +#define _TCFLSH 0x540C +#define _TIOCGPGRP 0x7414 +#define _TIOCSPGRP 0x7415 + +struct __sysv_termio + { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + char c_line; + unsigned char c_cc[_SYSV_NCC]; + };