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.
This commit is contained in:
Ulrich Drepper 1998-08-26 18:03:49 +00:00
parent 00a2f9aa41
commit 6075607b9a
8 changed files with 154 additions and 51 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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,

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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;
char buffer[sizeof(dumpform)];
char *bufferpos = buffer;
int i = 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)
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)