Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update.
2003-09-17  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if
	libpthread is loaded.  Elide backwards compatibility code when not
	required.
  • Loading branch information
Ulrich Drepper committed Sep 17, 2003
1 parent 65af7e6 commit 06f6ca9
Show file tree
Hide file tree
Showing 24 changed files with 746 additions and 138 deletions.
12 changes: 9 additions & 3 deletions elf/Makefile
Expand Up @@ -71,7 +71,7 @@ distribute := rtld-Rules \
tst-tlsmod1.c tst-tlsmod2.c tst-tlsmod3.c tst-tlsmod4.c \
tst-tlsmod5.c tst-tlsmod6.c tst-tlsmod7.c tst-tlsmod8.c \
tst-tlsmod9.c tst-tlsmod10.c tst-tlsmod11.c \
tst-tlsmod12.c tst-tls10.h \
tst-tlsmod12.c tst-tls10.h tst-alignmod.c \
circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \
circlemod3.c circlemod3a.c nodlopenmod2.c \
tls-macros.h \
Expand Down Expand Up @@ -150,7 +150,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align
# reldep9
test-srcs = tst-pathopt
tests-vis-yes = vismain
Expand All @@ -177,7 +177,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
circlemod1 circlemod1a circlemod2 circlemod2a \
circlemod3 circlemod3a \
reldep8mod1 reldep8mod2 reldep8mod3 \
reldep9mod1 reldep9mod2 reldep9mod3
reldep9mod1 reldep9mod2 reldep9mod3 \
tst-alignmod
ifeq (yes,$(have-initfini-array))
modules-names += tst-array2dep
endif
Expand Down Expand Up @@ -648,6 +649,11 @@ $(objpfx)tst-tls13.out: $(objpfx)tst-tlsmod13a.so
$(objpfx)tst-tls14: $(objpfx)tst-tlsmod14a.so $(libdl)
$(objpfx)tst-tls14.out:$(objpfx)tst-tlsmod14b.so

CFLAGS-tst-align.c = $(stack-align-test-flags)
CFLAGS-tst-alignmod.c = $(stack-align-test-flags)
$(objpfx)tst-align: $(libdl)
$(objpfx)tst-align.out: $(objpfx)tst-alignmod.so

ifdef libdl
$(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
$(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
Expand Down
54 changes: 54 additions & 0 deletions elf/tst-align.c
@@ -0,0 +1,54 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

static int
do_test (void)
{
static const char modname[] = "tst-alignmod.so";
int result = 0;
void (*fp) (int *);
void *h;

h = dlopen (modname, RTLD_LAZY);
if (h == NULL)
{
printf ("cannot open '%s': %s\n", modname, dlerror ());
exit (1);
}

fp = dlsym (h, "in_dso");
if (fp == NULL)
{
printf ("cannot get symbol 'in_dso': %s\n", dlerror ());
exit (1);
}

fp (&result);

dlclose (h);

return result;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
53 changes: 53 additions & 0 deletions elf/tst-alignmod.c
@@ -0,0 +1,53 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
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 <stdio.h>
#include <tst-stack-align.h>

static int res, *resp;

static void __attribute__((constructor))
con (void)
{
res = TEST_STACK_ALIGN () ? -1 : 1;
}

void
in_dso (int *result)
{
if (!res)
{
puts ("constructor has not been run");
*result = 1;
}
else if (res != 1)
{
puts ("constructor has been run without sufficient alignment");
*result = 1;
}

resp = result;
}

static void __attribute__((destructor))
des (void)
{
if (TEST_STACK_ALIGN ())
*resp = 1;
}
78 changes: 0 additions & 78 deletions libio/memstream.c
Expand Up @@ -32,8 +32,6 @@ struct _IO_FILE_memstream

static int _IO_mem_sync __P ((_IO_FILE* fp));
static void _IO_mem_finish __P ((_IO_FILE* fp, int));
static int _IO_wmem_sync __P ((_IO_FILE* fp));
static void _IO_wmem_finish __P ((_IO_FILE* fp, int));


static struct _IO_jump_t _IO_mem_jumps =
Expand All @@ -60,30 +58,6 @@ static struct _IO_jump_t _IO_mem_jumps =
JUMP_INIT(imbue, _IO_default_imbue)
};

static struct _IO_jump_t _IO_wmem_jumps =
{
JUMP_INIT_DUMMY,
JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
JUMP_INIT (xsputn, (_IO_xsputn_t) INTUSE(_IO_wdefault_xsputn)),
JUMP_INIT (xsgetn, (_IO_xsgetn_t) INTUSE(_IO_wdefault_xsgetn)),
JUMP_INIT (seekoff, _IO_wstr_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_default_setbuf),
JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync),
JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)),
JUMP_INIT (read, _IO_default_read),
JUMP_INIT (write, _IO_default_write),
JUMP_INIT (seek, _IO_default_seek),
JUMP_INIT (close, _IO_default_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT(showmanyc, _IO_default_showmanyc),
JUMP_INIT(imbue, _IO_default_imbue)
};

