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:
Ulrich Drepper 2003-01-12 10:11:16 +00:00
parent 26a676d0aa
commit aff4519d38
48 changed files with 1580 additions and 249 deletions

116
ChangeLog
View File

@ -1,3 +1,103 @@
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.
@ -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__.

View File

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

View File

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

View File

@ -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,9 +185,12 @@ _dl_close (void *_map)
{
assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
if (--new_opencount[dep_list[j]->l_idx] == 0)
{
assert (dep_list[j]->l_type == lt_loaded);
mark_removed (dep_list[j]);
}
}
}
if (remmap->l_reldeps != NULL)
{
@ -200,11 +203,14 @@ _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. */
assert (remmap->l_reldeps[j]->l_type == lt_loaded);
mark_removed (remmap->l_reldeps[j]);
}
}
}
}
mark_removed (list[i]);
}
@ -215,16 +221,16 @@ _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. */
/* Call its termination function. Do not do it for
half-cooked objects. */
if (imap->l_init_called)
{
if (imap->l_info[DT_FINI_ARRAY] != NULL)
{
ElfW(Addr) *array =
@ -241,31 +247,72 @@ _dl_close (void *_map)
/* 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)) ();
(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;
while (*runp != NULL)
if (*runp == &map->l_searchlist)
/* 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;
#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);
}

View File

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

View File

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

View File

@ -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
View 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
View 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
View File

@ -0,0 +1,3 @@
void baz (void)
{
}

1
elf/reldep9mod3.c Normal file
View File

@ -0,0 +1 @@
int x;

View File

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

View File

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

View File

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

View 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
}

View File

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

View File

@ -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 */

View File

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

View File

@ -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 \
# ifndef __ASSEMBLER__
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
# define NONTLS_INIT_TP \
do { \
static const tcbhead_t nontls_init_tp \
= { .multiple_threads = 0 }; \
__thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
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 */

View File

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

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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

View File

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

View File

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

View File

@ -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...) \
@ -156,7 +98,7 @@
"cr0", "cr1", "cr5", "cr6", "cr7", \
"memory"); \
ret = r3; \
if (err & 1 << 28) \
if (__builtin_expect ((err & (1 << 28)), 0)) \
{ \
__set_errno (ret); \
ret = -1L; \
@ -164,25 +106,74 @@
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 */

View 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

View File

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

View File

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