mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 14:50:05 +00:00
Update.
2003-01-11 Jim Meyering <jim@meyering.net> * io/ftw.c [HAVE_CONFIG_H]: Include <config.h>. [HAVE_SYS_PARAM_H || _LIBC]: Guard inclusion of <sys/param.h>. Include <sys/stat.h>, not <include/sys/stat.h>, if !_LIBC. [!_LIBC] (__chdir, __closedir, __fchdir, __getcwd, __opendir): Define. [!_LIBC] (__readdir64, __tdestroy, __tfind, __tsearch): Define. [!_LIBC] (internal_function, dirent64, MAX): Define. (__set_errno): Define if not already defined. (open_dir_stream): When FTW_CHDIR is enabled, invoke opendir on the basename, not the entire file name. (process_entry): When FTW_CHDIR is enabled, invoke XSTAT or LXSTAT on the basename, not the entire file name. 2003-01-12 Ulrich Drepper <drepper@redhat.com> * string/tester.c (test_strcpy): Disable last added strcpy until it is fixed. 2003-01-11 Philip Blundell <philb@gnu.org> * sysdeps/unix/sysv/linux/arm/socket.S: Add cancellation support. 2003-01-11 Andreas Schwab <schwab@suse.de> * Makerules: Add vpath for %.dynsym and %.so so that the implicit rule chaining for check-abi works. 2003-01-11 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/unix/sysv/linux/sh/sysdep.h (SYSCALL_ERROR_HANDLER): Add non-PIC case. 2003-01-11 Jakub Jelinek <jakub@redhat.com> * elf/tls-macros.h [__ia64__] (__TLS_CALL_CLOBBERS): Define. [__ia64__] (TLS_LE, TLS_IE): Fix typos. Add ;; at start of asm if gp is used early. [__ia64__] (TLS_LD, TLS_GD): Likewise. Use __TLS_CALL_CLOBBERS. * elf/Makefile ($(objpfx)tst-tlsmod5.so, $(objpfx)tst-tlsmod6.so): Ensure libc.so in DT_NEEDED. * sysdeps/alpha/dl-machine.h (elf_machine_rela): Move CHECK_STATIC_TLS before l_tls_offset use. * sysdeps/i386/dl-machine.h (elf_machine_rel, elf_machine_rela): Likewise. * sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise. * sysdeps/generic/dl-tls.c (_dl_allocate_tls_storage) [TLS_DTV_AT_TP]: Allocate TLS_PRE_TCB_SIZE bytes below result. (_dl_deallocate_tls) [TLS_DTV_AT_TP]: Adjust before freeing. * sysdeps/generic/libc-tls.c (__libc_setup_tls): If TLS_INIT_TP_EXPENSIVE is not defined, allocate even if no PT_TLS segment has been found. If TLS_DTV_AT_TP, allocate TLS_PRE_TCB_SIZE bytes below result and add tcb_offset to memsz. * sysdeps/ia64/dl-tls.h (__tls_get_addr): New prototype. * sysdeps/ia64/dl-machine.h: Include tls.h. (elf_machine_type_class): Return ELF_RTYPE_CLASS_PLT for TLS relocs too. (elf_machine_rela): Assume if sym_map != NULL sym is non-NULL too. Handle R_IA64_DTPMOD*, R_IA64_DTPREL* and R_IA64_TPREL* relocations. * sysdeps/ia64/libc-tls.c: New file. 2003-01-10 Steven Munroe <sjmunroe@us.ibm.com> * sysdeps/powerpc/powerpc64/sysdep.h (PSEUDO_RET): Add branch hit. * sysdeps/unix/sysv/linux/powerpc/bits/stat.h (STAT_VER_LINUX): Fix type. Move definition out of #if. * sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S: Add cancellation support. * sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Remove ftruncate64, pread64, pwrite64, truncate64 entries. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h (INLINE_SYSCALL): New version that supports function call like syscalls. Add __builtin_expect. (LOADARGS_n): Add argument size safety checks. (INTERNAL_SYSCALL): New Macro. * sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c: New file. * sysdeps/unix/sysv/linux/powerpc/sys/procfs.h [__PPC_ELF_H]: Avoid redefinition of elf_fpreg_t and elf_fpregset_t. 2003-01-12 Ulrich Drepper <drepper@redhat.com> * elf/dl-close.c (_dl_close): Add several asserts. Correct and simplify test for unloading. If loader of a DSO is unloaded do not use its scope anymore. Fall back to own scope and adjust opencounts. Fix several comments. * elf/dl-deps.c (_dl_map_object_deps): Always allocate memory for the l_searchlist, not only for l_initfini. * elf/dl-lookup.c (add_dependencies): Avoid creating relocation dependencies if objects cannot be removed. Remove object with the definition as not unloadable if necessary. * elf/reldep6.c: Create relocation dependency before closing the first module. 2003-01-10 Guido Gnther <agx@sigxcpu.org> * elf/Makefile: Add rules to build and run reldep9 test. * elf/reldep9.c: New file. * elf/reldep9mod1.c: New file. * elf/reldep9mod2.c: New file. * elf/reldep9mod3.c: New file. 2003-01-09 Jakub Jelinek <jakub@redhat.com> * elf/Makefile: Add rules to build and run nodelete2 test. * elf/nodelete2.c: New file. * elf/nodel2mod1.c: New file. * elf/nodel2mod2.c: New file. * elf/nodel2mod3.c: New file. 2003-01-09 Jakub Jelinek <jakub@redhat.com>
This commit is contained in:
parent
26a676d0aa
commit
aff4519d38
118
ChangeLog
118
ChangeLog
@ -1,4 +1,104 @@
|
||||
2003-01-10 Guido Günther <agx@sigxcpu.org>
|
||||
2003-01-11 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* io/ftw.c [HAVE_CONFIG_H]: Include <config.h>.
|
||||
[HAVE_SYS_PARAM_H || _LIBC]: Guard inclusion of <sys/param.h>.
|
||||
Include <sys/stat.h>, not <include/sys/stat.h>, if !_LIBC.
|
||||
[!_LIBC] (__chdir, __closedir, __fchdir, __getcwd, __opendir): Define.
|
||||
[!_LIBC] (__readdir64, __tdestroy, __tfind, __tsearch): Define.
|
||||
[!_LIBC] (internal_function, dirent64, MAX): Define.
|
||||
(__set_errno): Define if not already defined.
|
||||
(open_dir_stream): When FTW_CHDIR is enabled, invoke opendir on
|
||||
the basename, not the entire file name.
|
||||
(process_entry): When FTW_CHDIR is enabled, invoke XSTAT or LXSTAT on
|
||||
the basename, not the entire file name.
|
||||
|
||||
2003-01-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* string/tester.c (test_strcpy): Disable last added strcpy until
|
||||
it is fixed.
|
||||
|
||||
2003-01-11 Philip Blundell <philb@gnu.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/socket.S: Add cancellation support.
|
||||
|
||||
2003-01-11 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* Makerules: Add vpath for %.dynsym and %.so so that the
|
||||
implicit rule chaining for check-abi works.
|
||||
|
||||
2003-01-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sh/sysdep.h (SYSCALL_ERROR_HANDLER):
|
||||
Add non-PIC case.
|
||||
|
||||
2003-01-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/tls-macros.h [__ia64__] (__TLS_CALL_CLOBBERS): Define.
|
||||
[__ia64__] (TLS_LE, TLS_IE): Fix typos. Add ;; at start of asm if
|
||||
gp is used early.
|
||||
[__ia64__] (TLS_LD, TLS_GD): Likewise. Use __TLS_CALL_CLOBBERS.
|
||||
* elf/Makefile ($(objpfx)tst-tlsmod5.so, $(objpfx)tst-tlsmod6.so):
|
||||
Ensure libc.so in DT_NEEDED.
|
||||
* sysdeps/alpha/dl-machine.h (elf_machine_rela): Move
|
||||
CHECK_STATIC_TLS before l_tls_offset use.
|
||||
* sysdeps/i386/dl-machine.h (elf_machine_rel, elf_machine_rela):
|
||||
Likewise.
|
||||
* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
|
||||
* sysdeps/generic/dl-tls.c (_dl_allocate_tls_storage) [TLS_DTV_AT_TP]:
|
||||
Allocate TLS_PRE_TCB_SIZE bytes below result.
|
||||
(_dl_deallocate_tls) [TLS_DTV_AT_TP]: Adjust before freeing.
|
||||
* sysdeps/generic/libc-tls.c (__libc_setup_tls): If
|
||||
TLS_INIT_TP_EXPENSIVE is not defined, allocate even if no PT_TLS
|
||||
segment has been found. If TLS_DTV_AT_TP, allocate TLS_PRE_TCB_SIZE
|
||||
bytes below result and add tcb_offset to memsz.
|
||||
* sysdeps/ia64/dl-tls.h (__tls_get_addr): New prototype.
|
||||
* sysdeps/ia64/dl-machine.h: Include tls.h.
|
||||
(elf_machine_type_class): Return ELF_RTYPE_CLASS_PLT for TLS relocs
|
||||
too.
|
||||
(elf_machine_rela): Assume if sym_map != NULL sym is non-NULL too.
|
||||
Handle R_IA64_DTPMOD*, R_IA64_DTPREL* and R_IA64_TPREL* relocations.
|
||||
* sysdeps/ia64/libc-tls.c: New file.
|
||||
|
||||
2003-01-10 Steven Munroe <sjmunroe@us.ibm.com>
|
||||
|
||||
* sysdeps/powerpc/powerpc64/sysdep.h (PSEUDO_RET): Add branch hit.
|
||||
* sysdeps/unix/sysv/linux/powerpc/bits/stat.h (STAT_VER_LINUX):
|
||||
Fix type. Move definition out of #if.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S: Add cancellation
|
||||
support.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/syscalls.list: Remove
|
||||
ftruncate64, pread64, pwrite64, truncate64 entries.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
|
||||
(INLINE_SYSCALL): New version that supports function call like
|
||||
syscalls. Add __builtin_expect.
|
||||
(LOADARGS_n): Add argument size safety checks.
|
||||
(INTERNAL_SYSCALL): New Macro.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c: New file.
|
||||
* sysdeps/unix/sysv/linux/powerpc/sys/procfs.h [__PPC_ELF_H]: Avoid
|
||||
redefinition of elf_fpreg_t and elf_fpregset_t.
|
||||
|
||||
2003-01-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/dl-close.c (_dl_close): Add several asserts. Correct and
|
||||
simplify test for unloading. If loader of a DSO is unloaded do not
|
||||
use its scope anymore. Fall back to own scope and adjust opencounts.
|
||||
Fix several comments.
|
||||
* elf/dl-deps.c (_dl_map_object_deps): Always allocate memory for
|
||||
the l_searchlist, not only for l_initfini.
|
||||
|
||||
* elf/dl-lookup.c (add_dependencies): Avoid creating relocation
|
||||
dependencies if objects cannot be removed. Remove object with the
|
||||
definition as not unloadable if necessary.
|
||||
|
||||
* elf/reldep6.c: Create relocation dependency before closing the first
|
||||
module.
|
||||
|
||||
2003-01-10 Guido Günther <agx@sigxcpu.org>
|
||||
|
||||
* sysdeps/unix/mips/fork.S: Add PSEUDO_END.
|
||||
* sysdeps/unix/mips/brk.S: Likewise.
|
||||
@ -18,6 +118,22 @@
|
||||
(__ASSUME_STAT64_SYSCALL, __ASSUME_FCNTL64)
|
||||
(__ASSUME_VFORK_SYSCALL): Define for m68k kernels >= 2.4.12.
|
||||
|
||||
2003-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/Makefile: Add rules to build and run reldep9 test.
|
||||
* elf/reldep9.c: New file.
|
||||
* elf/reldep9mod1.c: New file.
|
||||
* elf/reldep9mod2.c: New file.
|
||||
* elf/reldep9mod3.c: New file.
|
||||
|
||||
2003-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/Makefile: Add rules to build and run nodelete2 test.
|
||||
* elf/nodelete2.c: New file.
|
||||
* elf/nodel2mod1.c: New file.
|
||||
* elf/nodel2mod2.c: New file.
|
||||
* elf/nodel2mod3.c: New file.
|
||||
|
||||
2003-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* posix/test-vfork.c (noop): Add __attribute_noinline__.
|
||||
|
@ -1138,6 +1138,8 @@ ifeq ($(versioning),yes)
|
||||
mv -f $@T $@
|
||||
|
||||
vpath %.symlist $(objpfx) $(common-objpfx)
|
||||
vpath %.dynsym $(objpfx) $(common-objpfx)
|
||||
vpath %.so $(objpfx) $(common-objpfx)
|
||||
check-abi-%: $(..)scripts/extract-abilist.awk $(common-objpfx)config.make \
|
||||
%.abilist %.symlist
|
||||
LC_ALL=C \
|
||||
|
28
elf/Makefile
28
elf/Makefile
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1995-2002, 2003 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
|
||||
@ -73,7 +73,9 @@ distribute := rtld-Rules \
|
||||
circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \
|
||||
circlemod3.c circlemod3a.c nodlopenmod2.c \
|
||||
tls-macros.h \
|
||||
reldep8mod1.c reldep8mod2.c reldep8mod3.c
|
||||
reldep8mod1.c reldep8mod2.c reldep8mod3.c \
|
||||
nodel2mod1.c nodel2mod2.c nodel2mod3.c \
|
||||
reldep9mod1.c reldep9mod2.c reldep9mod3.c
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
@ -138,9 +140,10 @@ 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
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
tests-vis-yes = vismain
|
||||
tests-nodelete-yes = nodelete
|
||||
tests-nodelete-yes = nodelete nodelete2
|
||||
tests-nodlopen-yes = nodlopen nodlopen2
|
||||
endif
|
||||
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
@ -160,12 +163,14 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
tst-tlsmod5 tst-tlsmod6 \
|
||||
circlemod1 circlemod1a circlemod2 circlemod2a \
|
||||
circlemod3 circlemod3a \
|
||||
reldep8mod1 reldep8mod2 reldep8mod3
|
||||
reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||
reldep9mod1 reldep9mod2 reldep9mod3
|
||||
ifeq (yes,$(have-initfini-array))
|
||||
modules-names += tst-array2dep
|
||||
endif
|
||||
modules-vis-yes = vismod1 vismod2 vismod3
|
||||
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
|
||||
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 \
|
||||
nodel2mod1 nodel2mod2 nodel2mod3
|
||||
modules-nodlopen-yes = nodlopenmod nodlopenmod2
|
||||
extra-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
# We need this variable to be sure the test modules get the right CPPFLAGS.
|
||||
@ -363,7 +368,13 @@ $(objpfx)reldep6mod2.so: $(objpfx)reldep6mod1.so
|
||||
$(objpfx)reldep6mod3.so: $(objpfx)reldep6mod2.so
|
||||
$(objpfx)reldep6mod4.so: $(objpfx)reldep6mod1.so
|
||||
$(objpfx)tst-tlsmod3.so: $(objpfx)tst-tlsmod2.so
|
||||
# For tst-tls9-static, make sure the modules it dlopens have libc.so in DT_NEEDED
|
||||
$(objpfx)tst-tlsmod5.so: $(common-objpfx)libc.so
|
||||
$(objpfx)tst-tlsmod6.so: $(common-objpfx)libc.so
|
||||
$(objpfx)reldep8mod3.so: $(objpfx)reldep8mod1.so $(objpfx)reldep8mod2.so
|
||||
$(objpfx)nodel2mod3.so: $(objpfx)nodel2mod1.so $(objpfx)nodel2mod2.so
|
||||
$(objpfx)reldep9mod2.so: $(objpfx)reldep9mod1.so
|
||||
$(objpfx)reldep9mod3.so: $(objpfx)reldep9mod1.so $(objpfx)reldep9mod2.so
|
||||
|
||||
LDFLAGS-tst-tlsmod5.so = -nostdlib
|
||||
LDFLAGS-tst-tlsmod6.so = -nostdlib
|
||||
@ -531,6 +542,13 @@ $(objpfx)reldep7.out: $(objpfx)reldep7mod1.so $(objpfx)reldep7mod2.so
|
||||
$(objpfx)reldep8: $(libdl)
|
||||
$(objpfx)reldep8.out: $(objpfx)reldep8mod3.so
|
||||
|
||||
LDFLAGS-nodel2mod2.so = -Wl,--enable-new-dtags,-z,nodelete
|
||||
$(objpfx)nodelete2: $(libdl)
|
||||
$(objpfx)nodelete2.out: $(objpfx)nodel2mod3.so
|
||||
|
||||
$(objpfx)reldep9: $(libdl)
|
||||
$(objpfx)reldep9.out: $(objpfx)reldep9mod3.so
|
||||
|
||||
$(objpfx)tst-tls3: $(objpfx)tst-tlsmod1.so
|
||||
|
||||
$(objpfx)tst-tls4: $(libdl)
|
||||
|
125
elf/dl-close.c
125
elf/dl-close.c
@ -1,5 +1,5 @@
|
||||
/* Close a shared object opened by `_dl_open'.
|
||||
Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2002, 2003 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
|
||||
@ -138,7 +138,7 @@ _dl_close (void *_map)
|
||||
_dl_debug_printf ("\nclosing file=%s; opencount == %u\n",
|
||||
map->l_name, map->l_opencount);
|
||||
|
||||
/* One decrement the object itself, not the dependencies. */
|
||||
/* Decrement the object's reference counter, not the dependencies'. */
|
||||
--map->l_opencount;
|
||||
|
||||
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||
@ -165,7 +165,7 @@ _dl_close (void *_map)
|
||||
}
|
||||
--new_opencount[0];
|
||||
for (i = 1; list[i] != NULL; ++i)
|
||||
if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called)
|
||||
if ((list[i]->l_flags_1 & DF_1_NODELETE) == 0
|
||||
/* Decrement counter. */
|
||||
&& --new_opencount[i] == 0)
|
||||
{
|
||||
@ -185,7 +185,10 @@ _dl_close (void *_map)
|
||||
{
|
||||
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
|
||||
if (--new_opencount[dep_list[j]->l_idx] == 0)
|
||||
mark_removed (dep_list[j]);
|
||||
{
|
||||
assert (dep_list[j]->l_type == lt_loaded);
|
||||
mark_removed (dep_list[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,8 +203,11 @@ _dl_close (void *_map)
|
||||
== remmap->l_reldeps[j]))
|
||||
/* Yes, it is. */
|
||||
if (--new_opencount[remmap->l_reldeps[j]->l_idx] == 0)
|
||||
/* This one is now gone, too. */
|
||||
mark_removed (remmap->l_reldeps[j]);
|
||||
{
|
||||
/* This one is now gone, too. */
|
||||
assert (remmap->l_reldeps[j]->l_type == lt_loaded);
|
||||
mark_removed (remmap->l_reldeps[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,57 +221,98 @@ _dl_close (void *_map)
|
||||
{
|
||||
struct link_map *imap = list[i];
|
||||
if (new_opencount[i] == 0 && imap->l_type == lt_loaded
|
||||
&& (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY])
|
||||
&& (! (imap->l_flags_1 & DF_1_NODELETE) || ! imap->l_init_called)
|
||||
/* Skip any half-cooked objects that were never initialized. */
|
||||
&& imap->l_init_called)
|
||||
&& (imap->l_flags_1 & DF_1_NODELETE) == 0)
|
||||
{
|
||||
/* When debugging print a message first. */
|
||||
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||
_dl_debug_printf ("\ncalling fini: %s\n\n", imap->l_name);
|
||||
|
||||
/* Call its termination function. */
|
||||
if (imap->l_info[DT_FINI_ARRAY] != NULL)
|
||||
/* Call its termination function. Do not do it for
|
||||
half-cooked objects. */
|
||||
if (imap->l_init_called)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (imap->l_addr
|
||||
+ imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
unsigned int cnt;
|
||||
if (imap->l_info[DT_FINI_ARRAY] != NULL)
|
||||
{
|
||||
ElfW(Addr) *array =
|
||||
(ElfW(Addr) *) (imap->l_addr
|
||||
+ imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
|
||||
unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
|
||||
/ sizeof (ElfW(Addr)));
|
||||
unsigned int cnt;
|
||||
|
||||
for (cnt = 0; cnt < sz; ++cnt)
|
||||
((fini_t) (imap->l_addr + array[cnt])) ();
|
||||
for (cnt = 0; cnt < sz; ++cnt)
|
||||
((fini_t) (imap->l_addr + array[cnt])) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (imap->l_info[DT_FINI] != NULL)
|
||||
(*(void (*) (void)) DL_DT_FINI_ADDRESS
|
||||
(imap, ((void *) imap->l_addr
|
||||
+ imap->l_info[DT_FINI]->d_un.d_ptr))) ();
|
||||
}
|
||||
|
||||
/* Next try the old-style destructor. */
|
||||
if (imap->l_info[DT_FINI] != NULL)
|
||||
(*(void (*) (void)) DL_DT_FINI_ADDRESS
|
||||
(imap, (void *) imap->l_addr
|
||||
+ imap->l_info[DT_FINI]->d_un.d_ptr)) ();
|
||||
}
|
||||
else if (new_opencount[i] != 0 && imap->l_type == lt_loaded)
|
||||
{
|
||||
/* The object is still used. But the object we are unloading
|
||||
right now is responsible for loading it and therefore we
|
||||
have the search list of the current object in its scope.
|
||||
Remove it. */
|
||||
struct r_scope_elem **runp = imap->l_scope;
|
||||
/* This object must not be used anymore. We must remove the
|
||||
reference from the scope. */
|
||||
unsigned int j;
|
||||
struct link_map **searchlist = map->l_searchlist.r_list;
|
||||
unsigned int nsearchlist = map->l_searchlist.r_nlist;
|
||||
|
||||
while (*runp != NULL)
|
||||
if (*runp == &map->l_searchlist)
|
||||
#ifndef NDEBUG
|
||||
bool found = false;
|
||||
#endif
|
||||
for (j = 0; j < nsearchlist; ++j)
|
||||
if (imap == searchlist[j])
|
||||
{
|
||||
/* Copy all later elements. */
|
||||
while ((runp[0] = runp[1]) != NULL)
|
||||
++runp;
|
||||
/* This is the object to remove. Copy all the
|
||||
following ones. */
|
||||
while (++j < nsearchlist)
|
||||
searchlist[j - 1] = searchlist[j];
|
||||
|
||||
searchlist[j - 1] = NULL;
|
||||
|
||||
--map->l_searchlist.r_nlist;
|
||||
|
||||
#ifndef NDEBUG
|
||||
found = true;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
assert (found);
|
||||
}
|
||||
else if (new_opencount[i] != 0 && imap->l_type == lt_loaded
|
||||
&& imap->l_searchlist.r_list == NULL
|
||||
&& imap->l_initfini != NULL)
|
||||
{
|
||||
/* The object is still used. But the object we are
|
||||
unloading right now is responsible for loading it. If
|
||||
the current object does not have it's own scope yet we
|
||||
have to create one. This has to be done before running
|
||||
the finalizers.
|
||||
|
||||
To do this count the number of dependencies. */
|
||||
unsigned int cnt;
|
||||
for (cnt = 1; imap->l_initfini[cnt] != NULL; ++cnt)
|
||||
if (imap->l_initfini[cnt]->l_idx >= i
|
||||
&& imap->l_initfini[cnt]->l_idx < nopencount)
|
||||
++new_opencount[imap->l_initfini[cnt]->l_idx];
|
||||
else
|
||||
++runp;
|
||||
++imap->l_initfini[cnt]->l_opencount;
|
||||
|
||||
/* We simply reuse the l_initfini list. */
|
||||
imap->l_searchlist.r_list = &imap->l_initfini[cnt + 1];
|
||||
imap->l_searchlist.r_nlist = cnt;
|
||||
|
||||
for (cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
|
||||
if (imap->l_scope[cnt] = &map->l_searchlist)
|
||||
{
|
||||
imap->l_scope[cnt] = &imap->l_searchlist;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the new l_opencount value. */
|
||||
imap->l_opencount = new_opencount[i];
|
||||
|
||||
/* Just a sanity check. */
|
||||
assert (imap->l_type == lt_loaded || imap->l_opencount > 0);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Load the dependencies of a mapped object.
|
||||
Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2001, 2002, 2003 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
|
||||
@ -455,12 +455,14 @@ _dl_map_object_deps (struct link_map *map,
|
||||
needed[nneeded++] = NULL;
|
||||
|
||||
l->l_initfini = (struct link_map **)
|
||||
malloc ((nneeded + 1) * sizeof needed[0]);
|
||||
malloc ((2 * nneeded + 1) * sizeof needed[0]);
|
||||
if (l->l_initfini == NULL)
|
||||
INTUSE(_dl_signal_error) (ENOMEM, map->l_name, NULL,
|
||||
N_("cannot allocate dependency list"));
|
||||
l->l_initfini[0] = l;
|
||||
memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]);
|
||||
memcpy (&l->l_initfini[nneeded + 1], l->l_initfini,
|
||||
nneeded * sizeof needed[0]);
|
||||
}
|
||||
|
||||
/* If we have no auxiliary objects just go on to the next map. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Look up a symbol in the loaded objects.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2001,2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2002, 2003 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
|
||||
@ -90,18 +90,35 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
|
||||
unsigned int i;
|
||||
int result = 0;
|
||||
|
||||
/* Avoid self-references. */
|
||||
/* Avoid self-references and references to objects which cannot be
|
||||
unloaded anyway. */
|
||||
if (undef_map == map)
|
||||
return 0;
|
||||
|
||||
/* Don't create cross-reference between modules which are
|
||||
dynamically loaded by the same dlopen() call. */
|
||||
if (undef_map->l_opencount == 0 && map->l_opencount == 0)
|
||||
return 0;
|
||||
|
||||
/* Make sure nobody can unload the object while we are at it. */
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
||||
/* Don't create cross-reference between modules which are
|
||||
dynamically loaded by the same dlopen() call. */
|
||||
if (undef_map->l_opencount == 0 && map->l_opencount == 0)
|
||||
goto out;
|
||||
|
||||
/* Avoid references to objects which cannot be unloaded anyway. */
|
||||
if (map->l_type != lt_loaded
|
||||
|| (map->l_flags_1 & DF_1_NODELETE) != 0)
|
||||
goto out;
|
||||
|
||||
/* If the object with the undefined reference cannot be removed ever
|
||||
just make sure the same is true for the object which contains the
|
||||
definition. */
|
||||
if (undef_map->l_type != lt_loaded
|
||||
|| (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
|
||||
{
|
||||
++map->l_opencount;
|
||||
map->l_flags |= DF_1_NODELETE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Determine whether UNDEF_MAP already has a reference to MAP. First
|
||||
look in the normal dependencies. */
|
||||
if (undef_map->l_searchlist.r_list != NULL)
|
||||
|
16
elf/nodelete2.c
Normal file
16
elf/nodelete2.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
void *handle = dlopen ("nodel2mod3.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
dlclose (handle);
|
||||
exit (1);
|
||||
}
|
@ -48,6 +48,18 @@ main (void)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
baz = dlsym (h2, "baz");
|
||||
if (baz == NULL)
|
||||
{
|
||||
printf ("cannot get address of \"baz\": %s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
if (baz () != 31)
|
||||
{
|
||||
printf ("baz() did not return 31\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (dlclose (h1) != 0)
|
||||
{
|
||||
printf ("closing h1 failed: %s\n", dlerror ());
|
||||
|
16
elf/reldep9.c
Normal file
16
elf/reldep9.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
void *handle = dlopen ("reldep9mod3.so", RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
printf ("%s\n", dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
dlclose (handle);
|
||||
abort ();
|
||||
}
|
23
elf/reldep9mod1.c
Normal file
23
elf/reldep9mod1.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdlib.h>
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
__attribute__((destructor))
|
||||
bar (void)
|
||||
{
|
||||
static int i;
|
||||
foo ();
|
||||
++i;
|
||||
}
|
||||
|
||||
void
|
||||
__attribute__((constructor))
|
||||
destr (void)
|
||||
{
|
||||
extern void baz (void);
|
||||
baz ();
|
||||
}
|
3
elf/reldep9mod2.c
Normal file
3
elf/reldep9mod2.c
Normal file
@ -0,0 +1,3 @@
|
||||
void baz (void)
|
||||
{
|
||||
}
|
1
elf/reldep9mod3.c
Normal file
1
elf/reldep9mod3.c
Normal file
@ -0,0 +1 @@
|
||||
int x;
|
@ -243,47 +243,59 @@ register void *__gp __asm__("$29");
|
||||
|
||||
# define TLS_LE(x) \
|
||||
({ void *__l; \
|
||||
asm ("ld8 r2=tp\n\t" \
|
||||
asm ("mov r2=r13\n\t" \
|
||||
";;\n\t" \
|
||||
"addl %0=@tpre1(" #x "),r2\n\t" \
|
||||
"addl %0=@tprel(" #x "),r2\n\t" \
|
||||
: "=r" (__l) : : "r2" ); __l; })
|
||||
|
||||
# define TLS_IE(x) \
|
||||
({ void *__l; \
|
||||
asm ("addl r16=@ltoff(@tprel(" #x ")),gp\n\t" \
|
||||
asm (";;\n\t" \
|
||||
"addl r16=@ltoff(@tprel(" #x ")),gp\n\t" \
|
||||
";;\n\t" \
|
||||
"ld8 r17=[r16]\n\t" \
|
||||
";;\n\t" \
|
||||
"add %0=tp,r17\n\t" \
|
||||
"add %0=r13,r17\n\t" \
|
||||
: "=r" (__l) : : "r16", "r17" ); __l; })
|
||||
|
||||
# define __TLS_CALL_CLOBBERS \
|
||||
"r2", "r3", "r8", "r9", "r10", "r11", "r14", "r15", "r16", "r17", \
|
||||
"r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", \
|
||||
"r27", "r28", "r29", "r30", "r31", \
|
||||
"p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
|
||||
"f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
|
||||
"b6", "b7", \
|
||||
"out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7"
|
||||
|
||||
# define TLS_LD(x) \
|
||||
({ void *__l; \
|
||||
asm ("mov loc0=gp\n\t" \
|
||||
asm (";;\n\t" \
|
||||
"mov loc0=gp\n\t" \
|
||||
"addl r16=@ltoff(@dtpmod(" #x ")),gp\n\t" \
|
||||
"addl out1=@dtprel(" #x "),r0\n\t" \
|
||||
";;\n\t" \
|
||||
"ld8 out0=[r16]\n\t" \
|
||||
"br.callrp=__tls_get_addr" \
|
||||
"br.call.sptk.many b0=__tls_get_addr" \
|
||||
";;\n\t" \
|
||||
"mov gp=loc0\n\t" \
|
||||
"mov %0=r8\n\t" \
|
||||
: "=r" (__l) : : "r16" , "loc0" , "out0" , "out1" , "r8" ); \
|
||||
: "=r" (__l) : : "loc0", __TLS_CALL_CLOBBERS); \
|
||||
__l; })
|
||||
|
||||
# define TLS_GD(x) \
|
||||
({ void *__l; \
|
||||
asm ("mov loc0=gp\n\t" \
|
||||
asm (";;\n\t" \
|
||||
"mov loc0=gp\n\t" \
|
||||
"addl r16=@ltoff(@dtpmod(" #x ")),gp\n\t" \
|
||||
"addl r17=@ltoff(@dtprel(" #x ")),gp\n\t" \
|
||||
";;\n\t" \
|
||||
"ld8 out0=[r16]\n\t" \
|
||||
"ld8 out1=[r17]\n\t" \
|
||||
"br.callrp=__tls_get_addr" \
|
||||
"br.call.sptk.many b0=__tls_get_addr" \
|
||||
";;\n\t" \
|
||||
"mov gp=loc0\n\t" \
|
||||
"mov %0=r8\n\t" \
|
||||
: "=r" (__l) : : "r16", "r17" , "loc0" , "out0", "out1" , "r8"); \
|
||||
: "=r" (__l) : : "loc0", __TLS_CALL_CLOBBERS); \
|
||||
__l; })
|
||||
|
||||
#else
|
||||
|
62
io/ftw.c
62
io/ftw.c
@ -1,5 +1,5 @@
|
||||
/* File tree walker functions.
|
||||
Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -18,6 +18,10 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <ftw.h>
|
||||
@ -25,12 +29,49 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <include/sys/stat.h>
|
||||
#if HAVE_SYS_PARAM_H || defined _LIBC
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#ifdef _LIBC
|
||||
# include <include/sys/stat.h>
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/* #define NDEBUG 1 */
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _LIBC
|
||||
# undef __chdir
|
||||
# define __chdir chdir
|
||||
# undef __closedir
|
||||
# define __closedir closedir
|
||||
# undef __fchdir
|
||||
# define __fchdir fchdir
|
||||
# undef __getcwd
|
||||
# define __getcwd getcwd
|
||||
# undef __opendir
|
||||
# define __opendir opendir
|
||||
# undef __readdir64
|
||||
# define __readdir64 readdir
|
||||
# undef __tdestroy
|
||||
# define __tdestroy tdestroy
|
||||
# undef __tfind
|
||||
# define __tfind tfind
|
||||
# undef __tsearch
|
||||
# define __tsearch tsearch
|
||||
# undef internal_function
|
||||
# define internal_function /* empty */
|
||||
# undef dirent64
|
||||
# define dirent64 dirent
|
||||
# undef MAX
|
||||
# define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(Val) errno = (Val)
|
||||
#endif
|
||||
|
||||
/* Support for the LFS API version. */
|
||||
#ifndef FTW_NAME
|
||||
# define FTW_NAME ftw
|
||||
@ -213,9 +254,11 @@ open_dir_stream (struct ftw_data *data, struct dir_data *dirp)
|
||||
/* Open the new stream. */
|
||||
if (result == 0)
|
||||
{
|
||||
const char *name = ((data->flags & FTW_CHDIR)
|
||||
? data->dirbuf + data->ftw.base: data->dirbuf);
|
||||
assert (data->dirstreams[data->actdir] == NULL);
|
||||
|
||||
dirp->stream = __opendir (data->dirbuf);
|
||||
dirp->stream = __opendir (name);
|
||||
if (dirp->stream == NULL)
|
||||
result = -1;
|
||||
else
|
||||
@ -251,7 +294,7 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
|
||||
char *newp;
|
||||
|
||||
data->dirbufsize *= 2;
|
||||
newp = realloc (data->dirbuf, data->dirbufsize);
|
||||
newp = (char *) realloc (data->dirbuf, data->dirbufsize);
|
||||
if (newp == NULL)
|
||||
return -1;
|
||||
data->dirbuf = newp;
|
||||
@ -259,14 +302,17 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
|
||||
|
||||
*((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0';
|
||||
|
||||
if ((data->flags & FTW_CHDIR) == 0)
|
||||
name = data->dirbuf;
|
||||
|
||||
if (((data->flags & FTW_PHYS)
|
||||
? LXSTAT (_STAT_VER, data->dirbuf, &st)
|
||||
: XSTAT (_STAT_VER, data->dirbuf, &st)) < 0)
|
||||
? LXSTAT (_STAT_VER, name, &st)
|
||||
: XSTAT (_STAT_VER, name, &st)) < 0)
|
||||
{
|
||||
if (errno != EACCES && errno != ENOENT)
|
||||
result = -1;
|
||||
else if (!(data->flags & FTW_PHYS)
|
||||
&& LXSTAT (_STAT_VER, data->dirbuf, &st) == 0
|
||||
&& LXSTAT (_STAT_VER, name, &st) == 0
|
||||
&& S_ISLNK (st.st_mode))
|
||||
flag = FTW_SLN;
|
||||
else
|
||||
|
@ -1,3 +1,50 @@
|
||||
2003-01-11 Philip Blundell <philb@gnu.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/vfork.S: New file.
|
||||
* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO_RET):
|
||||
Correctly unstack lr.
|
||||
(UNDOARGS_5): Fix ordering of pushes and pops.
|
||||
(SINGLE_THREAD_P_PIC): New.
|
||||
(SINGLE_THREAD_P_INT): New.
|
||||
(SINGLE_THREAD_P): Implement in terms of above. Restore lr if it
|
||||
was stacked.
|
||||
(PSEUDO): Use SINGLE_THREAD_P_INT.
|
||||
|
||||
2003-01-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sh/vfork.S: New file.
|
||||
|
||||
2003-01-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/ia64/tls.h (tcbhead_t): Change into dtv_t *, void *.
|
||||
[HAVE_TLS_SUPPORT] (USE_TLS, TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN,
|
||||
TLS_TCB_SIZE, TLS_PRE_TCB_SIZE, TLS_TCB_ALIGN, TLS_DTV_AT_TP,
|
||||
INSTALL_DTV, INSTALL_NEW_DTV, GET_DTV, TLS_INIT_TP, THREAD_SELF,
|
||||
INIT_THREAD_SELF): Define.
|
||||
[HAVE_TLS_SUPPORT]: Include descr.h.
|
||||
(NONTLS_INIT_TP): Point __thread_self at the end of dummy
|
||||
struct _pthread_descr_struct.
|
||||
* sysdeps/ia64/pt-machine.h (THREAD_GETMEM, THREAD_GETMEM_NC,
|
||||
THREAD_SETMEM, THREAD_SETMEM_NC): Define using THREAD_SELF,
|
||||
not __thread_self.
|
||||
* sysdeps/ia64/tcb-offsets.sym (MULTIPLE_THREADS_OFFSET): Adjust
|
||||
computation.
|
||||
* pthread.c (__pthread_initialize_minimal): Use tcbp, not self
|
||||
for TCB pointer.
|
||||
(__pthread_initialize_manager): Rename tcb to mgr.
|
||||
Use tcbp for TCB pointer, if TLS_DTV_AT_TP set mgr to sizeof (struct
|
||||
_pthread_descr) below tcbp, otherwise to tcbp.
|
||||
* manager.c (pthread_handle_create): If TLS_DTV_AT_TP, set
|
||||
new_thread to be below _dl_allocate_tls (). Adjust new_thread back
|
||||
before freeing. Fix clone arguments if report_events and USE_TLS.
|
||||
(pthread_free): Adjust th back before freeing.
|
||||
|
||||
2003-01-10 Steven Munroe <sjmunroe@us.ibm.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile: Moved to ...
|
||||
* sysdeps/unix/sysv/linux/powerpc/Makefile: ...here.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: New File.
|
||||
|
||||
2003-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/vfork.S: New file.
|
||||
|
@ -590,6 +590,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
new_thread = _dl_allocate_tls (NULL);
|
||||
if (new_thread == NULL)
|
||||
return EAGAIN;
|
||||
# if TLS_DTV_AT_TP
|
||||
/* pthread_descr is right below TP. */
|
||||
--new_thread;
|
||||
# endif
|
||||
#else
|
||||
/* Prevent warnings. */
|
||||
new_thread = NULL;
|
||||
@ -607,6 +611,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
if (sseg >= PTHREAD_THREADS_MAX)
|
||||
{
|
||||
#ifdef USE_TLS
|
||||
# if TLS_DTV_AT_TP
|
||||
++new_thread;
|
||||
# endif
|
||||
_dl_deallocate_tls (new_thread, true);
|
||||
#endif
|
||||
return EAGAIN;
|
||||
@ -631,7 +638,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
new_thread_id = sseg + pthread_threads_counter;
|
||||
/* Initialize the thread descriptor. Elements which have to be
|
||||
initialized to zero already have this value. */
|
||||
#if defined USE_TLS && TLS_DTV_AT_TP
|
||||
new_thread->p_header.data.tcb = new_thread + 1;
|
||||
#else
|
||||
new_thread->p_header.data.tcb = new_thread;
|
||||
#endif
|
||||
new_thread->p_header.data.self = new_thread;
|
||||
new_thread->p_header.data.multiple_threads = 1;
|
||||
new_thread->p_tid = new_thread_id;
|
||||
@ -711,15 +722,15 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
other, to get less paging and fewer mmaps. */
|
||||
pid = __clone2(pthread_start_thread_event,
|
||||
(void **)new_thread_bottom,
|
||||
(char *)new_thread - new_thread_bottom,
|
||||
(char *)stack_addr - new_thread_bottom,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
||||
__pthread_sig_cancel, new_thread);
|
||||
#elif _STACK_GROWS_UP
|
||||
pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom,
|
||||
pid = __clone(pthread_start_thread_event, (void *) new_thread_bottom,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
||||
__pthread_sig_cancel, new_thread);
|
||||
#else
|
||||
pid = __clone(pthread_start_thread_event, (void **) new_thread,
|
||||
pid = __clone(pthread_start_thread_event, stack_addr,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
||||
__pthread_sig_cancel, new_thread);
|
||||
#endif
|
||||
@ -794,6 +805,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_TLS
|
||||
# if TLS_DTV_AT_TP
|
||||
++new_thread;
|
||||
# endif
|
||||
_dl_deallocate_tls (new_thread, true);
|
||||
#endif
|
||||
__pthread_handles[sseg].h_descr = NULL;
|
||||
@ -881,6 +895,9 @@ static void pthread_free(pthread_descr th)
|
||||
munmap(guardaddr, stacksize + guardsize);
|
||||
|
||||
#ifdef USE_TLS
|
||||
# if TLS_DTV_AT_TP
|
||||
++th;
|
||||
# endif
|
||||
_dl_deallocate_tls (th, true);
|
||||
#endif
|
||||
}
|
||||
|
@ -307,6 +307,8 @@ __pthread_initialize_minimal(void)
|
||||
# elif !USE___THREAD
|
||||
if (__builtin_expect (GL(dl_tls_max_dtv_idx) == 0, 0))
|
||||
{
|
||||
tcbhead_t *tcbp;
|
||||
|
||||
/* There is no actual TLS being used, so the thread register
|
||||
was not initialized in the dynamic linker. */
|
||||
|
||||
@ -318,7 +320,7 @@ __pthread_initialize_minimal(void)
|
||||
__libc_malloc_pthread_startup (true);
|
||||
|
||||
if (__builtin_expect (_dl_tls_setup (), 0)
|
||||
|| __builtin_expect ((self = _dl_allocate_tls (NULL)) == NULL, 0))
|
||||
|| __builtin_expect ((tcbp = _dl_allocate_tls (NULL)) == NULL, 0))
|
||||
{
|
||||
static const char msg[] = "\
|
||||
cannot allocate TLS data structures for initial thread\n";
|
||||
@ -326,7 +328,7 @@ cannot allocate TLS data structures for initial thread\n";
|
||||
msg, sizeof msg - 1));
|
||||
abort ();
|
||||
}
|
||||
const char *lossage = TLS_INIT_TP (self, 0);
|
||||
const char *lossage = TLS_INIT_TP (tcbp, 0);
|
||||
if (__builtin_expect (lossage != NULL, 0))
|
||||
{
|
||||
static const char msg[] = "cannot set up thread-local storage: ";
|
||||
@ -343,7 +345,7 @@ cannot allocate TLS data structures for initial thread\n";
|
||||
the hooks might not work with that block from the plain malloc.
|
||||
So we record this block as unfreeable just as the dynamic linker
|
||||
does when it allocates the DTV before the libc malloc exists. */
|
||||
GL(dl_initial_dtv) = GET_DTV (self);
|
||||
GL(dl_initial_dtv) = GET_DTV (tcbp);
|
||||
|
||||
__libc_malloc_pthread_startup (false);
|
||||
}
|
||||
@ -558,7 +560,10 @@ int __pthread_initialize_manager(void)
|
||||
int pid;
|
||||
struct pthread_request request;
|
||||
int report_events;
|
||||
pthread_descr tcb;
|
||||
pthread_descr mgr;
|
||||
#ifdef USE_TLS
|
||||
tcbhead_t *tcbp;
|
||||
#endif
|
||||
|
||||
__pthread_multiple_threads = 1;
|
||||
__pthread_main_thread->p_header.data.multiple_threads = 1;
|
||||
@ -588,31 +593,39 @@ int __pthread_initialize_manager(void)
|
||||
|
||||
#ifdef USE_TLS
|
||||
/* Allocate memory for the thread descriptor and the dtv. */
|
||||
__pthread_handles[1].h_descr = manager_thread = tcb
|
||||
= _dl_allocate_tls (NULL);
|
||||
if (tcb == NULL) {
|
||||
tcbp = _dl_allocate_tls (NULL);
|
||||
if (tcbp == NULL) {
|
||||
free(__pthread_manager_thread_bos);
|
||||
__libc_close(manager_pipe[0]);
|
||||
__libc_close(manager_pipe[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize the descriptor. */
|
||||
tcb->p_header.data.tcb = tcb;
|
||||
tcb->p_header.data.self = tcb;
|
||||
tcb->p_header.data.multiple_threads = 1;
|
||||
tcb->p_lock = &__pthread_handles[1].h_lock;
|
||||
# ifndef HAVE___THREAD
|
||||
tcb->p_errnop = &tcb->p_errno;
|
||||
# if TLS_TCB_AT_TP
|
||||
mgr = (pthread_descr) tcbp;
|
||||
# elif TLS_DTV_AT_TP
|
||||
/* pthread_descr is located right below tcbhead_t which _dl_allocate_tls
|
||||
returns. */
|
||||
mgr = (pthread_descr) tcbp - 1;
|
||||
# endif
|
||||
tcb->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager);
|
||||
tcb->p_nr = 1;
|
||||
__pthread_handles[1].h_descr = manager_thread = mgr;
|
||||
|
||||
/* Initialize the descriptor. */
|
||||
mgr->p_header.data.tcb = tcbp;
|
||||
mgr->p_header.data.self = mgr;
|
||||
mgr->p_header.data.multiple_threads = 1;
|
||||
mgr->p_lock = &__pthread_handles[1].h_lock;
|
||||
# ifndef HAVE___THREAD
|
||||
mgr->p_errnop = &mgr->p_errno;
|
||||
# endif
|
||||
mgr->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager);
|
||||
mgr->p_nr = 1;
|
||||
# if __LT_SPINLOCK_INIT != 0
|
||||
self->p_resume_count = (struct pthread_atomic) __ATOMIC_INITIALIZER;
|
||||
# endif
|
||||
tcb->p_alloca_cutoff = PTHREAD_STACK_MIN / 4;
|
||||
mgr->p_alloca_cutoff = PTHREAD_STACK_MIN / 4;
|
||||
#else
|
||||
tcb = &__pthread_manager_thread;
|
||||
mgr = &__pthread_manager_thread;
|
||||
#endif
|
||||
|
||||
__pthread_manager_request = manager_pipe[1]; /* writing end */
|
||||
@ -649,24 +662,24 @@ int __pthread_initialize_manager(void)
|
||||
if ((mask & (__pthread_threads_events.event_bits[idx] | event_bits))
|
||||
!= 0)
|
||||
{
|
||||
__pthread_lock(tcb->p_lock, NULL);
|
||||
__pthread_lock(mgr->p_lock, NULL);
|
||||
|
||||
#ifdef NEED_SEPARATE_REGISTER_STACK
|
||||
pid = __clone2(__pthread_manager_event,
|
||||
(void **) __pthread_manager_thread_bos,
|
||||
THREAD_MANAGER_STACK_SIZE,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
|
||||
tcb);
|
||||
mgr);
|
||||
#elif _STACK_GROWS_UP
|
||||
pid = __clone(__pthread_manager_event,
|
||||
(void **) __pthread_manager_thread_bos,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
|
||||
tcb);
|
||||
mgr);
|
||||
#else
|
||||
pid = __clone(__pthread_manager_event,
|
||||
(void **) __pthread_manager_thread_tos,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
|
||||
tcb);
|
||||
mgr);
|
||||
#endif
|
||||
|
||||
if (pid != -1)
|
||||
@ -675,18 +688,18 @@ int __pthread_initialize_manager(void)
|
||||
the newly created thread's data structure. We cannot let
|
||||
the new thread do this since we don't know whether it was
|
||||
already scheduled when we send the event. */
|
||||
tcb->p_eventbuf.eventdata = tcb;
|
||||
tcb->p_eventbuf.eventnum = TD_CREATE;
|
||||
__pthread_last_event = tcb;
|
||||
tcb->p_tid = 2* PTHREAD_THREADS_MAX + 1;
|
||||
tcb->p_pid = pid;
|
||||
mgr->p_eventbuf.eventdata = mgr;
|
||||
mgr->p_eventbuf.eventnum = TD_CREATE;
|
||||
__pthread_last_event = mgr;
|
||||
mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1;
|
||||
mgr->p_pid = pid;
|
||||
|
||||
/* Now call the function which signals the event. */
|
||||
__linuxthreads_create_event ();
|
||||
}
|
||||
|
||||
/* Now restart the thread. */
|
||||
__pthread_unlock(tcb->p_lock);
|
||||
__pthread_unlock(mgr->p_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,13 +708,13 @@ int __pthread_initialize_manager(void)
|
||||
#ifdef NEED_SEPARATE_REGISTER_STACK
|
||||
pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos,
|
||||
THREAD_MANAGER_STACK_SIZE,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb);
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr);
|
||||
#elif _STACK_GROWS_UP
|
||||
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb);
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr);
|
||||
#else
|
||||
pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, tcb);
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, mgr);
|
||||
#endif
|
||||
}
|
||||
if (__builtin_expect (pid, 0) == -1) {
|
||||
@ -710,8 +723,8 @@ int __pthread_initialize_manager(void)
|
||||
__libc_close(manager_pipe[1]);
|
||||
return -1;
|
||||
}
|
||||
tcb->p_tid = 2* PTHREAD_THREADS_MAX + 1;
|
||||
tcb->p_pid = pid;
|
||||
mgr->p_tid = 2* PTHREAD_THREADS_MAX + 1;
|
||||
mgr->p_pid = pid;
|
||||
/* Make gdb aware of new thread manager */
|
||||
if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Machine-dependent pthreads configuration and inline functions.
|
||||
IA-64 version.
|
||||
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2002, 2003 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
|
||||
@ -64,10 +64,10 @@ register struct _pthread_descr_struct *__thread_self __asm__("r13");
|
||||
|
||||
|
||||
/* Access to data in the thread descriptor is easy. */
|
||||
#define THREAD_GETMEM(descr, member) __thread_self->member
|
||||
#define THREAD_GETMEM_NC(descr, member) __thread_self->member
|
||||
#define THREAD_SETMEM(descr, member, value) __thread_self->member = (value)
|
||||
#define THREAD_SETMEM_NC(descr, member, value) __thread_self->member = (value)
|
||||
#define THREAD_GETMEM(descr, member) THREAD_SELF->member
|
||||
#define THREAD_GETMEM_NC(descr, member) THREAD_SELF->member
|
||||
#define THREAD_SETMEM(descr, member, value) THREAD_SELF->member = (value)
|
||||
#define THREAD_SETMEM_NC(descr, member, value) THREAD_SELF->member = (value)
|
||||
|
||||
|
||||
/* Memory barrier */
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
|
||||
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
|
||||
MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads) - sizeof (struct _pthread_descr_struct)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definitions for thread-local data handling. linuxthreads/IA-64 version.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003 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
|
||||
@ -33,35 +33,91 @@ typedef union dtv
|
||||
} dtv_t;
|
||||
|
||||
|
||||
/* FIXME: Only temporary. When TLS is supported on IA-64,
|
||||
pthread_descr struct needs to be immediately below r13 and
|
||||
at r13 a struct { dtv_t *dtv; void *private; }. */
|
||||
typedef struct
|
||||
{
|
||||
void *tcb; /* Pointer to the TCB. Not necessary the
|
||||
thread descriptor used by libpthread. */
|
||||
dtv_t *dtv;
|
||||
void *self; /* Pointer to the thread descriptor. */
|
||||
int multiple_threads;
|
||||
void *private;
|
||||
} tcbhead_t;
|
||||
|
||||
#else /* __ASSEMBLER__ */
|
||||
# include <tcb-offsets.h>
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#undef USE_TLS
|
||||
#ifdef HAVE_TLS_SUPPORT
|
||||
|
||||
#if USE_TLS
|
||||
/* Signal that TLS support is available. */
|
||||
# define USE_TLS 1
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
/* This is the size of the initial TCB. */
|
||||
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* Alignment requirements for the initial TCB. */
|
||||
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
|
||||
|
||||
/* This is the size of the TCB. */
|
||||
# define TLS_TCB_SIZE sizeof (tcbhead_t)
|
||||
|
||||
/* This is the size we need before TCB. */
|
||||
# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
|
||||
|
||||
/* Alignment requirements for the TCB. */
|
||||
# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
|
||||
|
||||
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
|
||||
# define TLS_DTV_AT_TP 1
|
||||
|
||||
/* Install the dtv pointer. The pointer passed is to the element with
|
||||
index -1 which contain the length. */
|
||||
# define INSTALL_DTV(tcbp, dtvp) \
|
||||
((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1
|
||||
|
||||
/* Install new dtv for current thread. */
|
||||
# define INSTALL_NEW_DTV(DTV) \
|
||||
(((tcbhead_t *)__thread_self)->dtv = (DTV))
|
||||
|
||||
/* Return dtv of given thread descriptor. */
|
||||
# define GET_DTV(tcbp) \
|
||||
(((tcbhead_t *) (tcbp))->dtv)
|
||||
|
||||
/* Code to initially initialize the thread pointer. This might need
|
||||
special attention since 'errno' is not yet available and if the
|
||||
operation can cause a failure 'errno' must not be touched. */
|
||||
# define TLS_INIT_TP(tcbp, secondcall) \
|
||||
(__thread_self = (tcbp), NULL)
|
||||
|
||||
/* Return the address of the dtv for the current thread. */
|
||||
# define THREAD_DTV() \
|
||||
(((tcbhead_t *)__thread_self)->dtv)
|
||||
|
||||
/* Return the thread descriptor for the current thread. */
|
||||
# undef THREAD_SELF
|
||||
# define THREAD_SELF (__thread_self - 1)
|
||||
|
||||
# undef INIT_THREAD_SELF
|
||||
# define INIT_THREAD_SELF(descr, nr) \
|
||||
(__thread_self = (struct _pthread_descr_struct *)(descr) + 1)
|
||||
|
||||
/* Get the thread descriptor definition. */
|
||||
# include <linuxthreads/descr.h>
|
||||
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#define NONTLS_INIT_TP \
|
||||
do { \
|
||||
static const tcbhead_t nontls_init_tp \
|
||||
= { .multiple_threads = 0 }; \
|
||||
__thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
|
||||
# ifndef __ASSEMBLER__
|
||||
/* Get the thread descriptor definition. */
|
||||
# include <linuxthreads/descr.h>
|
||||
|
||||
# define NONTLS_INIT_TP \
|
||||
do { \
|
||||
static struct _pthread_descr_struct nontls_init_tp \
|
||||
= { .p_header.data.multiple_threads = 0 }; \
|
||||
__thread_self = ((__typeof (__thread_self)) &nontls_init_tp) + 1; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* USE_TLS */
|
||||
|
||||
#endif /* tls.h */
|
||||
|
@ -27,6 +27,7 @@
|
||||
# undef PSEUDO_RET
|
||||
# define PSEUDO_RET \
|
||||
ldrcc pc, [sp], $4; \
|
||||
ldr lr, [sp], $4; \
|
||||
b PLTJMP(SYSCALL_ERROR)
|
||||
|
||||
# undef PSEUDO
|
||||
@ -34,7 +35,7 @@
|
||||
.section ".text"; \
|
||||
PSEUDO_PROLOGUE; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
SINGLE_THREAD_P_INT; \
|
||||
bne .Lpseudo_cancel; \
|
||||
DO_CALL (syscall_name, args); \
|
||||
cmn r0, $4096; \
|
||||
@ -74,7 +75,7 @@
|
||||
# define UNDOC2ARGS_4
|
||||
|
||||
# define DOCARGS_5 stmfd sp!, {r0-r3}
|
||||
# define UNDOCARGS_5 str r4, [sp, #-4]!; ldmfd sp, {r0-r4}
|
||||
# define UNDOCARGS_5 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
|
||||
# define UNDOC2ARGS_5 ldr r4, [sp], #20
|
||||
|
||||
# ifdef IS_IN_libpthread
|
||||
@ -92,10 +93,11 @@ extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# if !defined PIC
|
||||
# define SINGLE_THREAD_P \
|
||||
# define SINGLE_THREAD_P_INT \
|
||||
ldr ip, =__local_multiple_threads; \
|
||||
ldr ip, [ip]; \
|
||||
teq ip, #0;
|
||||
# define SINGLE_THREAD_P SINGLE_THREAD_P_INT
|
||||
# define MAYBE_SAVE_LR \
|
||||
str lr, [sp, $-4]!;
|
||||
# define PSEUDO_RET_MOV \
|
||||
@ -103,14 +105,19 @@ extern int __local_multiple_threads attribute_hidden;
|
||||
b PLTJMP(SYSCALL_ERROR)
|
||||
# define PSEUDO_PROLOGUE
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
str lr, [sp, $-4]!; \
|
||||
# define SINGLE_THREAD_P_PIC(reg) \
|
||||
ldr ip, 1b; \
|
||||
ldr lr, 2b; \
|
||||
ldr reg, 2b; \
|
||||
3: \
|
||||
add ip, pc, ip; \
|
||||
ldr ip, [ip, lr]; \
|
||||
teq ip, #0;
|
||||
# define SINGLE_THREAD_P_INT \
|
||||
str lr, [sp, $-4]!; \
|
||||
SINGLE_THREAD_P_PIC(lr)
|
||||
# define SINGLE_THREAD_P \
|
||||
SINGLE_THREAD_P_INT; \
|
||||
ldr lr, [sp], $4
|
||||
# define PSEUDO_PROLOGUE \
|
||||
1: .word _GLOBAL_OFFSET_TABLE_ - 3f - 8; \
|
||||
2: .word __local_multiple_threads(GOTOFF);
|
||||
|
57
linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
Normal file
57
linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Philip Blundell <philb@gnu.org>.
|
||||
|
||||
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 <sysdep-cancel.h>
|
||||
#define _ERRNO_H 1
|
||||
#include <bits/errno.h>
|
||||
|
||||
/* Clone the calling process, but without copying the whole address
|
||||
pace.
|
||||
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,
|
||||
and the process ID of the new process to the old process. */
|
||||
|
||||
PSEUDO_PROLOGUE
|
||||
|
||||
ENTRY (__vfork)
|
||||
|
||||
#ifdef __NR_vfork
|
||||
SINGLE_THREAD_P
|
||||
bne HIDDEN_JUMPTARGET (__fork)
|
||||
swi __NR_vfork
|
||||
cmn a1, #4096
|
||||
RETINSTR(movcc, pc, lr)
|
||||
|
||||
/* Check if vfork syscall is known at all. */
|
||||
ldr a2, =-ENOSYS
|
||||
teq a1, a2
|
||||
bne PLTJMP(C_SYMBOL_NAME(__syscall_error))
|
||||
#endif
|
||||
|
||||
/* If we don't have vfork, fork is close enough. */
|
||||
swi __NR_fork
|
||||
cmn a1, #4096
|
||||
RETINSTR(movcc, pc, lr)
|
||||
b PLTJMP(C_SYMBOL_NAME(__syscall_error))
|
||||
|
||||
PSEUDO_END (__vfork)
|
||||
libc_hidden_def (__vfork)
|
||||
|
||||
weak_alias (__vfork, vfork)
|
@ -0,0 +1,102 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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 <sysdep.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <linuxthreads/internals.h>
|
||||
#endif
|
||||
|
||||
#if !defined NOT_IN_libc || defined IS_IN_libpthread
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.section ".text"; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
bne- .Lpseudo_cancel; \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
PSEUDO_RET; \
|
||||
.Lpseudo_cancel: \
|
||||
stdu 1,-128(1); \
|
||||
mflr 9; \
|
||||
std 9,128+16(1); \
|
||||
DOCARGS_##args; /* save syscall args around CENABLE. */ \
|
||||
CENABLE; \
|
||||
std 3,72(1); /* store CENABLE return value (MASK). */ \
|
||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
mfcr 0; /* save CR/R3 around CDISABLE. */ \
|
||||
std 3,64(1); \
|
||||
std 0,8(1); \
|
||||
ld 3,72(1); /* pass MASK to CDISABLE. */ \
|
||||
CDISABLE; \
|
||||
ld 9,128+16(1); \
|
||||
ld 0,8(1); /* restore CR/R3. */ \
|
||||
ld 3,64(1); \
|
||||
mtlr 9; \
|
||||
mtcr 0; \
|
||||
addi 1,1,128;
|
||||
|
||||
# define DOCARGS_0
|
||||
# define UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_1 std 3,80(1); DOCARGS_0
|
||||
# define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_2 std 4,88(1); DOCARGS_1
|
||||
# define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
|
||||
|
||||
# define DOCARGS_3 std 5,96(1); DOCARGS_2
|
||||
# define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
|
||||
|
||||
# define DOCARGS_4 std 6,104(1); DOCARGS_3
|
||||
# define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
|
||||
|
||||
# define DOCARGS_5 std 7,112(1); DOCARGS_4
|
||||
# define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
|
||||
|
||||
# define DOCARGS_6 std 8,120(1); DOCARGS_5
|
||||
# define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
|
||||
|
||||
# ifdef IS_IN_libpthread
|
||||
# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
|
||||
# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# else
|
||||
# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
|
||||
# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
ld 10,__local_multiple_threads@got(2); \
|
||||
ld 10,0(10); \
|
||||
cmpdi 10,0
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
/* This code should never be used but we define it anyhow. */
|
||||
# define SINGLE_THREAD_P (1)
|
||||
|
||||
#endif
|
57
linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
Normal file
57
linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2003 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 <sysdep-cancel.h>
|
||||
#define _ERRNO_H 1
|
||||
#include <bits/errno.h>
|
||||
|
||||
/* 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 process,
|
||||
and the process ID of the new process to the old process. */
|
||||
|
||||
ENTRY (__vfork)
|
||||
SINGLE_THREAD_P
|
||||
bf .Lhidden_fork
|
||||
|
||||
mov.w .L1, r3
|
||||
trapa #0x10
|
||||
mov r0, r1
|
||||
mov #-12, r2
|
||||
shad r2, r1
|
||||
not r1, r1 // r1=0 means r0 = -1 to -4095
|
||||
tst r1, r1 // i.e. error in linux
|
||||
bf .Lpseudo_end
|
||||
SYSCALL_ERROR_HANDLER
|
||||
.Lpseudo_end:
|
||||
rts
|
||||
nop
|
||||
.L1: .word __NR_vfork
|
||||
|
||||
.Lhidden_fork:
|
||||
mov.l .L2, r1
|
||||
braf r1
|
||||
nop
|
||||
1:
|
||||
.align 2
|
||||
.L2: .long HIDDEN_JUMPTARGET(__fork)-1b
|
||||
|
||||
PSEUDO_END (__vfork)
|
||||
libc_hidden_def (__vfork)
|
||||
|
||||
weak_alias (__vfork, vfork)
|
@ -174,11 +174,13 @@ test_strcpy (void)
|
||||
SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
|
||||
SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
|
||||
|
||||
#if 0
|
||||
/* Simple test using implicitly coerced `void *' arguments. */
|
||||
const void *src = "frobozz";
|
||||
void *dst = one;
|
||||
check (strcpy (dst, src) == dst, 1);
|
||||
equal (dst, "frobozz", 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. Alpha version.
|
||||
Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2002, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Richard Henderson <rth@tamu.edu>.
|
||||
|
||||
@ -610,8 +610,8 @@ elf_machine_rela (struct link_map *map,
|
||||
#else
|
||||
if (sym_map)
|
||||
{
|
||||
*reloc_addr = sym_value - sym_map->l_tls_offset;
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr = sym_value - sym_map->l_tls_offset;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -282,9 +282,18 @@ internal_function
|
||||
_dl_allocate_tls_storage (void)
|
||||
{
|
||||
void *result;
|
||||
size_t size = GL(dl_tls_static_size);
|
||||
|
||||
# if TLS_DTV_AT_TP
|
||||
/* Memory layout is:
|
||||
[ TLS_PRE_TCB_SIZE ] [ TLS_TCB_SIZE ] [ TLS blocks ]
|
||||
^ This should be returned. */
|
||||
size += (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
|
||||
& ~(GL(dl_tls_static_align) - 1);
|
||||
# endif
|
||||
|
||||
/* Allocate a correctly aligned chunk of memory. */
|
||||
result = __libc_memalign (GL(dl_tls_static_align), GL(dl_tls_static_size));
|
||||
result = __libc_memalign (GL(dl_tls_static_align), size);
|
||||
if (__builtin_expect (result != NULL, 0))
|
||||
{
|
||||
/* Allocate the DTV. */
|
||||
@ -292,12 +301,20 @@ _dl_allocate_tls_storage (void)
|
||||
|
||||
# if TLS_TCB_AT_TP
|
||||
/* The TCB follows the TLS blocks. */
|
||||
result = (char *) result + GL(dl_tls_static_size) - TLS_TCB_SIZE;
|
||||
# endif
|
||||
result = (char *) result + size - TLS_TCB_SIZE;
|
||||
|
||||
/* Clear the TCB data structure. We can't ask the caller (i.e.
|
||||
libpthread) to do it, because we will initialize the DTV et al. */
|
||||
memset (result, 0, TLS_TCB_SIZE);
|
||||
# elif TLS_DTV_AT_TP
|
||||
result = (char *) result + size - GL(dl_tls_static_size);
|
||||
|
||||
/* Clear the TCB data structure and TLS_PRE_TCB_SIZE bytes before it.
|
||||
We can't ask the caller (i.e. libpthread) to do it, because we will
|
||||
initialize the DTV et al. */
|
||||
memset ((char *) result - TLS_PRE_TCB_SIZE, 0,
|
||||
TLS_PRE_TCB_SIZE + TLS_TCB_SIZE);
|
||||
# endif
|
||||
|
||||
result = allocate_dtv (result);
|
||||
if (result == NULL)
|
||||
@ -405,6 +422,10 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
|
||||
# if TLS_TCB_AT_TP
|
||||
/* The TCB follows the TLS blocks. Back up to free the whole block. */
|
||||
tcb -= GL(dl_tls_static_size) - TLS_TCB_SIZE;
|
||||
# elif TLS_DTV_AT_TP
|
||||
/* Back up the TLS_PRE_TCB_SIZE bytes. */
|
||||
tcb -= (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
|
||||
& ~(GL(dl_tls_static_align) - 1);
|
||||
# endif
|
||||
free (tcb);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Initialization code for TLS in statically linked application.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003 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
|
||||
@ -134,15 +134,16 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef TLS_INIT_TP_EXPENSIVE
|
||||
if (memsz == 0 && tcbsize <= TLS_INIT_TCB_SIZE)
|
||||
{
|
||||
/* We do not need a TLS block and no thread descriptor. */
|
||||
#ifdef NONTLS_INIT_TP
|
||||
# ifdef NONTLS_INIT_TP
|
||||
NONTLS_INIT_TP;
|
||||
#endif
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* We have to set up the TCB block which also (possibly) contains
|
||||
'errno'. Therefore we avoid 'malloc' which might touch 'errno'.
|
||||
@ -157,8 +158,10 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
|
||||
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
|
||||
# elif TLS_DTV_AT_TP
|
||||
tlsblock = __sbrk (roundup (tcbsize, align) + memsz + max_align
|
||||
+ GL(dl_tls_static_size));
|
||||
tcb_offset = roundup (tcbsize, align ?: 1);
|
||||
tlsblock = __sbrk (tcb_offset + memsz + max_align
|
||||
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
|
||||
tlsblock += TLS_PRE_TCB_SIZE;
|
||||
# else
|
||||
/* In case a model with a different layout for the TCB and DTV
|
||||
is defined add another #elif here and in the following #ifs. */
|
||||
@ -179,7 +182,6 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
- roundup (memsz, align ?: 1));
|
||||
static_map.l_tls_offset = roundup (memsz, align ?: 1);
|
||||
# elif TLS_DTV_AT_TP
|
||||
tcb_offset = roundup (tcbsize, align);
|
||||
static_dtv[2].pointer = (char *) tlsblock + tcb_offset;
|
||||
static_map.l_tls_offset = tcb_offset;
|
||||
# else
|
||||
@ -222,6 +224,8 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
|
||||
# if TLS_TCB_AT_TP
|
||||
memsz += tcbsize;
|
||||
# elif TLS_DTV_AT_TP
|
||||
memsz += tcb_offset;
|
||||
# endif
|
||||
|
||||
init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. i386 version.
|
||||
Copyright (C) 1995,96,97,98,99,2000,2001,2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2002, 2003 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
|
||||
@ -445,8 +445,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||
block we subtract the offset from that of the TLS block. */
|
||||
if (sym != NULL)
|
||||
{
|
||||
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
|
||||
}
|
||||
# endif
|
||||
break;
|
||||
@ -460,8 +460,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||
thread pointer. */
|
||||
if (sym != NULL)
|
||||
{
|
||||
*reloc_addr += sym->st_value - sym_map->l_tls_offset;
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr += sym->st_value - sym_map->l_tls_offset;
|
||||
}
|
||||
# endif
|
||||
break;
|
||||
@ -555,20 +555,20 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
It is a positive value which will be subtracted from the
|
||||
thread pointer. To get the variable position in the TLS
|
||||
block we subtract the offset from that of the TLS block. */
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr
|
||||
= (sym == NULL ? 0 : sym_map->l_tls_offset - sym->st_value)
|
||||
+ reloc->r_addend;
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
break;
|
||||
case R_386_TLS_TPOFF:
|
||||
/* The offset is negative, forward from the thread pointer. */
|
||||
/* We know the offset of object the symbol is contained in.
|
||||
It is a negative value which will be added to the
|
||||
thread pointer. */
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr
|
||||
= (sym == NULL ? 0 : sym->st_value - sym_map->l_tls_offset)
|
||||
+ reloc->r_addend;
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
break;
|
||||
# endif /* use TLS */
|
||||
# ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. IA-64 version.
|
||||
Copyright (C) 1995,1996,1997,2000,2001,2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-1997, 2000-2002, 2003 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
|
||||
@ -26,7 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <tls.h>
|
||||
|
||||
/* Translate a processor specific dynamic tag to the index
|
||||
in l_info array. */
|
||||
@ -448,14 +448,22 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
#define RTLD_START_SPECIAL_INIT /* nothing */
|
||||
#endif
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value.
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS
|
||||
variable, so undefined references should not be allowed to define the
|
||||
value.
|
||||
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
|
||||
of the main executable's symbols, as for a COPY reloc, which we don't
|
||||
use. */
|
||||
/* ??? Ignore IPLTMSB for now. */
|
||||
/* ??? Ignore *MSB for now. */
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
|
||||
#define elf_machine_type_class(type) \
|
||||
(((type) == R_IA64_IPLTLSB || (type) == R_IA64_DTPMOD64LSB \
|
||||
|| (type) == R_IA64_DTPREL64LSB || (type) == R_IA64_TPREL64LSB) \
|
||||
* ELF_RTYPE_CLASS_PLT)
|
||||
#else
|
||||
#define elf_machine_type_class(type) \
|
||||
(((type) == R_IA64_IPLTLSB) * ELF_RTYPE_CLASS_PLT)
|
||||
#endif
|
||||
|
||||
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
|
||||
#define ELF_MACHINE_JMP_SLOT R_IA64_IPLTLSB
|
||||
@ -557,8 +565,7 @@ elf_machine_rela (struct link_map *map,
|
||||
/* RESOLVE_MAP() will return NULL if it fail to locate the symbol. */
|
||||
if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
|
||||
{
|
||||
value = sym ? sym_map->l_addr + sym->st_value : 0;
|
||||
value += reloc->r_addend;
|
||||
value = sym_map->l_addr + sym->st_value + reloc->r_addend;
|
||||
|
||||
if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DIR64LSB))
|
||||
;/* No adjustment. */
|
||||
@ -571,6 +578,26 @@ elf_machine_rela (struct link_map *map,
|
||||
value = __ia64_make_fptr (sym_map, sym, value);
|
||||
else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_PCREL64LSB))
|
||||
value -= (Elf64_Addr) reloc_addr & -16;
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD)
|
||||
else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPMOD64LSB))
|
||||
# ifdef RTLD_BOOTSTRAP
|
||||
/* During startup the dynamic linker is always index 1. */
|
||||
value = 1;
|
||||
# else
|
||||
/* Get the information from the link map returned by the
|
||||
resolv function. */
|
||||
value = sym_map->l_tls_modid;
|
||||
else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPREL64LSB))
|
||||
value -= sym_map->l_addr;
|
||||
# endif
|
||||
else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_TPREL64LSB))
|
||||
{
|
||||
# ifndef RTLD_BOOTSTRAP
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
# endif
|
||||
value += sym_map->l_tls_offset - sym_map->l_addr;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
assert (! "unexpected dynamic reloc type");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Thread-local storage handling in the ELF dynamic linker. IA-64 version.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003 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
|
||||
@ -26,3 +26,5 @@
|
||||
|
||||
/* We have no tls_index type. */
|
||||
#define DONT_USE_TLS_INDEX 1
|
||||
|
||||
extern void *__tls_get_addr (size_t m, size_t offset);
|
||||
|
37
sysdeps/ia64/libc-tls.c
Normal file
37
sysdeps/ia64/libc-tls.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* Thread-local storage handling in the ELF dynamic linker. IA-64 version.
|
||||
Copyright (C) 2003 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 <sysdeps/generic/libc-tls.c>
|
||||
|
||||
#if USE_TLS
|
||||
|
||||
/* On IA-64, as it lacks linker optimizations, __tls_get_addr can be
|
||||
called even in statically linked binaries.
|
||||
In this case module must be always 1 and PT_TLS segment
|
||||
exist in the binary, otherwise it would not link. */
|
||||
|
||||
void *
|
||||
__tls_get_addr (size_t m, size_t offset)
|
||||
{
|
||||
dtv_t *dtv = THREAD_DTV ();
|
||||
return (char *) dtv[1].pointer + offset;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -216,7 +216,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
|
||||
DO_CALL (SYS_ify (syscall_name));
|
||||
|
||||
#define PSEUDO_RET \
|
||||
bnslr; \
|
||||
bnslr+; \
|
||||
b JUMPTARGET(__syscall_error)
|
||||
|
||||
#define ret PSEUDO_RET
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. SH version.
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003 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
|
||||
@ -579,10 +579,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
It is a positive value which will be added to the thread
|
||||
pointer. To get the variable position in the TLS block
|
||||
we add the offset from that of the TLS block. */
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
*reloc_addr
|
||||
= ((sym == NULL ? 0 : sym_map->l_tls_offset + sym->st_value)
|
||||
+ reloc->r_addend);
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
# endif
|
||||
break;
|
||||
#endif /* use TLS */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995, 1996, 1997, 1998, 2003 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
|
||||
@ -16,7 +16,7 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sysdep-cancel.h>
|
||||
#include <socketcall.h>
|
||||
|
||||
#define P(a, b) P2(a, b)
|
||||
@ -53,6 +53,10 @@
|
||||
#define NARGS 3 /* If we were called with no wrapper, this is really socket() */
|
||||
#endif
|
||||
|
||||
#if defined NEED_CANCELLATION && defined CENABLE
|
||||
PSEUDO_PROLOGUE
|
||||
#endif
|
||||
|
||||
.globl __socket
|
||||
ENTRY (__socket)
|
||||
/* This code previously moved sp into ip and stored the args using
|
||||
@ -68,6 +72,15 @@ ENTRY (__socket)
|
||||
/* Push args onto the stack. */
|
||||
P(PUSHARGS_,NARGS)
|
||||
|
||||
#if defined NEED_CANCELLATION && defined CENABLE
|
||||
#ifdef PIC
|
||||
SINGLE_THREAD_P_PIC(r3)
|
||||
#else
|
||||
SINGLE_THREAD_P
|
||||
#endif
|
||||
bne 1f
|
||||
#endif
|
||||
|
||||
/* Do the system call trap. */
|
||||
mov a1, $P(SOCKOP_,socket)
|
||||
mov a2, sp
|
||||
@ -81,6 +94,30 @@ ENTRY (__socket)
|
||||
RETINSTR(movcc, pc, r14)
|
||||
b PLTJMP(SYSCALL_ERROR)
|
||||
|
||||
#if defined NEED_CANCELLATION && defined CENABLE
|
||||
1:
|
||||
str lr, [sp, #-4]!
|
||||
CENABLE
|
||||
mov ip, r0
|
||||
|
||||
mov r0, #P(SOCKOP_,socket)
|
||||
add r1, sp, #4
|
||||
swi SYS_ify(socketcall)
|
||||
|
||||
str r0, [sp, #-4]!
|
||||
mov r0, ip
|
||||
CDISABLE
|
||||
ldr r0, [sp], #4
|
||||
ldr lr, [sp], #4
|
||||
|
||||
P(POPARGS_,NARGS)
|
||||
|
||||
/* r0 is < 0 if there was an error. */
|
||||
cmn r0, $124
|
||||
RETINSTR(movcc, pc, r14)
|
||||
b PLTJMP(SYSCALL_ERROR)
|
||||
#endif
|
||||
|
||||
PSEUDO_END (__socket)
|
||||
|
||||
weak_alias (__socket, socket)
|
||||
|
@ -27,11 +27,11 @@
|
||||
#define _STAT_VER_LINUX_OLD 1
|
||||
#define _STAT_VER_KERNEL 1
|
||||
#define _STAT_VER_SVR4 2
|
||||
#define _STAT_VER_LINUX 3
|
||||
#if __WORDSIZE == 32
|
||||
# define _STAT_VER_LINUX 3
|
||||
# define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
|
||||
# define _STAT_VER _STAT_VER_LINUX
|
||||
#else
|
||||
# define _STAT_VER _STAT_VER_KERNEL /* The one defined below. */
|
||||
# define _STAT_VER _STAT_VER_KERNEL
|
||||
#endif
|
||||
|
||||
/* Versions of the `xmknod' interface. */
|
||||
|
75
sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c
Normal file
75
sysdeps/unix/sysv/linux/powerpc/powerpc64/ftruncate64.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* Copyright (C) 1997,1998,1999,2000,2001,2002 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 <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#ifdef __NR_ftruncate64
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
/* The variable is shared between all wrappers around *truncate64 calls. */
|
||||
extern int have_no_truncate64;
|
||||
#endif
|
||||
|
||||
|
||||
/* Truncate the file FD refers to to LENGTH bytes. */
|
||||
int
|
||||
__ftruncate64 (fd, length)
|
||||
int fd;
|
||||
off64_t length;
|
||||
{
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if (! have_no_truncate64)
|
||||
#endif
|
||||
{
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
int saved_errno = errno;
|
||||
#endif
|
||||
int result = INLINE_SYSCALL (ftruncate64, 2, fd, length);
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if (result != -1 || errno != ENOSYS)
|
||||
#endif
|
||||
return result;
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
__set_errno (saved_errno);
|
||||
have_no_truncate64 = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if ((off_t) length != length)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
return __ftruncate (fd, (off_t) length);
|
||||
#endif
|
||||
}
|
||||
weak_alias (__ftruncate64, ftruncate64)
|
||||
|
||||
#else
|
||||
/* Use the generic implementation. */
|
||||
# include <sysdeps/generic/ftruncate64.c>
|
||||
#endif
|
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c
Normal file
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep-cancel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
|
||||
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
static ssize_t __emulate_pread (int fd, void *buf, size_t count,
|
||||
off_t offset) internal_function;
|
||||
# endif
|
||||
|
||||
|
||||
ssize_t
|
||||
__libc_pread (fd, buf, count, offset)
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t count;
|
||||
off_t offset;
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
if (SINGLE_THREAD_P)
|
||||
{
|
||||
result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pread (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||
|
||||
result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pread (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
LIBC_CANCEL_RESET (oldtype);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
strong_alias (__libc_pread, __pread)
|
||||
weak_alias (__libc_pread, pread)
|
||||
|
||||
# define __libc_pread(fd, buf, count, offset) \
|
||||
static internal_function __emulate_pread (fd, buf, count, offset)
|
||||
#endif
|
||||
|
||||
#if __ASSUME_PREAD_SYSCALL == 0
|
||||
# include <sysdeps/posix/pread.c>
|
||||
#endif
|
84
sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c
Normal file
84
sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c
Normal file
@ -0,0 +1,84 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
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 <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep-cancel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
|
||||
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
static ssize_t __emulate_pread64 (int fd, void *buf, size_t count,
|
||||
off64_t offset) internal_function;
|
||||
# endif
|
||||
|
||||
|
||||
ssize_t
|
||||
__libc_pread64 (fd, buf, count, offset)
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t count;
|
||||
off64_t offset;
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
if (SINGLE_THREAD_P)
|
||||
{
|
||||
result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pread64 (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||
|
||||
result = INLINE_SYSCALL (pread, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pread64 (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
LIBC_CANCEL_RESET (oldtype);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
weak_alias (__libc_pread64, __pread64)
|
||||
weak_alias (__libc_pread64, pread64)
|
||||
|
||||
# define __libc_pread64(fd, buf, count, offset) \
|
||||
static internal_function __emulate_pread64 (fd, buf, count, offset)
|
||||
#endif
|
||||
|
||||
# if __ASSUME_PREAD_SYSCALL == 0
|
||||
# include <sysdeps/posix/pread64.c>
|
||||
#endif
|
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c
Normal file
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep-cancel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
|
||||
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
static ssize_t __emulate_pwrite (int fd, const void *buf, size_t count,
|
||||
off_t offset) internal_function;
|
||||
# endif
|
||||
|
||||
|
||||
ssize_t
|
||||
__libc_pwrite (fd, buf, count, offset)
|
||||
int fd;
|
||||
const void *buf;
|
||||
size_t count;
|
||||
off_t offset;
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
if (SINGLE_THREAD_P)
|
||||
{
|
||||
result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pwrite (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||
|
||||
result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pwrite (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
LIBC_CANCEL_RESET (oldtype);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
strong_alias (__libc_pwrite, __pwrite)
|
||||
weak_alias (__libc_pwrite, pwrite)
|
||||
|
||||
# define __libc_pwrite(fd, buf, count, offset) \
|
||||
static internal_function __emulate_pwrite (fd, buf, count, offset)
|
||||
#endif
|
||||
|
||||
#if __ASSUME_PWRITE_SYSCALL == 0
|
||||
# include <sysdeps/posix/pwrite.c>
|
||||
#endif
|
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c
Normal file
85
sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
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 <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep-cancel.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#if defined __NR_pwrite || __ASSUME_PWRITE_SYSCALL > 0
|
||||
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
static ssize_t __emulate_pwrite64 (int fd, const void *buf, size_t count,
|
||||
off64_t offset) internal_function;
|
||||
# endif
|
||||
|
||||
|
||||
ssize_t
|
||||
__libc_pwrite64 (fd, buf, count, offset)
|
||||
int fd;
|
||||
const void *buf;
|
||||
size_t count;
|
||||
off64_t offset;
|
||||
{
|
||||
ssize_t result;
|
||||
|
||||
if (SINGLE_THREAD_P)
|
||||
{
|
||||
result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pwrite64 (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||
|
||||
result = INLINE_SYSCALL (pwrite, 4, fd, CHECK_N (buf, count), count,
|
||||
offset);
|
||||
# if __ASSUME_PWRITE_SYSCALL == 0
|
||||
if (result == -1 && errno == ENOSYS)
|
||||
/* No system call available. Use the emulation. */
|
||||
result = __emulate_pwrite64 (fd, buf, count, offset);
|
||||
# endif
|
||||
|
||||
LIBC_CANCEL_RESET (oldtype);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
weak_alias (__libc_pwrite64, __pwrite64)
|
||||
libc_hidden_weak (__pwrite64)
|
||||
weak_alias (__libc_pwrite64, pwrite64)
|
||||
|
||||
# define __libc_pwrite64(fd, buf, count, offset) \
|
||||
static internal_function __emulate_pwrite64 (fd, buf, count, offset)
|
||||
#endif
|
||||
|
||||
#if __ASSUME_PWRITE_SYSCALL == 0
|
||||
# include <sysdeps/posix/pwrite64.c>
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1995, 1996, 1997, 1999, 2003 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
|
||||
@ -39,7 +39,7 @@
|
||||
#define NARGS 3
|
||||
#endif
|
||||
|
||||
#define stackblock 48 /* offset to parm save area */
|
||||
#define stackblock 80 /* offset to socket parm area. */
|
||||
|
||||
#ifndef socket
|
||||
/* If this is just socket.S leave it alone! */
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
.text
|
||||
ENTRY(__socket)
|
||||
stdu r1,-112(r1)
|
||||
stdu r1,-144(r1)
|
||||
#if NARGS >= 1
|
||||
std r3,stackblock(r1)
|
||||
#endif
|
||||
@ -79,11 +79,40 @@ ENTRY(__socket)
|
||||
#if NARGS >= 9
|
||||
#error too many arguments!
|
||||
#endif
|
||||
li r3,P(SOCKOP_,socket)
|
||||
|
||||
#if defined NEED_CANCELLATION && defined CENABLE
|
||||
SINGLE_THREAD_P
|
||||
bne- .Lsocket_cancel
|
||||
#endif
|
||||
|
||||
li r3,P(SOCKOP_,socket)
|
||||
addi r4,r1,stackblock
|
||||
DO_CALL(SYS_ify(socketcall))
|
||||
addi r1,r1,112
|
||||
addi r1,r1,144
|
||||
PSEUDO_RET
|
||||
|
||||
#if defined NEED_CANCELLATION && defined CENABLE
|
||||
.Lsocket_cancel:
|
||||
mflr r9
|
||||
std r9,144+16(r1)
|
||||
CENABLE
|
||||
std r3,72(r1)
|
||||
li r3,P(SOCKOP_,socket)
|
||||
addi r4,r1,stackblock
|
||||
DO_CALL(SYS_ify(socketcall))
|
||||
mfcr r0
|
||||
std r3,64(r1)
|
||||
std r0,8(r1)
|
||||
ld r3,72(r1)
|
||||
CDISABLE
|
||||
ld r4,144+16(r1)
|
||||
ld r0,8(r1)
|
||||
ld r3,64(r1)
|
||||
mtlr r4
|
||||
mtcr r0
|
||||
addi r1,r1,144
|
||||
PSEUDO_RET
|
||||
#endif
|
||||
PSEUDO_END (__socket)
|
||||
|
||||
weak_alias (__socket, socket)
|
||||
|
@ -16,7 +16,6 @@ rt_sigtimedwait - rt_sigtimedwait i:pppi __syscall_rt_sigtimedwait
|
||||
s_fcntl fcntl fcntl i:iiF __syscall_fcntl
|
||||
s_fcntl64 fcntl64 fcntl64 i:iiF __syscall_fcntl64
|
||||
s_fstat64 fxstat64 fstat64 i:ip __syscall_fstat64
|
||||
s_ftruncate64 ftruncate64 ftruncate64 i:iii __syscall_ftruncate64
|
||||
s_getcwd getcwd getcwd i:pi __syscall_getcwd
|
||||
s_getdents getdents getdents i:ipi __syscall_getdents
|
||||
s_getdents64 getdents getdents64 i:ipi __syscall_getdents64
|
||||
@ -26,10 +25,8 @@ s_getrlimit getrlimit getrlimit i:ip __syscall_getrlimit
|
||||
s_lstat64 lxstat64 lstat64 i:sp __syscall_lstat64
|
||||
s_mmap2 mmap64 mmap2 b:aniiii __syscall_mmap2
|
||||
s_poll poll poll i:pii __syscall_poll
|
||||
s_pread64 pread64 pread i:ibnii __syscall_pread
|
||||
s_ptrace ptrace ptrace i:iipp __syscall_ptrace
|
||||
s_putpmsg putpmsg putpmsg i:ippii __syscall_putpmsg
|
||||
s_pwrite64 pwrite64 pwrite i:ibnii __syscall_pwrite
|
||||
s_reboot reboot reboot i:iii __syscall_reboot
|
||||
s_setrlimit setrlimit setrlimit i:ip __syscall_setrlimit
|
||||
s_sigaction sigaction sigaction i:ipp __syscall_sigaction
|
||||
@ -38,7 +35,6 @@ s_sigprocmask sigprocmask sigprocmask i:ipp __syscall_sigprocmask
|
||||
s_sigsuspend sigsuspend sigsuspend i:iii __syscall_sigsuspend
|
||||
s_stat64 xstat64 stat64 i:sp __syscall_stat64
|
||||
s_sysctl sysctl _sysctl i:p __syscall__sysctl
|
||||
s_truncate64 truncate64 truncate64 i:sii __syscall_truncate64
|
||||
s_ugetrlimit getrlimit ugetrlimit i:ip __syscall_ugetrlimit
|
||||
s_ustat ustat ustat i:ip __syscall_ustat
|
||||
s_vfork vfork vfork i: __syscall_vfork
|
||||
|
@ -69,65 +69,7 @@
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#undef INLINE_SYSCALL
|
||||
#if 1
|
||||
#define INLINE_SYSCALL(name, nr, args...) \
|
||||
({ \
|
||||
DECLARGS_##nr; \
|
||||
long ret, err; \
|
||||
LOADARGS_##nr(name, args); \
|
||||
__asm __volatile ("sc\n\t" \
|
||||
"mfcr %1\n\t" \
|
||||
: "=r" (r3), "=r" (err) \
|
||||
: ASM_INPUT_##nr \
|
||||
: "cc", "memory"); \
|
||||
ret = r3; \
|
||||
if (err & 1 << 28) \
|
||||
{ \
|
||||
__set_errno (ret); \
|
||||
ret = -1L; \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define DECLARGS_0 register long r0 __asm__ ("r0"); \
|
||||
register long r3 __asm__ ("r3")
|
||||
#define DECLARGS_1 DECLARGS_0
|
||||
#define DECLARGS_2 DECLARGS_1; register long r4 __asm__ ("r4")
|
||||
#define DECLARGS_3 DECLARGS_2; register long r5 __asm__ ("r5")
|
||||
#define DECLARGS_4 DECLARGS_3; register long r6 __asm__ ("r6")
|
||||
#define DECLARGS_5 DECLARGS_4; register long r7 __asm__ ("r7")
|
||||
#define DECLARGS_6 DECLARGS_5; register long r8 __asm__ ("r8")
|
||||
|
||||
#define LOADARGS_0(name) \
|
||||
r0 = __NR_##name
|
||||
#define LOADARGS_1(name, arg1) \
|
||||
LOADARGS_0(name); \
|
||||
r3 = (long) (arg1)
|
||||
#define LOADARGS_2(name, arg1, arg2) \
|
||||
LOADARGS_1(name, arg1); \
|
||||
r4 = (long) (arg2)
|
||||
#define LOADARGS_3(name, arg1, arg2, arg3) \
|
||||
LOADARGS_2(name, arg1, arg2); \
|
||||
r5 = (long) (arg3)
|
||||
#define LOADARGS_4(name, arg1, arg2, arg3, arg4) \
|
||||
LOADARGS_3(name, arg1, arg2, arg3); \
|
||||
r6 = (long) (arg4)
|
||||
#define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
|
||||
LOADARGS_4(name, arg1, arg2, arg3, arg4); \
|
||||
r7 = (long) (arg5)
|
||||
#define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||
LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
|
||||
r8 = (long) (arg6)
|
||||
|
||||
#define ASM_INPUT_0 "r" (r0)
|
||||
#define ASM_INPUT_1 ASM_INPUT_0, "0" (r3)
|
||||
#define ASM_INPUT_2 ASM_INPUT_1, "r" (r4)
|
||||
#define ASM_INPUT_3 ASM_INPUT_2, "r" (r5)
|
||||
#define ASM_INPUT_4 ASM_INPUT_3, "r" (r6)
|
||||
#define ASM_INPUT_5 ASM_INPUT_4, "r" (r7)
|
||||
#define ASM_INPUT_6 ASM_INPUT_5, "r" (r8)
|
||||
|
||||
#else
|
||||
/* This version is for kernels that implement system calls that
|
||||
behave like function calls as far as register saving. */
|
||||
#define INLINE_SYSCALL(name, nr, args...) \
|
||||
@ -149,40 +91,89 @@
|
||||
: ASM_INPUT_##nr \
|
||||
: "r9", "r10", "r11", "r12", \
|
||||
"fr0", "fr1", "fr2", "fr3", \
|
||||
"fr4", "fr5", "fr6", "fr7", \
|
||||
"fr8", "fr9", "fr10", "fr11", \
|
||||
"fr12", "fr13", \
|
||||
"ctr", "lr", \
|
||||
"cr0", "cr1", "cr5", "cr6", "cr7", \
|
||||
"memory"); \
|
||||
"fr4", "fr5", "fr6", "fr7", \
|
||||
"fr8", "fr9", "fr10", "fr11", \
|
||||
"fr12", "fr13", \
|
||||
"ctr", "lr", \
|
||||
"cr0", "cr1", "cr5", "cr6", "cr7", \
|
||||
"memory"); \
|
||||
ret = r3; \
|
||||
if (err & 1 << 28) \
|
||||
if (__builtin_expect ((err & (1 << 28)), 0)) \
|
||||
{ \
|
||||
__set_errno (ret); \
|
||||
ret = -1L; \
|
||||
__set_errno (ret); \
|
||||
ret = -1L; \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define LOADARGS_0(name) \
|
||||
/* Define a macro which expands inline into the wrapper code for a system
|
||||
call. This use is for internal calls that do not need to handle errors
|
||||
normally. It will never touch errno. This returns just what the kernel
|
||||
gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
|
||||
the negation of the return value in the kernel gets reverted. */
|
||||
|
||||
# undef INTERNAL_SYSCALL
|
||||
# define INTERNAL_SYSCALL(name, nr, args...) \
|
||||
({ \
|
||||
register long r0 __asm__ ("r0"); \
|
||||
register long r3 __asm__ ("r3"); \
|
||||
register long r4 __asm__ ("r4"); \
|
||||
register long r5 __asm__ ("r5"); \
|
||||
register long r6 __asm__ ("r6"); \
|
||||
register long r7 __asm__ ("r7"); \
|
||||
register long r8 __asm__ ("r8"); \
|
||||
LOADARGS_##nr(name, args); \
|
||||
__asm__ __volatile__ \
|
||||
("sc\n\t" \
|
||||
"bns+ 0f\n\t" \
|
||||
"neg %1,%1\n" \
|
||||
"0:" \
|
||||
: "=&r" (r0), \
|
||||
"=&r" (r3), "=&r" (r4), "=&r" (r5), \
|
||||
"=&r" (r6), "=&r" (r7), "=&r" (r8) \
|
||||
: ASM_INPUT_##nr \
|
||||
: "r9", "r10", "r11", "r12", \
|
||||
"cr0", "ctr", "memory"); \
|
||||
(int) r3; \
|
||||
})
|
||||
|
||||
# undef INTERNAL_SYSCALL_ERROR_P
|
||||
# define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= 0xfffffffffffff001u)
|
||||
|
||||
# undef INTERNAL_SYSCALL_ERRNO
|
||||
# define INTERNAL_SYSCALL_ERRNO(val) (-(val))
|
||||
|
||||
#define LOADARGS_0(name, dummy) \
|
||||
r0 = __NR_##name
|
||||
#define LOADARGS_1(name, arg1) \
|
||||
LOADARGS_0(name); \
|
||||
LOADARGS_0(name, 0); \
|
||||
extern void __illegally_sized_syscall_##name##_arg1 (void); \
|
||||
if (sizeof (arg1) > 8) __illegally_sized_syscall_##name##_arg1 (); \
|
||||
r3 = (long) (arg1)
|
||||
#define LOADARGS_2(name, arg1, arg2) \
|
||||
LOADARGS_1(name, arg1); \
|
||||
extern void __illegally_sized_syscall_##name##_arg2 (void); \
|
||||
if (sizeof (arg2) > 8) __illegally_sized_syscall_##name##_arg2 (); \
|
||||
r4 = (long) (arg2)
|
||||
#define LOADARGS_3(name, arg1, arg2, arg3) \
|
||||
LOADARGS_2(name, arg1, arg2); \
|
||||
extern void __illegally_sized_syscall_##name##_arg3 (void); \
|
||||
if (sizeof (arg3) > 8) __illegally_sized_syscall_##name##_arg3 (); \
|
||||
r5 = (long) (arg3)
|
||||
#define LOADARGS_4(name, arg1, arg2, arg3, arg4) \
|
||||
LOADARGS_3(name, arg1, arg2, arg3); \
|
||||
extern void __illegally_sized_syscall_##name##_arg4 (void); \
|
||||
if (sizeof (arg4) > 8) __illegally_sized_syscall_##name##_arg4 (); \
|
||||
r6 = (long) (arg4)
|
||||
#define LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
|
||||
LOADARGS_4(name, arg1, arg2, arg3, arg4); \
|
||||
extern void __illegally_sized_syscall_##name##_arg5 (void); \
|
||||
if (sizeof (arg5) > 8) __illegally_sized_syscall_##name##_arg5 (); \
|
||||
r7 = (long) (arg5)
|
||||
#define LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||
LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
|
||||
extern void __illegally_sized_syscall_##name##_arg6 (void); \
|
||||
if (sizeof (arg6) > 8) __illegally_sized_syscall_##name##_arg6 (); \
|
||||
r8 = (long) (arg6)
|
||||
|
||||
#define ASM_INPUT_0 "0" (r0)
|
||||
@ -193,6 +184,4 @@
|
||||
#define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
|
||||
#define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* linux/powerpc/powerpc64/sysdep.h */
|
||||
|
76
sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c
Normal file
76
sysdeps/unix/sysv/linux/powerpc/powerpc64/truncate64.c
Normal file
@ -0,0 +1,76 @@
|
||||
/* Copyright (C) 1997, 1998, 1999, 2000, 2002 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 <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <bp-checks.h>
|
||||
|
||||
#include "kernel-features.h"
|
||||
|
||||
#ifdef __NR_truncate64
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
/* The variable is shared between all wrappers around *truncate64 calls. */
|
||||
int have_no_truncate64;
|
||||
#endif
|
||||
|
||||
|
||||
/* Truncate the file FD refers to to LENGTH bytes. */
|
||||
int
|
||||
truncate64 (path, length)
|
||||
const char *path;
|
||||
off64_t length;
|
||||
{
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if (! have_no_truncate64)
|
||||
#endif
|
||||
{
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
int saved_errno = errno;
|
||||
#endif
|
||||
int result = INLINE_SYSCALL (truncate64, 2, CHECK_STRING (path),
|
||||
length);
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if (result != -1 || errno != ENOSYS)
|
||||
#endif
|
||||
return result;
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
__set_errno (saved_errno);
|
||||
have_no_truncate64 = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __ASSUME_TRUNCATE64_SYSCALL
|
||||
if ((off_t) length != length)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
return truncate (path, (off_t) length);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
/* Use the generic implementation. */
|
||||
# include <sysdeps/generic/truncate64.c>
|
||||
#endif
|
@ -32,6 +32,10 @@
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* These definitions are normally provided by ucontext.h via
|
||||
asm/sigcontext.h, asm/ptrace.h, and asm/elf.h. Otherwise we define
|
||||
them here. */
|
||||
#ifndef __PPC64_ELF_H
|
||||
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
|
||||
#define ELF_NFPREG 33 /* includes fpscr */
|
||||
#define ELF_NVRREG 33 /* includes vscr */
|
||||
@ -41,6 +45,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
#endif
|
||||
|
||||
/* gcc 3.1 and newer support __uint128_t. */
|
||||
#if !__GNUC_PREREQ(3,1)
|
||||
|
@ -66,7 +66,12 @@
|
||||
END (name)
|
||||
|
||||
#ifndef PIC
|
||||
# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
|
||||
# define SYSCALL_ERROR_HANDLER \
|
||||
mov.l 0f,r1; \
|
||||
jmp @r1; \
|
||||
mov r0,r4; \
|
||||
.align 2; \
|
||||
0: .long __syscall_error
|
||||
#else
|
||||
# if RTLD_PRIVATE_ERRNO
|
||||
# define SYSCALL_ERROR_HANDLER \
|
||||
|
Loading…
Reference in New Issue
Block a user