/* Open a stream that writes into a malloc'd buffer that is expanded as
necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
and the number of characters written on fflush or fclose. */
Expand Down Expand Up @@ -172,55 +146,3 @@ _IO_mem_finish (fp, dummy)

INTUSE(_IO_default_finish) (fp, 0);
}


static int
_IO_wmem_sync (fp)
_IO_FILE* fp;
{
struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
int res;

res = _IO_default_sync (fp);
if (res < 0)
return res;

if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
{
_IO_wstr_overflow (fp, L'\0');
--fp->_wide_data->_IO_write_ptr;
}
else
*fp->_wide_data->_IO_write_ptr = '\0';

*mp->bufloc = (char *) fp->_wide_data->_IO_write_base;
*mp->sizeloc = (fp->_wide_data->_IO_write_ptr
- fp->_wide_data->_IO_write_base);

return 0;
}


static void
_IO_wmem_finish (fp, dummy)
_IO_FILE* fp;
int dummy;
{
struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;

*mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base,
(fp->_wide_data->_IO_write_ptr
- fp->_wide_data->_IO_write_base + 1)
* sizeof (wchar_t));
if (*mp->bufloc != NULL)
{
((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr
- fp->_wide_data->_IO_write_base] = '\0';
*mp->sizeloc = (fp->_wide_data->_IO_write_ptr
- fp->_wide_data->_IO_write_base);
}

fp->_wide_data->_IO_buf_base = NULL;

INTUSE(_IO_default_finish) (fp, 0);
}
6 changes: 6 additions & 0 deletions linuxthreads/ChangeLog
@@ -1,3 +1,9 @@
2003-09-17 Philip Blundell <philb@gnu.org>

* sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if
libpthread is loaded. Elide backwards compatibility code when not
required.

2003-09-17 Jakub Jelinek <jakub@redhat.com>

* descr.h (manager_thread): Rename to...
Expand Down
9 changes: 9 additions & 0 deletions linuxthreads/attr.c
Expand Up @@ -404,7 +404,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
# endif
#endif

#ifdef USE_TLS
if (attr->__stackaddr == NULL)
#else
if (descr == &__pthread_initial_thread)
#endif
{
/* Defined in ld.so. */
extern void *__libc_stack_end;
Expand Down Expand Up @@ -448,6 +452,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
attr->__stacksize = rl.rlim_cur;
attr->__stackaddr = (void *) to;

/* The limit might be too high. This is a bogus
situation but try to avoid making it worse. */
if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr)
attr->__stacksize = (size_t) attr->__stackaddr;

/* We succeed and no need to look further. */
ret = 0;
break;
Expand Down
39 changes: 31 additions & 8 deletions linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
Expand Up @@ -20,37 +20,60 @@
#include <sysdep-cancel.h>
#define _ERRNO_H 1
#include <bits/errno.h>
#include <kernel-features.h>

/* Clone the calling process, but without copying the whole address
pace.
/* Clone the calling process, but without copying the whole address space.
The calling process is suspended until the new process exits or is
replaced by a call to `execve'. Return -1 for errors, 0 to the new
rocess,
replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
and the process ID of the new process to the old process. */

PSEUDO_PROLOGUE

ENTRY (__vfork)

SINGLE_THREAD_P
bne HIDDEN_JUMPTARGET (__fork)
#ifdef __NR_vfork

#ifdef SHARED
ldr ip, 1f
ldr r0, 2f
3: add ip, pc, ip
ldr r0, [ip, r0]
#else
ldr r0, 1f
#endif
movs r0, r0
bne HIDDEN_JUMPTARGET (__fork)

swi __NR_vfork
cmn a1, #4096
RETINSTR(movcc, pc, lr)

#ifndef __ASSUME_VFORK_SYSCALL
/* Check if vfork syscall is known at all. */
ldr a2, =-ENOSYS
teq a1, a2
cmn a1, #ENOSYS
bne PLTJMP(C_SYMBOL_NAME(__syscall_error))
#endif

#endif

#ifndef __ASSUME_VFORK_SYSCALL
/* If we don't have vfork, fork is close enough. */
swi __NR_fork
cmn a1, #4096
RETINSTR(movcc, pc, lr)
#elif !defined __NR_vfork
# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
#endif
b PLTJMP(C_SYMBOL_NAME(__syscall_error))

#ifdef SHARED
1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8
2: .word __libc_pthread_functions(GOTOFF)
#else
.weak pthread_create
1: .word pthread_create
#endif

PSEUDO_END (__vfork)
libc_hidden_def (__vfork)

Expand Down
1 change: 1 addition & 0 deletions misc/Makefile
Expand Up @@ -89,6 +89,7 @@ CFLAGS-mkstemp64.c = -fexceptions
CFLAGS-getsysstats.c = -fexceptions
CFLAGS-getusershell.c = -fexceptions
CFLAGS-err.c = -fexceptions
CFLAGS-tst-tsearch.c = $(stack-align-test-flags)

include ../Rules

Expand Down

0 comments on commit 06f6ca9

Please sign in to comment.