diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-08-26 18:03:49 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-08-26 18:03:49 +0000 |
commit | 6075607b9abba5ae10b87a9913f2a26548021272 (patch) | |
tree | 7072999d05ec4068a5f71737f7a53c5660becb27 /sysdeps | |
parent | 00a2f9aa41a4f2a441c3b9787ca1a7701632de5f (diff) | |
download | glibc-6075607b9abba5ae10b87a9913f2a26548021272.zip glibc-6075607b9abba5ae10b87a9913f2a26548021272.tar.gz glibc-6075607b9abba5ae10b87a9913f2a26548021272.tar.bz2 |
Update.
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.
* elf/rtld.c (dl_main): Unload map file before jumping to user code.
Diffstat (limited to 'sysdeps')
-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 |
4 files changed, 103 insertions, 44 deletions
diff --git a/sysdeps/generic/segfault.c b/sysdeps/generic/segfault.c index 090f91a..0d4be93 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 535eab2..e90553a 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 94cb423..a52ac8b 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 428b607..2e15c0b 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) |