diff options
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | elf/dl-close.c | 8 | ||||
-rw-r--r-- | elf/dl-open.c | 4 | ||||
-rw-r--r-- | math/Makefile | 16 | ||||
-rw-r--r-- | sysdeps/generic/segfault.c | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/elf/libc-start.c | 23 | ||||
-rw-r--r-- | sysdeps/powerpc/elf/start.S | 11 | ||||
-rw-r--r-- | sysdeps/powerpc/register-dump.h | 109 |
8 files changed, 155 insertions, 52 deletions
@@ -1,3 +1,33 @@ +1998-08-26 17:48 Ulrich Drepper <drepper@cygnus.com> + + * elf/dl-close.c (_dl_close): Move map->l_nsearchlist value into local + variable so that map can be freed. + Reported by Philippe Troin <phil@fifi.org>. + + * elf/dl-open.c (dl_open_worker): Correct test for extending global + scope array. + Patch by Philippe Troin <phil@fifi.org>. + +1998-08-26 Geoff Keating <geoffk@ozemail.com.au> + + * sysdeps/powerpc/register-dump.h: Rewrite. Much nicer this way. + Don't call writev() with a 100-element vector. + * sysdeps/generic/segfault.c (catch_segfault): Skip top-level NULL + return address. + + * sysdeps/powerpc/elf/libc-start.c: Sync up with generic version. + In particular, set __libc_stack_end. + * sysdeps/powerpc/elf/start.S: Allow _init and _fini to be + undefined. Fix copyright notice. + +1998-08-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + * math/Makefile (gmp-objs): New variable. + ($(objpfx)atest-exp, $(objpfx)atest-sincos, $(objpfx)atest-exp2): + Depend on it. + (tests): Add atest-exp atest-sincos atest-exp2. + (tests-static): Remove atest-exp atest-sincos atest-exp2. + 1998-08-25 Ulrich Drepper <drepper@cygnus.com> * sysdeps/generic/dl-cache.c: Move static variable cache and cachesize @@ -5,7 +35,7 @@ (_dl_unload_cache): New function. * elf/Versions [libc GLIBC_2.1]: Add _dl_unload_cache. * elf/dl-open.c (_dl_open): Unload map file before freeing the lock. - * elf/rtld (dl_main): Unload map file before jumping to user code. + * elf/rtld.c (dl_main): Unload map file before jumping to user code. * sysdeps/unix/sysv/linux/alpha/bits/fcntl.h: Define O_DIRECT. Correct comment for O_LARGEFILE. diff --git a/elf/dl-close.c b/elf/dl-close.c index e1ca142a69..8e613eb3eb 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -38,6 +38,7 @@ internal_function _dl_close (struct link_map *map) { struct link_map **list; + unsigned nsearchlist; unsigned int i; if (map->l_opencount == 0) @@ -56,9 +57,10 @@ _dl_close (struct link_map *map) } list = map->l_searchlist; + nsearchlist = map->l_nsearchlist; /* Call all termination functions at once. */ - for (i = 0; i < map->l_nsearchlist; ++i) + for (i = 0; i < nsearchlist; ++i) { struct link_map *imap = list[i]; if (imap->l_opencount == 1 && imap->l_type == lt_loaded @@ -83,12 +85,12 @@ _dl_close (struct link_map *map) /* The search list contains a counted reference to each object it points to, the 0th elt being MAP itself. Decrement the reference counts on all the objects MAP depends on. */ - for (i = 0; i < map->l_nsearchlist; ++i) + for (i = 0; i < nsearchlist; ++i) --list[i]->l_opencount; /* Check each element of the search list to see if all references to it are gone. */ - for (i = 0; i < map->l_nsearchlist; ++i) + for (i = 0; i < nsearchlist; ++i) { struct link_map *imap = list[i]; if (imap->l_opencount == 0 && imap->l_type == lt_loaded) diff --git a/elf/dl-open.c b/elf/dl-open.c index 3670657379..fa36fcb32e 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -169,8 +169,8 @@ dl_open_worker (void *a) } else { - if (_dl_global_scope_end + 2 - == _dl_global_scope + _dl_global_scope_alloc) + if (_dl_global_scope_end + 3 + > _dl_global_scope + _dl_global_scope_alloc) { /* Must extend the list. */ struct link_map **new = realloc (_dl_global_scope, diff --git a/math/Makefile b/math/Makefile index 6930b206a7..ee39968b21 100644 --- a/math/Makefile +++ b/math/Makefile @@ -75,8 +75,8 @@ distribute += $(long-c-yes:=.c) # Rules for the test suite. tests = test-float test-double $(test-longdouble-$(long-double-fcts)) \ - test-ifloat test-idouble test-matherr test-fenv -tests-static = atest-exp atest-sincos atest-exp2 + test-ifloat test-idouble test-matherr test-fenv \ + atest-exp atest-sincos atest-exp2 # We do the `long double' tests only if this data type is available and # distinct from `double'. test-longdouble-yes = test-ldouble test-ildoubl @@ -148,6 +148,18 @@ else $(addprefix $(objpfx),$(tests)): $(objpfx)libm.a endif +ifeq ($(build-static),yes) +o = .o +else +o = .os +endif +gmp-objs = $(patsubst %,$(common-objpfx)stdlib/%$o,\ + add_n sub_n cmp addmul_1 mul_1 mul_n divmod_1 \ + lshift rshift) +$(objpfx)atest-exp: $(gmp-objs) +$(objpfx)atest-sincos: $(gmp-objs) +$(objpfx)atest-exp2: $(gmp-objs) + # Depend on libc.so so a DT_NEEDED is generated in the shared objects. # This ensures they will load libc.so for needed symbols if loaded by # a statically-linked program that hasn't already loaded it. diff --git a/sysdeps/generic/segfault.c b/sysdeps/generic/segfault.c index 090f91a657..0d4be93837 100644 --- a/sysdeps/generic/segfault.c +++ b/sysdeps/generic/segfault.c @@ -136,6 +136,10 @@ catch_segfault (int signal, SIGCONTEXT ctx) current = current->next; } + /* If the last return address was NULL, assume that it doesn't count. */ + if (arr[cnt-1] == NULL) + cnt--; + /* Now generate nicely formatted output. */ __backtrace_symbols_fd (arr, cnt, fd); diff --git a/sysdeps/powerpc/elf/libc-start.c b/sysdeps/powerpc/elf/libc-start.c index 535eab2a64..e90553a154 100644 --- a/sysdeps/powerpc/elf/libc-start.c +++ b/sysdeps/powerpc/elf/libc-start.c @@ -25,6 +25,7 @@ extern void __libc_init_first (int argc, char **argv, char **envp); extern int _dl_starting_up; weak_extern (_dl_starting_up) extern int __libc_multiple_libcs; +extern void *__libc_stack_end; struct startup_info { @@ -67,13 +68,17 @@ __libc_start_main (int argc, char **argv, char **envp, rtld_fini = NULL; } - /* Register the destructor of the dynamic linker if there is any. */ - if (rtld_fini != NULL) - atexit (rtld_fini); + /* Store something that has some relationship to the end of the + stack, for backtraces. This variable should be thread-specific. */ + __libc_stack_end = stack_on_entry + 4; /* Set the global _environ variable correctly. */ __environ = envp; + /* Register the destructor of the dynamic linker if there is any. */ + if (rtld_fini != NULL) + atexit (rtld_fini); + /* Call the initializer of the libc. */ #ifdef PIC if (_dl_debug_impcalls) @@ -81,15 +86,17 @@ __libc_start_main (int argc, char **argv, char **envp, #endif __libc_init_first (argc, argv, envp); - /* Call the initializer of the program. */ + /* Register the destructor of the program, if any. */ + if (stinfo->fini) + atexit (stinfo->fini); + + /* Call the initializer of the program, if any. */ #ifdef PIC if (_dl_debug_impcalls) _dl_debug_message (1, "\ninitialize program: ", argv[0], "\n\n", NULL); #endif - stinfo->init (argc, argv, __environ, auxvec); - - /* Register the destructor of the program. */ - atexit (stinfo->fini); + if (stinfo->init) + stinfo->init (argc, argv, __environ, auxvec); #ifdef PIC if (_dl_debug_impcalls) diff --git a/sysdeps/powerpc/elf/start.S b/sysdeps/powerpc/elf/start.S index 94cb423629..a52ac8b64d 100644 --- a/sysdeps/powerpc/elf/start.S +++ b/sysdeps/powerpc/elf/start.S @@ -7,6 +7,15 @@ published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + In addition to the permissions in the GNU Library General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The Library General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + 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 @@ -22,6 +31,8 @@ /* These are the various addresses we require. */ .section ".rodata" .align 2 + weak_extern(_init) + weak_extern(_fini) L(start_addresses): .long _SDA_BASE_ .long JUMPTARGET(main) diff --git a/sysdeps/powerpc/register-dump.h b/sysdeps/powerpc/register-dump.h index 428b6073b9..2e15c0bd71 100644 --- a/sysdeps/powerpc/register-dump.h +++ b/sysdeps/powerpc/register-dump.h @@ -1,7 +1,6 @@ /* Dump registers. Copyright (C) 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. 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 @@ -21,53 +20,91 @@ #include <sys/uio.h> #include <stdio-common/_itoa.h> -static const char *regnames[] = -{ - "\nr0 =", " sp =", " r2 =", " r3 =", " r4 =", " r5 =", - "\nr6 =", " r7 =", " r8 =", " r9 =", " r10=", " r11=", - "\nr12=", " r13=", " r14=", " r15=", " r16=", " r17=", - "\nr18=", " r19=", " r20=", " r21=", " r22=", " r23=", - "\nr24=", " r25=", " r26=", " r27=", " r28=", " r29=", - "\nr30=", " r31=", " nip=", " msr=", " r3*=", " ctr=", - "\nlr =", " xer=", " ccr=", " mq =", " trap=", - "\naddress of fault=", " dsisr=", -}; +/* This prints out the information in the following form: */ +static const char dumpform[] = +"Register dump:\n\ +r0 =0000000% sp =0000000% r2 =0000000% r3 =0000000% r4 =0000000% r5 =0000000% +r6 =0000000% r7 =0000000% r8 =0000000% r9 =0000000% r10=0000000% r11=0000000% +r12=0000000% r13=0000000% r14=0000000% r15=0000000% r16=0000000% r17=0000000% +r18=0000000% r19=0000000% r20=0000000% r21=0000000% r22=0000000% r23=0000000% +r24=0000000% r25=0000000% r26=0000000% r27=0000000% r28=0000000% r29=0000000% +r30=0000000% r31=0000000% sr0=0000000% msr=0000000% r3*=0000000% ctr=0000000% +lr =0000000% xer=0000000% ccr=0000000% sr1=0000000% trap=0000000% +address of fault=0000000% dsisr=0000000%\n"; +/* Most of the fields are self-explanatory. 'sr0' is the next + instruction to execute, from SRR0, which may have some relationship + with the instruction that caused the exception. 'r3*' is the value + that will be returned in register 3 when the current system call + returns. 'sr1' is SRR1, bits 16-31 of which are copied from the MSR: + + 16 - External interrupt enable + 17 - Privilege level (1=user, 0=supervisor) + 18 - FP available + 19 - Machine check enable (if clear, processor locks up on machine check) + 20 - FP exception mode bit 0 (FP exceptions recoverable) + 21 - Single-step trace enable + 22 - Branch trace enable + 23 - FP exception mode bit 1 + 25 - exception prefix (if set, exceptions are taken from 0xFFFnnnnn, + otherwise from 0x000nnnnn). + 26 - Instruction address translation enabled. + 27 - Data address translation enabled. + 30 - Exception is recoverable (otherwise, don't try to return). + 31 - Little-endian mode enable. + + 'Trap' is the address of the exception: + + 00200 - Machine check exception (memory parity error, for instance) + 00300 - Data access exception (memory not mapped, see dsisr for why) + 00400 - Instruction access exception (memory not mapped) + 00500 - External interrupt + 00600 - Alignment exception (see dsisr for more information) + 00700 - Program exception (illegal/trap instruction, FP exception) + 00800 - FP unavailable (should not be seen by user code) + 00900 - Decrementer exception (for instance, SIGALRM) + 00A00 - I/O controller interface exception + 00C00 - System call exception (for instance, kill(3)). + 00E00 - FP assist exception (optional FP instructions, etc.) + + 'address of fault' is the memory location that wasn't mapped + (from the DAR). 'dsisr' has the following bits under trap 00300: + 0 - direct-store error exception + 1 - no page table entry for page + 4 - memory access not permitted + 5 - trying to access I/O controller space or using lwarx/stwcx on + non-write-cached memory + 6 - access was store + 9 - data access breakpoint hit + 10 - segment table search failed to find translation (64-bit ppcs only) + 11 - I/O controller instruction not permitted + For trap 00400, the same bits are set in SRR1 instead. + For trap 00600, bits 12-31 of the DSISR set to allow emulation of + the instruction without actually having to read it from memory. +*/ static void register_dump (int fd, void **ctx) { - char buffer[(sizeof (regnames) / sizeof (regnames[0])) * 8]; - char *bufferpos = buffer + sizeof (buffer); - struct iovec iov[(sizeof (regnames) / sizeof (regnames[0])) * 2 + 1]; - int nr = 0; - -#define ADD_STRING(str) \ - iov[nr].iov_base = (char *) str; \ - iov[nr].iov_len = strlen (str); \ - ++nr -#define ADD_HEX(str, len) \ - do { \ - char *s = _itoa_word ((unsigned long int) x, bufferpos, 16, 0); \ - while (bufferpos - s < 8) \ - *--s = '0'; \ - iov[nr].iov_base = s; \ - iov[nr].iov_len = bufferpos - s; \ - bufferpos = s; \ - } while (0) + char buffer[sizeof(dumpform)]; + char *bufferpos = buffer; + int i = 0; + + memcpy(buffer, dumpform, sizeof(dumpform)); + + ctx += 8; /* FIXME!!!! Why is this necessary? Is it necessary? */ /* Generate the output. */ - ADD_STRING ("Register dump:\n\n"); - for (i = 0; i < sizeof (regnames) / sizeof (regnames[0]); i++) + while ((bufferpos = memchr (bufferpos, '%', sizeof(dumpform)))) { - ADD_STRING (regnames[i]); - ADD_HEX (ctx[i]); + *bufferpos++ = '0'; + _itoa_word ((unsigned long int)(ctx[i]), bufferpos, 16, 0); + i++; } /* Write the output. */ - writev (fd, iov, nr); + write (fd, buffer, sizeof(buffer)); } #define REGISTER_DUMP \ - ctx += 8; /* FIXME!!!! Why is this necessary? Is it necessary? */ \ register_dump (fd, ctx) |