Updated to fedora-glibc-20050208T0948 fedora-glibc-2_3_4-6
authorjakub <jakub>
Tue, 8 Feb 2005 10:03:48 +0000 (10:03 +0000)
committerjakub <jakub>
Tue, 8 Feb 2005 10:03:48 +0000 (10:03 +0000)
220 files changed:
ChangeLog
Makeconfig
catgets/gencat.c
configure
configure.in
csu/elf-init.c
csu/version.c
debug/catchsegv.sh
debug/chk_fail.c
debug/xtrace.sh
dirent/tst-seekdir.c
dlfcn/Makefile
dlfcn/dlclose.c
dlfcn/dlfcn.c [new file with mode: 0644]
dlfcn/dlmopen.c
dlfcn/dlopen.c
dlfcn/dlopenold.c
elf/Makefile
elf/Versions
elf/dl-close.c
elf/dl-debug.c
elf/dl-fini.c
elf/dl-init.c
elf/dl-libc.c
elf/dl-load.c
elf/dl-object.c
elf/dl-open.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dl-sym.c
elf/dynamic-link.h
elf/ldconfig.c
elf/ldd.bash.in
elf/link.h
elf/rtld.c
elf/sprof.c
elf/tst-align2.c [new file with mode: 0644]
elf/tst-alignmod2.c [new file with mode: 0644]
elf/tst-audit1.c [new file with mode: 0644]
elf/tst-auditmod1.c [new file with mode: 0644]
fedora/branch.mk
fedora/glibc.spec.in
grp/putgrent.c
hurd/sigunwind.c
iconv/iconv_prog.c
iconv/iconvconfig.c
iconv/strtab.c
iconvdata/jis0208.h
include/dlfcn.h
include/link.h
libio/fmemopen.c
libio/iofopncook.c
libio/stdio.h
linuxthreads/ChangeLog
linuxthreads/Makefile
linuxthreads/pthread.c
linuxthreads/specific.c
linuxthreads/sysdeps/alpha/tls.h
linuxthreads/sysdeps/i386/tls.h
linuxthreads/sysdeps/ia64/tls.h
linuxthreads/sysdeps/powerpc/tls.h
linuxthreads/sysdeps/s390/tls.h
linuxthreads/sysdeps/sh/tls.h
linuxthreads/sysdeps/sparc/tls.h
linuxthreads/sysdeps/x86_64/tls.h
linuxthreads/tst-tsd1.c [new file with mode: 0644]
linuxthreads_db/ChangeLog
linuxthreads_db/td_thr_tlsbase.c
locale/programs/locale.c
locale/programs/localedef.c
malloc/malloc.c
malloc/malloc.h
malloc/memusage.sh
malloc/mtrace.pl
manual/.cvsignore
manual/memory.texi
manual/string.texi
manual/users.texi
math/math_private.h
misc/sys/cdefs.h
misc/syslog.c [deleted file]
nptl/ChangeLog
nptl/allocatestack.c
nptl/sysdeps/alpha/tls.h
nptl/sysdeps/generic/lowlevellock.h
nptl/sysdeps/i386/tls.h
nptl/sysdeps/ia64/tls.h
nptl/sysdeps/powerpc/tls.h
nptl/sysdeps/pthread/pthread.h
nptl/sysdeps/s390/tls.h
nptl/sysdeps/sh/tls.h
nptl/sysdeps/sparc/tls.h
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
nptl/sysdeps/x86_64/tls.h
nscd/Makefile
nscd/connections.c
nscd/nscd.c
nscd/nscd.init
nscd/nscd_getai.c
nscd/nscd_helper.c
nscd/nscd_initgroups.c
nscd/nscd_nischeck.c
nss/getent.c
posix/Makefile
posix/bug-regex19.c
posix/execl.c
posix/execle.c
posix/execlp.c
posix/execvp.c
posix/getconf.c
posix/regcomp.c
posix/regex_internal.c
posix/regex_internal.h
posix/regexec.c
posix/rxspencer/tests
posix/tst-rxspencer.c
posix/unistd.h
pwd/putpwent.c
shadow/sgetspent_r.c
stdio-common/tst-fmemopen2.c
stdlib/Makefile
stdlib/fmtmsg.c
stdlib/stdlib.h
stdlib/tst-fmtmsg.c
sunrpc/openchild.c
sunrpc/rpc_main.c
sunrpc/svc_tcp.c
sunrpc/svc_unix.c
sysdeps/alpha/bits/link.h [new file with mode: 0644]
sysdeps/alpha/dl-machine.h
sysdeps/alpha/dl-trampoline.S [new file with mode: 0644]
sysdeps/alpha/fpu/bits/mathinline.h
sysdeps/alpha/libc-tls.c
sysdeps/arm/bits/link.h
sysdeps/arm/bits/linkmap.h [new file with mode: 0644]
sysdeps/generic/bits/link.h
sysdeps/generic/bits/linkmap.h [new file with mode: 0644]
sysdeps/generic/dl-fptr.h
sysdeps/generic/dl-lookupcfg.h
sysdeps/generic/dl-tls.c
sysdeps/generic/dl-trampoline.c [new file with mode: 0644]
sysdeps/generic/ldsodefs.h
sysdeps/generic/libc-start.c
sysdeps/generic/libc-tls.c
sysdeps/generic/syslog.c [new file with mode: 0644]
sysdeps/generic/unsecvars.h
sysdeps/generic/wordexp.c
sysdeps/hppa/bits/link.h
sysdeps/hppa/bits/linkmap.h [new file with mode: 0644]
sysdeps/hppa/dl-lookupcfg.h
sysdeps/i386/Makefile
sysdeps/i386/bits/link.h
sysdeps/i386/bits/linkmap.h [new file with mode: 0644]
sysdeps/i386/dl-machine.h
sysdeps/i386/dl-trampoline.S [new file with mode: 0644]
sysdeps/ia64/bits/link.h
sysdeps/ia64/bits/linkmap.h [new file with mode: 0644]
sysdeps/ia64/dl-lookupcfg.h
sysdeps/ia64/dl-machine.h
sysdeps/ia64/dl-trampoline.S [new file with mode: 0644]
sysdeps/ia64/fpu/e_logl.c [deleted file]
sysdeps/ia64/libc-tls.c
sysdeps/linkmap.h [new file with mode: 0644]
sysdeps/m68k/bits/link.h [new file with mode: 0644]
sysdeps/m68k/dl-machine.h
sysdeps/m68k/dl-trampoline.S [new file with mode: 0644]
sysdeps/mach/hurd/tls.h
sysdeps/powerpc/powerpc32/bits/link.h [new file with mode: 0644]
sysdeps/powerpc/powerpc32/dl-machine.c
sysdeps/powerpc/powerpc32/dl-machine.h
sysdeps/powerpc/powerpc32/dl-trampoline.S [new file with mode: 0644]
sysdeps/powerpc/powerpc64/bits/link.h [new file with mode: 0644]
sysdeps/powerpc/powerpc64/dl-lookupcfg.h
sysdeps/powerpc/powerpc64/dl-machine.h
sysdeps/powerpc/powerpc64/dl-trampoline.S [new file with mode: 0644]
sysdeps/powerpc/tst-stack-align.h [new file with mode: 0644]
sysdeps/s390/bits/link.h
sysdeps/s390/bits/linkmap.h [new file with mode: 0644]
sysdeps/s390/bits/string.h
sysdeps/s390/s390-32/dl-machine.h
sysdeps/s390/s390-32/dl-trampoline.S [new file with mode: 0644]
sysdeps/s390/s390-64/dl-machine.h
sysdeps/s390/s390-64/dl-trampoline.S [new file with mode: 0644]
sysdeps/sh/bits/link.h
sysdeps/sh/bits/linkmap.h [new file with mode: 0644]
sysdeps/sh/dl-machine.h
sysdeps/sh/dl-trampoline.S [new file with mode: 0644]
sysdeps/sh/sh4/Versions [new file with mode: 0644]
sysdeps/sh/sh4/dl-machine.h [deleted file]
sysdeps/sh/sh4/dl-trampoline.S [new file with mode: 0644]
sysdeps/unix/i386/sysdep.S
sysdeps/unix/rewinddir.c
sysdeps/unix/sysv/linux/alpha/oldglob.c
sysdeps/unix/sysv/linux/dl-execstack.c
sysdeps/unix/sysv/linux/futimes.c
sysdeps/unix/sysv/linux/i386/sysdep.h
sysdeps/unix/sysv/linux/init-first.c
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
sysdeps/unix/sysv/linux/syslog.c [new file with mode: 0644]
sysdeps/x86_64/bits/link.h
sysdeps/x86_64/bits/linkmap.h [new file with mode: 0644]
sysdeps/x86_64/dl-machine.h
sysdeps/x86_64/dl-trampoline.S [new file with mode: 0644]
time/strptime_l.c
time/tst-strptime.c
timezone/asia
timezone/backward
timezone/europe
timezone/leapseconds
timezone/northamerica
timezone/private.h
timezone/southamerica
timezone/tzfile.h
timezone/zdump.c
timezone/zic.c

index ab874d8..ba9d876 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,736 @@
+2005-02-07  Richard Henderson  <rth@redhat.com>
+
+       * iconvdata/jis0208.h (struct jisx0208_ucs_idx): Move before use.
+
+2005-02-08  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/dl-machine.h (elf_machine_rela): Remove code using
+       RESOLVE.
+
+2005-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-load.c (_dl_map_object_from_fd): Makre sure registers are
+       set correctly.
+
+2005-01-07  Richard Henderson  <rth@redhat.com>
+
+       * math/math_private.h (__copysign): Define as builtin for gcc 4.
+       (__copysignf, __copysignl): Likewise.
+       * sysdeps/alpha/fpu/bits/mathinline.h (copysign): Don't define
+       for gcc 4.0.
+       (copysignf, copysignl, fabsf, fabs): Likewise.
+       (__copysign, __copysignf, __copysignl): Remove.
+       (__fabs, __fabsf): Remove.
+
+2005-01-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/dl-load.c (open_path): If rtld_search_dirs is in RELRO segment,
+       avoid writing to it if none of the standard search directories exist.
+
+2005-02-07  Steven Munroe  <sjmunroe@us.ibm.com>
+
+       [BZ #700]
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
+       (__novec_setcontext, __setcontext): Fix typo so CCR is restored.
+       Load MSR as a doubleword.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
+       (__novec_swapcontext, __swapcontext): Likewise.
+
+2005-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * iconv/iconv_prog.c (main): Provide more help in case on an error.
+
+       * sysdeps/unix/sysv/linux/i386/sysdep.h (check_consistency): Define.
+
+2005-02-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/nscd.c (termination_handler): Avoid segfault if some database
+       is not enabled.
+
+       * nscd/nscd_getai.c (__nscd_getai): If ai_resp->found == -1, set
+       __nss_not_use_nscd_hosts and return -1.
+       * nscd/nscd_initgroups.c (__nscd_getgrouplist): If
+       initgr_resp->found == -1, set __nss_not_use_nscd_group and return -1.
+       Avoid leaking sockets.
+
+2005-01-28  Andreas Schwab  <schwab@suse.de>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       [BZ #677]
+       * elf/dl-runtime.c (fixup): Change return type to
+       DL_FIXUP_VALUE_TYPE. Use DL_FIXUP_VALUE_TYPE,
+       DL_FIXUP_MAKE_VALUE and DL_FIXUP_VALUE_CODE_ADDR for relocation
+       values. Use DL_FIXUP_VALUE_ADDR and DL_FIXUP_ADDR_VALUE to
+       store and retrieve relocation values.
+       (profile_fixup): Likewise.
+       * include/link.h (link_map): Use DL_FIXUP_VALUE_TYPE for
+       l_reloc_result.
+       * sysdeps/generic/dl-fptr.h (link_map): Forward declaration.
+       * sysdeps/generic/dl-lookupcfg.h (DL_FIXUP_VALUE_TYPE): New.
+       (DL_FIXUP_MAKE_VALUE): Likewise.
+       (DL_FIXUP_VALUE_CODE_ADDR): Likewise.
+       (DL_FIXUP_VALUE_ADDR): Likewise.
+       (DL_FIXUP_ADDR_VALUE): Likewise.
+       * sysdeps/ia64/dl-lookupcfg.h: Include <dl-fptr.h> for "struct fdesc".
+       (DL_FIXUP_VALUE_TYPE): New.
+       (DL_FIXUP_MAKE_VALUE): Likewise.
+       (DL_FIXUP_VALUE_CODE_ADDR): Likewise.
+       (DL_FIXUP_VALUE_ADDR): Likewise.
+       (DL_FIXUP_ADDR_VALUE): Likewise.
+       * sysdeps/ia64/dl-machine.h (elf_machine_profile_fixup_plt): Removed.
+       (elf_machine_profile_plt): Removed.
+       (elf_machine_fixup_plt): Change return type and type of value
+       parameter to struct fdesc.
+       (elf_machine_plt_value): Likewise.
+       (elf_machine_rela): Use DL_FIXUP_MAKE_VALUE to construct
+       argument for elf_machine_fixup_plt.
+
+2005-02-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/nscd.init (reload): Print Reloading nscd: before and a newline
+       after the status string printed by killproc.
+
+2004-11-18  Alexandre Oliva  <aoliva@redhat.com>
+
+       * manual/.cvsignore: Add dir-add.texi.
+
+2005-02-06  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/dl-machine.h (elf_machine_rela): Use RESOLVE_MAP
+       all the time.
+
+2004-11-03  Marcus Brinkmann  <marcus@gnu.org>
+
+       * configure.in (sysnames): Append sysdeps/generic for each add-on.
+       * configure: Regenerated.
+
+2005-02-02  Alfred M. Szmidt  <ams@gnu.org>
+
+       * sysdeps/mach/hurd/tls.h: Include <stdbool.h>
+       (dtv_t): Change pointer type to be a struct which also contains
+       information whether the memory pointed to is static TLS or not.
+
+       * sysdeps/generic/syslog.c (send_flags) [!send_flags]: Define it.
+
+       * shadow/sgetspent_r.c (FALSE): Macro renamed to ...
+       (FALSEP): ... this.  Updated all references.
+
+       * libio/fmemopen.c: Include <stdint.h>.
+
+2005-01-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * nscd/nscd_helper.c (get_mapping): Use MSG_NOSIGNAL if available.
+       * nscd/connections.c (send_ro_fd): Likewise.
+
+2005-01-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf/tst-auditmod1.c: Add ia64 entries.
+       * sysdeps/generic/ldsodefs.h (La_ia64_regs): New.
+       (La_ia64_retval): New.
+       (audit_ifaces): Add ia64 entries.
+       * sysdeps/ia64/bits/link.h: New file.
+       * sysdeps/ia64/dl-machine.h (elf_machine_runtime_setup): Test
+       for dl_profile non-null.
+       (ARCH_LA_PLTENTER): New.
+       (ARCH_LA_PLTEXIT): New.
+       * sysdeps/ia64/dl-trampoline.S (_dl_runtime_resolve): Allocate
+       only 2 output registers. Allocate stack to save/restore
+       8 incoming fp registers. Call _dl_fixup instead of fixup.
+       (_dl_runtime_profile): Rewrite.
+
+2005-01-28  Martin Schwidefsky  <schwidefsky@de.ibm.com>
+
+       * sysdeps/s390/bits/link.h: New file.
+       * sysdeps/s390/s390-32/dl-trampoline.S: New file.
+       * sysdeps/s390/s390-64/dl-trampoline.S: New file.
+       * sysdeps/s390/s390-32/dl-machine.h: Move PLT trampolines to
+       dl-trampoline.S. Use RESOLVE_MAP instead of RESOLVE to protect
+       relocation code.
+       (elf_machine_runtime_setup): Test for dl_profile non-null.
+       (elf_machine_rela): Remove code using RESOLVE.
+       (ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): New.
+       * sysdeps/s390/s390-64/dl-machine.h: Likewise.
+       * sysdeps/generic/ldsodefs.h (La_s390_32_regs, La_s390_32_retval,
+       La_s390_64_regs, La_s390_64_retval): New.
+       * elf/tst-auditmod1.c: Add s390 entries.
+
+       * sysdeps/s390/bits/string.h (strlen, strncpy, strcat, strncat,
+       strncat, memchr, strcmp): Add missing memory clobber.
+
+2005-01-27  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_globfree): Also
+       copy gl_offs.  Patch by Sergey Tikhonov <tsv@solvo.ru>.
+
+2005-01-27  Paolo Bonzini  <bonzini@gnu.org>
+
+       [BZ #558]
+       * posix/regcomp.c (calc_inveclosure): Return reg_errcode_t.
+       Initialize the node sets in dfa->inveclosures.
+       (analyze): Initialize inveclosures only if it is needed.
+       Check errors from calc_inveclosure.
+       * posix/regex_internal.c (re_dfa_add_node): Do not initialize
+       the inveclosure node set.
+       * posix/regexec.c (re_search_internal): If nmatch includes unused
+       subexpressions, reset them to { rm_so: -1, rm_eo: -1 } here.
+
+       * posix/regcomp.c (parse_bracket_exp) [!RE_ENABLE_I18N]:
+       Do build a SIMPLE_BRACKET token.
+
+       * posix/regexec.c (transit_state_mb): Do not examine nodes
+       where ACCEPT_MB is not set.
+
+2005-01-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * stdlib/tst-fmtmsg.c: Include stdlib.h.
+       * stdio-common/tst-fmemopen2.c: Include string.h.
+       * posix/execvp.c: Include stdbool.h.
+
+2004-12-13  Paolo Bonzini  <bonzini@gnu.org>
+
+       Separate parsing and creation of the NFA.  Avoided recursion on
+       the (very unbalanced) parse tree.
+       [BZ #611]
+       * posix/regcomp.c (struct subexp_optimize, analyze_tree, calc_epsdest,
+       re_dfa_add_tree_node, mark_opt_subexp_iter): Removed.
+       (optimize_subexps, duplicate_tree, calc_first, calc_next,
+       mark_opt_subexp): Rewritten.
+       (preorder, postorder, lower_subexps, lower_subexp, link_nfa_nodes,
+       create_token_tree, free_tree, free_token): New.
+       (analyze): Accept a regex_t *.  Invoke the passes via the preorder and
+       postorder generic visitors.  Do not initialize the fields in the
+       re_dfa_t that represent the transitions.
+       (free_dfa_content): Use free_token.
+       (re_compile_internal): Analyze before UTF-8 optimizations.  Do not
+       include optimization of subexpressions.
+       (create_initial_state): Fetch the DFA node index from the first node's
+       bin_tree_t *.
+       (optimize_utf8): Abort on unexpected nodes, including OP_DUP_QUESTION.
+       Return on COMPLEX_BRACKET.
+       (duplicate_node_closure): Fix comment.
+       (duplicate_node): Do not initialize the fields in the
+       re_dfa_t that represent the transitions.
+       (calc_eclosure, calc_inveclosure): Do not handle OP_DELETED_SUBEXP.
+       (create_tree): Remove final argument.  All callers adjusted.  Rewritten
+       to use create_token_tree.
+       (parse_reg_exp, parse_branch, parse_expression, parse_bracket_exp,
+       build_charclass_op): Use create_tree or create_token_tree instead
+       of re_dfa_add_tree_node.
+       (parse_dup_op): Likewise.  Also free the tree using free_tree for
+       "<re>{0}", and lower OP_DUP_QUESTION to OP_ALT: "a?" is equivalent
+       to "a|".  Adjust invocation of mark_opt_subexp.
+       (parse_sub_exp): Create a single SUBEXP node.
+       * posix/regex_internal.c (re_dfa_add_node): Remove last parameter,
+       always perform as if it was 1.  Do not initialize OPT_SUBEXP and
+       DUPLICATED, and initialize the DFA fields representing the transitions.
+       * posix/regex_internal.h (re_dfa_add_node): Adjust prototype.
+       (re_token_type_t): Move OP_DUP_PLUS and OP_DUP_QUESTION to the tokens
+       section.  Add a tree-only code SUBEXP.  Remove OP_DELETED_SUBEXP.
+       (bin_tree_t): Include a full re_token_t for TOKEN.  Turn FIRST and
+       NEXT into pointers to trees.  Remove ECLOSURE.
+
+2004-12-28  Paolo Bonzini  <bonzini@gnu.org >
+
+       [BZ #605]
+       * posix/regcomp.c (parse_bracket_exp): Do not modify DFA nodes
+       that were already created.
+       * posix/regex_internal.c (re_dfa_add_node): Set accept_mb field
+       in the token if needed.
+       (create_ci_newstate, create_cd_newstate): Set accept_mb field
+       from the tokens' field.
+       * posix/regex_internal.h (re_token_t): Add accept_mb field.
+       (ACCEPT_MB_NODE): Removed.
+       * posix/regexec.c (proceed_next_node, transit_states_mb,
+       build_sifted_states, check_arrival_add_next_nodes): Use
+       accept_mb instead of ACCEPT_MB_NODE.
+
+2005-01-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * debug/chk_fail.c (__chk_fail): Print program name in final message.
+
+       * sysdeps/unix/sysv/linux/kernel-features.h: Found reference to
+       MSG_NOSIGNAL being in 2.2 kernels.
+
+2005-01-26  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/sysdep.h
+       (SYSCALL_ERROR_HANDLER_TLS_STORE): Remove unnecessary 0 imm.
+
+       [BZ #693]
+       * posix/regex_internal.h (DUMMY_CONSTRAINT): Rename to...
+       (WORD_DELIM_CONSTRAINT): ...this.
+       (NOT_WORD_DELIM_CONSTRAINT): Define.
+       (re_context_type): Add INSIDE_NOTWORD and NOT_WORD_DELIM,
+       change WORD_DELIM to use WORD_DELIM_CONSTRAINT.
+       * posix/regcomp.c (peek_token): For \B create NOT_WORD_DELIM
+       anchor instead of INSIDE_WORD.
+       (parse_expression): Handle NOT_WORD_DELIM constraint.
+       * posix/bug-regex19.c (tests): Adjust tests that relied on \B
+       being inside word instead of not word delim.
+       * posix/tst-rxspencer.c (mb_frob_pattern): Don't frob escaped
+       characters.
+       * posix/rxspencer/tests: Add some new tests.
+
+2005-01-14  GOTO Masanori  <gotom@debian.or.jp>
+
+       * sunrpc/rpc_main.c (s_output): Generate #include <rpc/pmap_clnt.h>
+       irrespective of Cflag.
+
+       * manual/memory.texi (sbrk): Fix definition.
+       * manual/string.texi (strcasestr): Fix example typo.
+
+2005-01-25  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/generic/syslog.c [NO_SIGPIPE]: Protect sigpipe_handler decl.
+
+2005-01-23  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/i386/Makefile (defines): If -mno-tls-direct-seg-refs appears
+       in $(CFLAGS), add -DNO_TLS_DIRECT_SEG_REFS.
+       * sysdeps/unix/sysv/linux/i386/sysdep.h [USE___THREAD]
+       (SYSCALL_ERROR_HANDLER) [NO_TLS_DIRECT_SEG_REFS]: Load thread pointer
+       from %gs:0 and add to that value, rather that direct %gs:OFFSET access.
+       * sysdeps/unix/i386/sysdep.S [NO_TLS_DIRECT_SEG_REFS]: Likewise.
+
+2005-01-25  Jakub Jelinek  <jakub@redhat.com>
+
+       * stdlib/fmtmsg.c (addseverity): Remove new_string variable.
+       (free_mem): Don't free string.
+       * stdlib/tst-fmtmsg.c: Include string.h.
+       (main): Add some more tests.
+
+2005-01-25  Andreas Schwab  <schwab@suse.de>
+
+       * timezone/asia: Update from tzdata2005c.
+       * timezone/backward: Likewise.
+       * timezone/leapseconds: Likewise.
+       * timezone/northamerica: Likewise.
+       * timezone/southamerica: Likewise.
+
+       * timezone/private.h: Update from tzcode2005c.
+       * timezone/tzfile.h: Likewise.
+       * timezone/zdump.c: Likewise.
+       * timezone/zic.c: Likewise.
+
+2005-01-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/i386/dl-machine.h (elf_machine_rel): Remove code using
+       RESOLVE.
+       * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Remove code
+       using RESOLVE.
+       * elf/rtld.c (_dl_start): Remove RESOLVE definition.
+
+2005-01-25  Alan Modra  <amodra@bigpond.net.au>
+
+       * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): Test
+       sym_map, not sym, against zero.
+
+2005-01-24  Ulrich Drepper  <drepper@redhat.com>
+
+       * misc/syslog.c: Moved to...
+       * sysdeps/generic/syslog.c: ...here.
+       [NO_SIGIPE]: Don't install SIGPIPE handler.
+       * sysdeps/unix/sysv/linux/syslog.c: New file.
+       * sysdeps/unix/sysv/linux/kernel-features.h: Define
+       __ASSUME_MSG_NOSIGNAL.
+
+2005-01-22  Richard Henderson  <rth@redhat.com>
+
+       * sysdeps/alpha/dl-trampoline.S: New file.
+       * sysdeps/alpha/dl-machine.h: Move PLT trampolines there.
+       Use RESOLVE_MAP instead of RESOLVE to protect relocation code.
+       (elf_machine_runtime_setup): Test for dl_profile non-null.
+       (ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): New.
+       * sysdeps/alpha/bits/link.h: New file.
+       * sysdeps/generic/ldsodefs.h (La_alpha_regs, La_alpha_retval): New.
+       (struct audit_ifaces): Add alpha entries.
+       * elf/tst-auditmod1.c: Add alpha entries.
+
+2005-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/ia64/dl-machine.h: Remove PLT trampolines here.
+       * sysdeps/ia64/dl-trampoline.S: New file.
+
+       * sysdeps/x86_64/bits/link.h: Use namespace-safe identifiers in
+       La_x86_64_xmm definition.
+
+       * posix/Makefile: Use CFLAGS-*.os instead of CFLAGS-*.c for frame
+       pointer option.
+       * stdlib/Makefile (CFLAGS-system.os): Use this instead of
+       CFLAGS-system.c for frame pointer option.
+
+2005-01-21  Roland McGrath  <roland@redhat.com>
+
+       * elf/dl-runtime.c (_dl_profile_fixup): Remove const from REGS.
+       * sysdeps/i386/dl-machine.h: Update decl.
+
+2005-01-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/Makefile: Add rules to build and run tst-align2.
+       * elf/tst-align2.c: New test.
+       * elf/tst-alignmod2.c: New file.
+       * sysdeps/powerpc/tst-stack-align.h: New file.
+       * sysdeps/i386/dl-machine.h (RTLD_START): Align stack and clear frame
+       pointer before calling _dl_init.
+       * sysdeps/x86_64/dl-machine.h (RTLD_START): Likewise.
+
+2005-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/execl.c: Do not allocate potentially large buffers on the
+       stack.
+       * posix/execle.c: Likewise.
+       * posix/execlp.c: Likewise.
+       * posix/execlp.c: Likewise.
+       (script_execute): Removed.
+       (allocate_scripts_argv): New function.  Called at most once to
+       allocate memory, not every time a script is run.  Adjust caller.
+
+       * sysdeps/generic/wordexp.c (exec_comm): Add a few
+       TEMP_FAILURE_RETRY.  Reorganize code to avoid multiple calls to
+       exec_comm_child.
+       (exec_comm_child): Can now be inlined.
+
+       * posix/Makefile: Add -fomit-frame-pointer for a few more files.
+       * stdlib/Makefile: Likewise.
+
+2005-01-19  Roland McGrath  <roland@redhat.com>
+
+       [BZ #681]
+       * sunrpc/openchild.c (_openchild): Use NULL instead of 0 for trailing
+       argument to execlp.
+       Reported by Marcus Meissner <meissner@suse.de>.
+
+2005-01-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * hurd/sigunwind.c (_hurdsig_longjmp_from_handler): Fix a typo
+       in assert.
+       * iconv/strtab.c (strtabfinalize): Likewise.
+
+       * libio/iofopncook.c (_IO_cookie_seekoff): Add prototype.
+
+2005-01-17  Roland McGrath  <roland@redhat.com>
+
+       * nscd/Makefile (LDLIBS-nscd): New variable.
+       ($(objpfx)nscd): Use that instead of selinux-LIBS.
+
+       * Makeconfig (link-extra-libs): Define just as $(LDLIBS-$(@F)).
+       (link-extra-libs-static): Define to $(link-extra-libs).
+       (link-extra-libs-bounded): Likewise.
+
+2005-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+       * include/link.h: Remove stray definition of pltenter.
+
+2005-01-16  GOTO Masanori  <gotom@debian.or.jp>
+
+       * sysdeps/unix/rewinddir.c: Reset filepos.
+       * dirent/tst-seekdir.c: Check telldir value after calling rewinddir.
+
+2005-01-15  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/tst-auditmod1.c: Reduce duplication.
+
+2005-01-16  Andreas Schwab  <schwab@suse.de>
+
+       * sysdeps/m68k/dl-machine.h: Remove trampoline code.  Define
+       ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT.
+       (elf_machine_runtime_setup): If profile != 0 does not anymore mean
+       GLRO(dl_profile) != NULL.
+       * sysdeps/m68k/dl-trampoline.S: New file.
+       * sysdeps/m68k/bits/link.h: New file.
+       * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add m68k
+       variants.
+       * elf/tst-auditmod1.c: Add m68k support.
+
+2005-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/regcomp.c [!_LIBC] (init_dfa): Fix determining of relevant
+       LC_* variable.  Patch by Aharon Robbins <arnold@skeeve.com>.
+
+       * stdlib/fmtmsg.c (internal_addseverity): Remove incorrect free call.
+       * stdlib/tst-fmtmsg.c (main): Add another addseverity test.
+
+2005-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-load.c (_dl_map_object_from_fd): We don't have to allow
+       callers from libc anymore.
+
+       * elf/dl-open.c (dl_open_worker): Pass __RTLD_AUDIT flag from caller
+       to _dl_map_object_deps.
+       * elf/dl-load.c (_dl_map_object_from_fd): Don't change memory
+       protections when loading auditing modules.
+
+       * dlfcn/dlopen.c (dlopen_doit): Catch invalid mode arguments and fail.
+
+       * posix/getconf.c: Update copyright year.
+       * nss/getent.c: Likewise.
+       * nscd/nscd_nischeck.c: Likewise.
+       * iconv/iconvconfig.c: Likewise.
+       * iconv/iconv_prog.c: Likewise.
+       * elf/ldconfig.c: Likewise.
+       * catgets/gencat.c: Likewise.
+       * csu/version.c: Likewise.
+       * elf/ldd.bash.in: Likewise.
+       * elf/sprof.c (print_version): Likewise.
+       * locale/programs/locale.c: Likewise.
+       * locale/programs/localedef.c: Likewise.
+       * nscd/nscd.c (print_version): Likewise.
+       * debug/xtrace.sh: Likewise.
+       * malloc/memusage.sh: Likewise.
+       * malloc/mtrace.pl: Likewise.
+       * debug/catchsegv.sh: Likewise.
+
+2005-01-11  Thorsten Kukuk  <kukuk@suse.de>
+
+       * sunrpc/svc_tcp.c (svctcp_create): Call listen with SOMAXCONN
+       as backlog.
+       * sunrpc/svc_unix.c (svcunix_create): Likewise.
+
+       * grp/putgrent.c (putgrent): Don't write 0 as group
+       ID if groupname starts with + or -.
+       * pwd/putpwent.c (putpwent): Don't write 0 as user or
+       group ID if user name starts with + or -.
+
+2005-01-09  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add sh variants.
+       * sysdeps/elf/tst-auditmod1.c: Add sh support.
+       * sysdeps/sh/bits/link.h: New.
+       * sysdeps/sh/dl-machine.h: Remove trampoline code here.  Define
+       ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT.  Remove obsolete comments.
+       (RTLD_START): Define __fpscr_values.
+       * sysdeps/sh/dl-trampoline.S: New file.
+       * sysdeps/sh/sh4/dl-trampoline.S: New file.
+       * sysdeps/sh/sh4/Versions [ld]: Add __fpscr_values.
+       * sysdeps/sh/sh4/dl-machine.h: Remove.
+
+2005-01-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * time/tst-strptime.c (day_tests): Add 2 new tests.
+       (test_tm, main): Issue an error instead of segfaulting if
+       strptime returns NULL.
+
+2005-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * sysdeps/alpha/libc-tls.c (__tls_get_addr): Updated for dtv_t union.
+       * sysdeps/ia64/libc-tls.c (__tls_get_addr): Likewise.
+
+2005-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * malloc/malloc.h: Remove no-glibc support.
+
+2005-01-12  GOTO Masanori  <gotom@debian.or.jp>
+
+       [BZ #650]
+       * malloc/malloc.h: Always include features.h.
+
+2005-01-10  Roland McGrath  <roland@redhat.com>
+
+       * sysdeps/ia64/fpu/e_logl.c: File removed.
+
+       * dlfcn/dlfcn.c (init): Fix typo in attribute decl.
+
+2005-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/generic/dl-tls.c (_dl_next_tls_modid): Fix assertion and
+       recognition of last entry.
+
+2005-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-runtime.c: Include <sys/param.h>.
+
+       * elf/Makefile (headers): Add bits/link.h.
+
+2005-01-09  Andreas Schwab  <schwab@suse.de>
+
+       * elf/rtld.c (dl_main): Create main_map with __RTLD_OPENEXEC.
+
+2005-01-09  Andreas Jaeger  <aj@suse.de>
+
+       * time/strptime_l.c (__strptime_internal): Add braces to avoid
+       warning.
+
+       * sysdeps/x86_64/bits/link.h: Use vector_size for GCC 4.0.
+
+       * elf/rtld.c (dl_main): Call _dl_add_to_slotinfo only if USE_TLS.
+
+2005-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/Makefile (generated): Add tst-pie1{,.out,.o}.
+
+2005-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-fini.c (_dl_fini): Call destructors of audit DSOs after
+       those of all the regular objects.
+
+       * elf/dl-debug.c (_dl_debug_initialize): Take extra parameter and
+       use it to select the r_debug structure for that namespace.
+       * elf/dl-close.c (_dl_close): Adjust call to _dl_debug_initialize.
+       * elf/dl-load.c (_dl_map_object_from_fd): Likewise.
+       * elf/dl-open.c (_dl_open): Likewise.
+       * elf/rtld.c (dl_main): Likewise.
+       * sysdeps/generic/ldsodefs.h (struct link_namespaces): Add _ns_debug
+       member.
+       (_dl_debug_initialize): Add new parameter in declaration.
+
+       * elf/dl-close.c (_dl_close): Make sure auditing callbacks are not
+       called for the auditing objects themselves.
+       * elf/dl-load.c (_dl_map_object_from_fd): Likewise.
+
+2005-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/powerpc/powerpc64/dl-machine.h
+       (elf_machine_runtime_setup): If profile != 0 does not anymore mean
+       GLRO(dl_profile) != NULL.
+       * sysdeps/powerpc/powerpc64/bits/link.h (struct la_ppc64_regs): Add
+       padding.
+       * sysdeps/powerpc/powerpc64/dl-trampoline.S: (_dl_profile_resolve):
+       Extend _dl_prof_resolve to add pass extra parameters to
+       _dl_profile_fixup and set up structure with register content.
+
+       * sysdeps/powerpc/powerpc32/dl-machine.c (__elf_machine_runtime_setup):
+       If profile != 0 does not anymore mean GLRO(dl_profile) != NULL.
+       * sysdeps/powerpc/powerpc32/dl-trampoline.S (_dl_prof_resolve):
+       Extend _dl_prof_resolve to add pass extra parameters to
+       _dl_profile_fixup and set up structure with register content.
+       * sysdeps/powerpc/powerpc32/bits/link.h: Fix types of some fields in
+       the register and result structures.
+       * sysdeps/powerpc/powerpc64/bits/link.h: Fix types of some fields
+       in the 32-bit register and result structures.
+
+       * sysdeps/powerpc/powerpc64/dl-trampoline.S: Use register names.
+
+       * sysdeps/powerpc/powerpc32/dl-trampoline.S: New file.
+       * sysdeps/powerpc/powerpc32/dl-machine.h: Remove trampoline code here.
+       Define ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT.
+       * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add ppc32 variants.
+       * elf/tst-auditmod1.c: Add ppc32 support.
+       * sysdeps/powerpc/powerpc32/bits/link.h: New file.
+       * sysdeps/powerpc/powerpc64/bits/link.h: Add ppc32 definitions.
+
+       * malloc/malloc.c (malloc_printerr): Print program name as part of
+       error message.
+
+       * misc/sys/cdefs.h (__attribute_warn_unused_result__): Define.
+       * stdlib/stdlib.h: Make realloc with
+       __attribute_warn_unused_result__ instead of __wur.
+       * malloc/malloc.h: Add __wur and __attribute_warn_unused_result__
+       markers as in <stdlib.h>.
+
+       * libio/stdio.h: Remove __wur from rename and remove.
+       * posix/unistd.h: Remove __wur from dup2.
+
+2005-01-03  Andreas Jaeger  <aj@suse.de>
+
+       * elf/Makefile (tests): Revert patch from 2005-01-03.
+
+2005-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/init-first.c (__libc_init_first): Don't
+       make __libc_init_first hidden.
+
+       * elf/rtld.c [!DONT_USE_BOOTSTRAP_MAP] (_dl_start_final): Initialize
+       l_relocated of rtld map.
+       * sysdeps/powerpc/powerpc64/dl-trampoline.S: New file.
+       * sysdeps/powerpc/powerpc64/dl-machine.h: Remove trampoline code here.
+       Define ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT.
+       * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add ppc64 variants.
+       * elf/tst-auditmod1.c: Add ppc64 support.
+       * sysdeps/powerpc/powerpc64/bits/link.h: New file.
+
+2005-01-06  Roland McGrath  <roland@redhat.com>
+
+       [BZ #633]
+       * sysdeps/unix/sysv/linux/futimes.c (__futimes): Catch errno values
+       indicating file-name lookup errors, and return ENOSYS or EBADF instead.
+
 2005-01-06  Ulrich Drepper  <drepper@redhat.com>
 
+       * csu/elf-init.c (__libc_csu_fini): Don't do anything here.
+       * sysdeps/generic/libc-start.c: Don't register program destructor here.
+
+       * dlfcn/Makefile: Add rules to build dlfcn.c.
+       (LDFLAGS-dl.so): Removed.
+       * dlfcn/dlclose.c: _dl_close is now in ld.so, use function pointer
+       table.
+       * dlfcn/dlmopen.c: Likewise for _dl_open.
+       * dlfcn/dlopen.c: Likewise.
+       * dlfcn/dlopenold.c: Likewise.
+       * elf/dl-libc.c: Likewise for _dl_open and _dl_close.
+       * elf/Makefile (routines): Remove dl-open and dl-close.
+       (dl-routines): Add dl-open, dl-close, and dl-trampoline.
+       Add rules to build and run tst-audit1.
+       * elf/tst-audit1.c: New file.
+       * elf/tst-auditmod1.c: New file.
+       * elf/Versions [libc]: Remove _dl_open and _dl_close.
+       * elf/dl-close.c: Change for use inside ld.so instead of libc.so.
+       * elf/dl-open.c: Likewise.
+       * elf/dl-debug.c (_dl_debug_initialize): Allow reinitialization,
+       signaled by nonzero parameter.
+       * elf/dl-init.c: Fix use of r_state.
+       * elf/dl-load.c: Likewise.
+
+       * elf/dl-close.c: Add auditing checkpoints.
+       * elf/dl-open.c: Likewise.
+       * elf/dl-fini.c: Likewise.
+       * elf/dl-load.c: Likewise.
+       * elf/dl-sym.c: Likewise.
+       * sysdeps/generic/libc-start.c: Likewise.
+       * elf/dl-object.c: Allocate memory for auditing information.
+       * elf/dl-reloc.c: Remove RESOLV.  We now always need the map.
+       Correctly initialize slotinfo.
+       * elf/dynamic-link.h: Adjust after removal of RESOLV.
+       * sysdeps/hppa/dl-lookupcfg.h: Likewise.
+       * sysdeps/ia64/dl-lookupcfg.h: Likewise.
+       * sysdeps/powerpc/powerpc64/dl-lookupcfg.h: Removed.
+       * elf/dl-runtime.c (_dl_fixup): Little cleanup.
+       (_dl_profile_fixup): New parameters to point to register struct and
+       variable for frame size.
+       Add auditing checkpoints.
+       (_dl_call_pltexit): New function.
+       Don't define trampoline code here.
+       * elf/rtld.c: Recognize LD_AUDIT.  Load modules on startup.
+       Remove all the functions from _rtld_global_ro which only _dl_open
+       and _dl_close needed.
+       Add auditing checkpoints.
+       * elf/link.h: Define symbols for auditing interfaces.
+       * include/link.h: Likewise.
+       * include/dlfcn.h: Define __RTLD_AUDIT.
+       Remove prototypes for _dl_open and _dl_close.
+       Adjust access to argc and argv in libdl.
+       * dlfcn/dlfcn.c: New file.
+       * sysdeps/generic/dl-lookupcfg.h: Remove all content now that RESOLVE
+       is gone.
+       * sysdeps/generic/ldsodefs.h: Add definitions for auditing interfaces.
+       * sysdeps/generic/unsecvars.h: Add LD_AUDIT.
+       * sysdeps/i386/dl-machine.h: Remove trampoline code here.
+       Adjust for removal of RESOLVE.
+       * sysdeps/x86_64/dl-machine.h: Likewise.
+       * sysdeps/generic/dl-trampoline.c: New file.
+       * sysdeps/i386/dl-trampoline.c: New file.
+       * sysdeps/x86_64/dl-trampoline.c: New file.
+
+       * sysdeps/generic/dl-tls.c: Cleanups.  Fixup for dtv_t change.
+       Fix updating of DTV.
+       * sysdeps/generic/libc-tls.c: Likewise.
+
+       * sysdeps/arm/bits/link.h: Renamed to ...
+       * sysdeps/arm/bits/linkmap.h: ...this.
+       * sysdeps/generic/bits/link.h: Renamed to...
+       * sysdeps/generic/bits/linkmap.h: ...this.
+       * sysdeps/hppa/bits/link.h: Renamed to...
+       * sysdeps/hppa/bits/linkmap.h: ...this.
+       * sysdeps/i386/bits/link.h: Renamed to...
+       * sysdeps/i386/bits/linkmap.h: ...this.
+       * sysdeps/ia64/bits/link.h: Renamed to...
+       * sysdeps/ia64/bits/linkmap.h: ...this.
+       * sysdeps/s390/bits/link.h: Renamed to...
+       * sysdeps/s390/bits/linkmap.h: ...this.
+       * sysdeps/sh/bits/link.h: Renamed to...
+       * sysdeps/sh/bits/linkmap.h: ...this.
+       * sysdeps/x86_64/bits/link.h: Renamed to...
+       * sysdeps/x86_64/bits/linkmap.h: ...this.
+
        * posix/unistd.h: Declare ftruncate for POSIX 2003.  [BZ #640]
 
 2004-12-22  Steven Munroe  <sjmunroe@us.ibm.com>
 
 2005-01-05  Ulrich Drepper  <drepper@redhat.com>
 
-       * libio/fmemopen.c (fmemopen_seek): SEEK_END should count from
-       maximum used address, not maximum buffer position.
-
        * libio/iofopncook.c (_IO_cookie_seekoff): Define.  Mark offset as
        invalid to disable optimizations in fileops which won't work here.
        (_IO_cookie_jumps): Use it.
index d267e5a..5ecda01 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1991-2003, 2004, 2005 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
@@ -480,32 +480,21 @@ default-rpath = $(libdir)
 endif
 
 ifndef link-extra-libs
-ifeq (yes,$(build-shared))
-ifneq ($(common-objpfx),$(objpfx))
-link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),\
-       $(wildcard $(common-objpfx)$(lib).so$($(notdir $(lib)).so-version) \
-                  $(objpfx)$(lib).so$($(notdir $(lib)).so-version)))
-else
-link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),$(common-objpfx)$(lib).so$($(notdir $(lib)).so-version))
-endif
-else
-link-extra-libs = $(foreach lib,$(LDLIBS-$(@F)),$(common-objpfx)$(lib).a)
-endif
+link-extra-libs = $(LDLIBS-$(@F))
+link-extra-libs-static = $(link-extra-libs)
+link-extra-libs-bounded = $(link-extra-libs)
 endif
 
 # The static libraries.
 ifeq (yes,$(build-static))
 link-libc-static = $(common-objpfx)libc.a $(static-gnulib) $(common-objpfx)libc.a
-link-extra-libs-static = $(foreach lib,$(LDLIBS-$(@F)),$(common-objpfx)$(lib).a)
 else
 ifeq (yes,$(build-shared))
 # We can try to link the programs with lib*_pic.a...
 link-libc-static = $(static-gnulib) $(common-objpfx)libc_pic.a
-link-extra-libs-static = $(link-extra-libs)
 endif
 endif
 link-libc-bounded = $(common-objpfx)libc_b.a $(gnulib) $(common-objpfx)libc_b.a
-link-extra-libs-bounded = $(foreach lib,$(LDLIBS-$(@F:%-bp=%)),$(common-objpfx)$(lib)_b.a)
 
 ifndef gnulib
 ifneq ($(have-cc-with-libunwind),yes)
index 2f6c81d..3993809 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 1996.
 
@@ -248,7 +248,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
index e10f4b9..1e9e50c 100755 (executable)
--- a/configure
+++ b/configure
@@ -2093,6 +2093,14 @@ for d in $add_ons_pfx ''; do
       done
     done
   done
+  if test -n "$d"; then
+    try="${d}sysdeps/generic"
+    test -n "$enable_debug_configure" &&
+    echo "$0 DEBUG: try $try" >&2
+    if test -d $srcdir/$try; then
+      sysnames="$sysnames $try"
+    fi
+  fi
 done
 IFS="$ac_save_ifs"
 
index 4ad54cf..11f78b0 100644 (file)
@@ -593,6 +593,14 @@ for d in $add_ons_pfx ''; do
       done
     done
   done
+  if test -n "$d"; then
+    try="${d}sysdeps/generic"
+    test -n "$enable_debug_configure" &&
+    echo "$0 DEBUG: try $try" >&2
+    if test -d $srcdir/$try; then
+      sysnames="$sysnames $try"
+    fi
+  fi
 done
 IFS="$ac_save_ifs"
 
index c538627..dbd2a91 100644 (file)
@@ -1,5 +1,5 @@
 /* Startup support for ELF initializers/finalizers in the main executable.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 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
@@ -104,9 +104,13 @@ __libc_csu_init (void)
 #endif
 }
 
+/* This function should not be used anymore.  We run the executable's
+   destructor now just like any other.  We cannot remove the function,
+   though.  */
 void
 __libc_csu_fini (void)
 {
+#if 0
 #ifdef HAVE_INITFINI_ARRAY
   size_t i = __fini_array_end - __fini_array_start;
   while (i-- > 0)
@@ -114,4 +118,5 @@ __libc_csu_fini (void)
 #endif
 
   _fini ();
+#endif
 }
index 1104fa9..606246a 100644 (file)
@@ -25,7 +25,7 @@ static const char __libc_version[] = VERSION;
 
 static const char banner[] =
 "GNU C Library "RELEASE" release version "VERSION", by Roland McGrath et al.\n\
-Copyright (C) 2004 Free Software Foundation, Inc.\n\
+Copyright (C) 2005 Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.\n\
 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
 PARTICULAR PURPOSE.\n\
index 14556f7..f7e79bc 100755 (executable)
@@ -39,7 +39,7 @@ if test $# -eq 0; then
       ;;
     --v | --ve | --ver | --vers | --versi | --versio | --version)
       echo 'catchsegv (GNU libc) @VERSION@'
-      echo 'Copyright (C) 2004 Free Software Foundation, Inc.
+      echo 'Copyright (C) 2005 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 Written by Ulrich Drepper.'
index dc1c3d7..29df08b 100644 (file)
@@ -1,5 +1,4 @@
-
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2005 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
 #include <stdlib.h>
 
 
+extern char **__libc_argv attribute_hidden;
+
 void
 __attribute__ ((noreturn))
 __chk_fail (void)
 {
-  __libc_fatal ("*** buffer overflow detected ***\n");
+  __libc_message (1, "*** buffer overflow detected ***: %s terminated\n",
+                 __libc_argv[0] ?: "<unknown>");
 }
 libc_hidden_def (__chk_fail)
index 4ce8888..811d6ba 100755 (executable)
@@ -1,5 +1,5 @@
 #! @BASH@
-# Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2001-2004, 2005 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@gnu.org>, 1999.
 
@@ -64,7 +64,7 @@ do_version() {
   printf $"Copyright (C) %s Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-" "2004"
+" "2005"
   printf $"Written by %s.
 " "Ulrich Drepper"
   exit 0
index b833c30..43808fe 100644 (file)
@@ -11,8 +11,23 @@ main (int argc, char *argv[])
   int i = 0;
   int result = 0;
   struct dirent *dp;
+  long int save0;
+  long int rewind;
 
   dirp = opendir (".");
+  if (dirp == NULL)
+    {
+      printf ("opendir failed: %m\n");
+      return 1;
+    }
+
+  save0 = telldir (dirp);
+  if (save0 == -1)
+    {
+      printf ("telldir failed: %m\n");
+      result = 1;
+    }
+
   for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp))
     {
       /* save position 3 (after fourth entry) */
@@ -44,6 +59,19 @@ main (int argc, char *argv[])
   for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp))
     printf ("%s\n", dp->d_name);
 
+  /* Check rewinddir */
+  rewinddir (dirp);
+  rewind = telldir (dirp);
+  if (rewind == -1)
+    {
+      printf ("telldir failed: %m\n");
+      result = 1;
+    }
+  else if (save0 != rewind)
+    {
+      printf ("rewinddir didn't reset directory stream\n");
+      result = 1;
+    }
 
   closedir (dirp);
   return result;
index ed20ae5..7b538fe 100644 (file)
@@ -20,8 +20,8 @@ subdir                := dlfcn
 headers                := bits/dlfcn.h dlfcn.h
 extra-libs     := libdl
 libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
-                  dlmopen
-routines       := $(patsubst %,s%,$(libdl-routines))
+                  dlmopen dlfcn
+routines       := $(patsubst %,s%,$(filter-out dlfcn,$(libdl-routines)))
 elide-routines.os := $(routines)
 distribute     := dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
                   defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
@@ -34,7 +34,7 @@ include ../Makeconfig
 
 ifeq ($(versioning),yes)
 libdl-routines += dlopenold
-libdl-shared-only-routines := dlopenold
+libdl-shared-only-routines := dlopenold dlfcn
 endif
 
 ifeq (yes,$(build-shared))
@@ -65,8 +65,6 @@ generated := $(modules-names:=.so)
 
 include ../Rules
 
-LDFLAGS-dl.so = -Wl,-dynamic-linker,$(slibdir)/$(rtld-installed-name)
-
 test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
 $(test-modules): $(objpfx)%.so: $(objpfx)%.os $(common-objpfx)shlib.lds
        $(build-module)
index 3ddedcf..5a344f3 100644 (file)
@@ -19,6 +19,7 @@
    02111-1307 USA.  */
 
 #include <dlfcn.h>
+#include <ldsodefs.h>
 
 #if !defined SHARED && defined IS_IN_libdl
 
@@ -33,7 +34,7 @@ dlclose (void *handle)
 static void
 dlclose_doit (void *handle)
 {
-  _dl_close (handle);
+  GLRO(dl_close) (handle);
 }
 
 int
diff --git a/dlfcn/dlfcn.c b/dlfcn/dlfcn.c
new file mode 100644 (file)
index 0000000..9c0a84a
--- /dev/null
@@ -0,0 +1,33 @@
+/* Load a shared object at run time.
+   Copyright (C) 2005 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 <dlfcn.h>
+
+
+int __dlfcn_argc attribute_hidden;
+char **__dlfcn_argv attribute_hidden;
+
+
+void
+__attribute__ ((constructor))
+init (int argc, char *argv[])
+{
+  __dlfcn_argc = argc;
+  __dlfcn_argv = argv;
+}
index 5fd6543..0a6d47e 100644 (file)
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <libintl.h>
 #include <stddef.h>
+#include <unistd.h>
 #include <ldsodefs.h>
 
 #if !defined SHARED && defined IS_IN_libdl
@@ -61,8 +62,10 @@ dlmopen_doit (void *a)
 # endif
       GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
 
-  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
-                       args->caller, args->nsid);
+  args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
+                            args->caller,
+                            args->nsid, __dlfcn_argc, __dlfcn_argv,
+                            __environ);
 }
 
 
index 6381ffc..bffb512 100644 (file)
@@ -1,5 +1,5 @@
 /* Load a shared object at run time.
-   Copyright (C) 1995,96,97,98,99,2000,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000,2003,2004,2005 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
    02111-1307 USA.  */
 
 #include <dlfcn.h>
+#include <libintl.h>
 #include <stddef.h>
+#include <unistd.h>
+#include <ldsodefs.h>
 
 #if !defined SHARED && defined IS_IN_libdl
 
@@ -56,8 +59,14 @@ dlopen_doit (void *a)
 {
   struct dlopen_args *args = (struct dlopen_args *) a;
 
-  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
-                       args->caller, args->file == NULL ? LM_ID_BASE : NS);
+  if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND
+                    | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE))
+    GLRO(dl_signal_error) (0, NULL, NULL, _("invalid mode parameter"));
+
+  args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
+                            args->caller,
+                            args->file == NULL ? LM_ID_BASE : NS,
+                            __dlfcn_argc, __dlfcn_argv, __environ);
 }
 
 
index 148716c..8dae1c4 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <dlfcn.h>
 #include <stddef.h>
+#include <unistd.h>
+#include <ldsodefs.h>
 
 /* This file is for compatibility with glibc 2.0.  Compile it only if
    versioning is used.  */
@@ -50,8 +52,10 @@ dlopen_doit (void *a)
 {
   struct dlopen_args *args = (struct dlopen_args *) a;
 
-  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
-                       args->caller, args->file == NULL ? LM_ID_BASE : NS);
+  args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
+                            args->caller,
+                            args->file == NULL ? LM_ID_BASE : NS,
+                            __dlfcn_argc, __dlfcn_argv, __environ);
 }
 
 extern void *__dlopen_nocheck (const char *file, int mode);
index 87172d3..47e6ea4 100644 (file)
@@ -20,8 +20,8 @@
 
 subdir         := elf
 
-headers                = elf.h bits/elfclass.h link.h
-routines       = $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
+headers                = elf.h bits/elfclass.h link.h bits/link.h
+routines       = $(dl-routines) dl-support dl-iteratephdr \
                  dl-addr enbl-secure dl-profstub \
                  dl-origin dl-libc dl-sym dl-tsd
 
@@ -30,7 +30,7 @@ routines      = $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
 dl-routines    = $(addprefix dl-,load cache lookup object reloc deps \
                                  runtime error init fini debug misc \
                                  version profile conflict tls origin \
-                                 execstack caller)
+                                 execstack caller open close trampoline)
 all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
 # But they are absent from the shared libc, because that code is in ld.so.
 elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin
@@ -72,7 +72,7 @@ distribute    := rtld-Rules \
                   tst-tlsmod1.c tst-tlsmod2.c tst-tlsmod3.c tst-tlsmod4.c \
                   tst-tlsmod5.c tst-tlsmod6.c tst-tlsmod7.c tst-tlsmod8.c \
                   tst-tlsmod9.c tst-tlsmod10.c tst-tlsmod11.c \
-                  tst-tlsmod12.c tst-tls10.h tst-alignmod.c \
+                  tst-tlsmod12.c tst-tls10.h tst-alignmod.c tst-alignmod2.c \
                   circlemod1.c circlemod1a.c circlemod2.c circlemod2a.c \
                   circlemod3.c circlemod3a.c nodlopenmod2.c \
                   tls-macros.h \
@@ -83,7 +83,8 @@ distribute    := rtld-Rules \
                   tst-array2dep.c tst-piemod1.c \
                   tst-execstack-mod.c tst-dlmodcount.c \
                   check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \
-                  tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c
+                  tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c \
+                  tst-auditmod1.c
 
 CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
@@ -153,8 +154,9 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
         restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
         circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
         tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
-        $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
-        tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3
+        tst-align2 $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
+        tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
+        tst-audit1
 #       reldep9
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
@@ -163,7 +165,7 @@ tests-nodlopen-yes = nodlopen nodlopen2
 tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
 endif
 ifeq (yesyes,$(have-fpie)$(build-shared))
-tests += tst-pie1
+tests: $(objpfx)tst-pie1.out
 endif
 modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
                testobj1_1 failobj constload2 constload3 unloadmod \
@@ -186,9 +188,10 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
                circlemod3 circlemod3a \
                reldep8mod1 reldep8mod2 reldep8mod3 \
                reldep9mod1 reldep9mod2 reldep9mod3 \
-               tst-alignmod $(modules-execstack-$(have-z-execstack)) \
+               tst-alignmod tst-alignmod2 \
+               $(modules-execstack-$(have-z-execstack)) \
                tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
-               tst-dlmopen1mod
+               tst-dlmopen1mod tst-auditmod1
 ifeq (yes,$(have-initfini-array))
 modules-names += tst-array2dep
 endif
@@ -668,9 +671,12 @@ $(objpfx)tst-tls14:  $(objpfx)tst-tlsmod14a.so $(libdl)
 $(objpfx)tst-tls14.out:$(objpfx)tst-tlsmod14b.so
 
 CFLAGS-tst-align.c = $(stack-align-test-flags)
+CFLAGS-tst-align2.c = $(stack-align-test-flags)
 CFLAGS-tst-alignmod.c = $(stack-align-test-flags)
+CFLAGS-tst-alignmod2.c = $(stack-align-test-flags)
 $(objpfx)tst-align: $(libdl)
 $(objpfx)tst-align.out: $(objpfx)tst-alignmod.so
+$(objpfx)tst-align2: $(objpfx)tst-alignmod2.so
 
 ifdef libdl
 $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a
@@ -732,6 +738,8 @@ $(objpfx)tst-pie1: $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so
          -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link) \
          -o $@ $(objpfx)tst-pie1.o $(objpfx)tst-piemod1.so \
          $(common-objpfx)libc_nonshared.a
+
+generated += tst-pie1 tst-pie1.out tst-pie1.o
 endif
 
 check-textrel-CFLAGS = -O -Wall -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
@@ -773,3 +781,6 @@ $(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
 
 $(objpfx)tst-dlmopen3: $(libdl)
 $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
+
+$(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
+tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
index e24b2de..aaacf3e 100644 (file)
@@ -19,7 +19,7 @@ libc {
 %endif
   GLIBC_PRIVATE {
     # functions used in other libraries
-    _dl_open; _dl_close; _dl_addr;
+    _dl_addr;
     _dl_sym; _dl_vsym;
     _dl_open_hook;
     __libc_dlopen_mode; __libc_dlsym; __libc_dlclose;
index c823b17..eb5e805 100644 (file)
@@ -1,5 +1,5 @@
 /* Close a shared object opened by `_dl_open'.
-   Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2002, 2003, 2004, 2005 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
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <bits/libc-lock.h>
 #include <ldsodefs.h>
 #include <sys/types.h>
@@ -99,7 +100,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 
 
 void
-internal_function
 _dl_close (void *_map)
 {
   struct reldep_list
@@ -112,6 +112,7 @@ _dl_close (void *_map)
   } *reldeps = NULL;
   struct link_map **list;
   struct link_map *map = _map;
+  Lmid_t ns = map->l_ns;
   unsigned int i;
   unsigned int *new_opencount;
 #ifdef USE_TLS
@@ -139,8 +140,8 @@ _dl_close (void *_map)
     {
       /* There are still references to this object.  Do nothing more.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
-       GLRO(dl_debug_printf) ("\nclosing file=%s; opencount == %u\n",
-                               map->l_name, map->l_opencount);
+       _dl_debug_printf ("\nclosing file=%s; opencount == %u\n",
+                         map->l_name, map->l_opencount);
 
       /* Decrement the object's reference counter, not the dependencies'.  */
       --map->l_opencount;
@@ -265,16 +266,23 @@ _dl_close (void *_map)
   assert (new_opencount[0] == 0);
 
   /* Call all termination functions at once.  */
+#ifdef SHARED
+  bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing;
+#endif
   for (i = 0; list[i] != NULL; ++i)
     {
       struct link_map *imap = list[i];
+
+      /* All elements must be in the same namespace.  */
+      assert (imap->l_ns == ns);
+
       if (new_opencount[i] == 0 && imap->l_type == lt_loaded
          && (imap->l_flags_1 & DF_1_NODELETE) == 0)
        {
          /* When debugging print a message first.  */
          if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
-           GLRO(dl_debug_printf) ("\ncalling fini: %s [%lu]\n\n",
-                                  imap->l_name, imap->l_ns);
+           _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+                             imap->l_name, ns);
 
          /* Call its termination function.  Do not do it for
             half-cooked objects.  */
@@ -299,6 +307,22 @@ _dl_close (void *_map)
                         + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
            }
 
+#ifdef SHARED
+         /* Auditing checkpoint: we have a new object.  */
+         if (__builtin_expect (do_audit, 0))
+           {
+             struct audit_ifaces *afct = GLRO(dl_audit);
+             for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+               {
+                 if (afct->objclose != NULL)
+                   /* Return value is ignored.  */
+                   (void) afct->objclose (&imap->l_audit[cnt].cookie);
+
+                 afct = afct->next;
+               }
+           }
+#endif
+
          /* This object must not be used anymore.  We must remove the
             reference from the scope.  */
          unsigned int j;
@@ -365,9 +389,30 @@ _dl_close (void *_map)
       assert (imap->l_type == lt_loaded || imap->l_opencount > 0);
     }
 
+#ifdef SHARED
+  /* Auditing checkpoint: we will start deleting objects.  */
+  if (__builtin_expect (do_audit, 0))
+    {
+      struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      /* Do not call the functions for any auditing object.  */
+      if (head->l_auditing == 0)
+       {
+         for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+           {
+             if (afct->activity != NULL)
+               afct->activity (&head->l_audit[cnt].cookie, LA_ACT_DELETE);
+
+             afct = afct->next;
+           }
+       }
+    }
+#endif
+
   /* Notify the debugger we are about to remove some loaded objects.  */
-  _r_debug.r_state = RT_DELETE;
-  GLRO(dl_debug_state) ();
+  struct r_debug *r = _dl_debug_initialize (0, ns);
+  r->r_state = RT_DELETE;
+  _dl_debug_state ();
 
 #ifdef USE_TLS
   size_t tls_free_start;
@@ -389,21 +434,19 @@ _dl_close (void *_map)
          if (__builtin_expect (imap->l_global, 0))
            {
              /* This object is in the global scope list.  Remove it.  */
-             unsigned int cnt
-               = GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
+             unsigned int cnt = GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
 
              do
                --cnt;
-             while (GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt]
-                    != imap);
+             while (GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt] != imap);
 
              /* The object was already correctly registered.  */
              while (++cnt
-                    < GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist)
-               GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt - 1]
-                 = GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt];
+                    < GL(dl_ns)[ns]._ns_main_searchlist->r_nlist)
+               GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt - 1]
+                 = GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt];
 
-             --GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
+             --GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
            }
 
 #ifdef USE_TLS
@@ -412,9 +455,10 @@ _dl_close (void *_map)
            {
              any_tls = true;
 
-             if (! remove_slotinfo (imap->l_tls_modid,
-                                    GL(dl_tls_dtv_slotinfo_list), 0,
-                                    imap->l_init_called))
+             if (GL(dl_tls_dtv_slotinfo_list) != NULL
+                 && ! remove_slotinfo (imap->l_tls_modid,
+                                       GL(dl_tls_dtv_slotinfo_list), 0,
+                                       imap->l_init_called))
                /* All dynamically loaded modules with TLS are unloaded.  */
                GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
 
@@ -499,12 +543,12 @@ _dl_close (void *_map)
          else
            {
 #ifdef SHARED
-             assert (imap->l_ns != LM_ID_BASE);
+             assert (ns != LM_ID_BASE);
 #endif
-             GL(dl_ns)[imap->l_ns]._ns_loaded = imap->l_next;
+             GL(dl_ns)[ns]._ns_loaded = imap->l_next;
            }
 
-         --GL(dl_ns)[imap->l_ns]._ns_nloaded;
+         --GL(dl_ns)[ns]._ns_nloaded;
          if (imap->l_next != NULL)
            imap->l_next->l_prev = imap->l_prev;
 
@@ -579,16 +623,36 @@ _dl_close (void *_map)
   if (any_tls)
     {
       if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
-       __libc_fatal (_("TLS generation counter wrapped!  Please report as described in <http://www.gnu.org/software/libc/bugs.html>."));
+       _dl_fatal_printf ("TLS generation counter wrapped!  Please report as described in <http://www.gnu.org/software/libc/bugs.html>.\n");
 
       if (tls_free_end == GL(dl_tls_static_used))
        GL(dl_tls_static_used) = tls_free_start;
     }
 #endif
 
+#ifdef SHARED
+  /* Auditing checkpoint: we have deleted all objects.  */
+  if (__builtin_expect (do_audit, 0))
+    {
+      struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
+      /* Do not call the functions for any auditing object.  */
+      if (head->l_auditing == 0)
+       {
+         struct audit_ifaces *afct = GLRO(dl_audit);
+         for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+           {
+             if (afct->activity != NULL)
+               afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
+
+             afct = afct->next;
+           }
+       }
+    }
+#endif
+
   /* Notify the debugger those objects are finalized and gone.  */
-  _r_debug.r_state = RT_CONSISTENT;
-  GLRO(dl_debug_state) ();
+  r->r_state = RT_CONSISTENT;
+  _dl_debug_state ();
 
   /* Now we can perhaps also remove the modules for which we had
      dependencies because of symbol lookup.  */
@@ -612,7 +676,6 @@ _dl_close (void *_map)
   /* Release the lock.  */
   __rtld_lock_unlock_recursive (GL(dl_load_lock));
 }
-libc_hidden_def (_dl_close)
 
 
 #ifdef USE_TLS
index bd6ee69..bc7d793 100644 (file)
@@ -1,5 +1,5 @@
 /* Communicate dynamic linker state to the debugger at runtime.
-   Copyright (C) 1996, 1998, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1998,2000,2002,2004,2005 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
@@ -32,20 +32,25 @@ struct r_debug _r_debug;
 
 struct r_debug *
 internal_function
-_dl_debug_initialize (ElfW(Addr) ldbase)
+_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
 {
-  if (_r_debug.r_brk == 0)
+  struct r_debug *r;
+
+  if (ns == LM_ID_BASE)
+    r = &_r_debug;
+  else
+    r = &GL(dl_ns)[ns]._ns_debug;
+
+  if (r->r_brk == 0 || ldbase != 0)
     {
       /* Tell the debugger where to find the map of loaded objects.  */
-      _r_debug.r_version = 1   /* R_DEBUG_VERSION XXX */;
-      _r_debug.r_ldbase = ldbase;
-      // XXX This is problematic.  It means we cannot tell the debugger
-      // XXX about namespaces other than the main one.
-      _r_debug.r_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-      _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state;
+      r->r_version = 1 /* R_DEBUG_VERSION XXX */;
+      r->r_ldbase = ldbase ?: _r_debug.r_ldbase;
+      r->r_map = GL(dl_ns)[ns]._ns_loaded;
+      r->r_brk = (ElfW(Addr)) &_dl_debug_state;
     }
 
-  return &_r_debug;
+  return r;
 }
 
 
index f43f4a0..b328208 100644 (file)
@@ -1,5 +1,5 @@
 /* Call the termination functions of loaded shared objects.
-   Copyright (C) 1995,96,1998-2002,2004 Free Software Foundation, Inc.
+   Copyright (C) 1995,96,1998-2002,2004, 2005 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
@@ -48,12 +48,25 @@ _dl_fini (void)
   /* We run the destructors of the main namespaces last.  As for the
      other namespaces, we pick run the destructors in them in reverse
      order of the namespace ID.  */
+#ifdef SHARED
+  int do_audit = 0;
+ again:
+#endif
   for (Lmid_t cnt = DL_NNS - 1; cnt >= 0; --cnt)
     {
       /* Protect against concurrent loads and unloads.  */
       __rtld_lock_lock_recursive (GL(dl_load_lock));
 
+      unsigned int nmaps = 0;
       unsigned int nloaded = GL(dl_ns)[cnt]._ns_nloaded;
+      /* No need to do anything for empty namespaces or those used for
+        auditing DSOs.  */
+      if (nloaded == 0
+#ifdef SHARED
+         || GL(dl_ns)[cnt]._ns_loaded->l_auditing != do_audit
+#endif
+         )
+       goto out;
 
       /* XXX Could it be (in static binaries) that there is no object
         loaded?  */
@@ -76,6 +89,7 @@ _dl_fini (void)
 
       unsigned int i;
       struct link_map *l;
+      assert (nloaded != 0 || GL(dl_ns)[cnt]._ns_loaded == NULL);
       for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
        /* Do not handle ld.so in secondary namespaces.  */
        if (l == l->l_real)
@@ -90,7 +104,7 @@ _dl_fini (void)
          }
       assert (cnt != LM_ID_BASE || i == nloaded);
       assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
-      unsigned int nmaps = i;
+      nmaps = i;
 
       if (nmaps != 0)
        {
@@ -163,6 +177,7 @@ _dl_fini (void)
         high and will be decremented in this loop.  So we release the
         lock so that some code which might be called from a destructor
         can directly or indirectly access the lock.  */
+    out:
       __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
       /* 'maps' now contains the objects in the right order.  Now call the
@@ -176,38 +191,49 @@ _dl_fini (void)
              /* Make sure nothing happens if we are called twice.  */
              l->l_init_called = 0;
 
-             /* Don't call the destructors for objects we are not
-                supposed to.  */
-             if (l->l_name[0] == '\0' && l->l_type == lt_executable)
-               continue;
-
              /* Is there a destructor function?  */
-             if (l->l_info[DT_FINI_ARRAY] == NULL
-                 && l->l_info[DT_FINI] == NULL)
-               continue;
-
-             /* When debugging print a message first.  */
-             if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
-                                   0))
-               _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
-                                 l->l_name[0] ? l->l_name : rtld_progname,
-                                 cnt);
-
-             /* First see whether an array is given.  */
-             if (l->l_info[DT_FINI_ARRAY] != NULL)
+             if (l->l_info[DT_FINI_ARRAY] != NULL
+                 || l->l_info[DT_FINI] != NULL)
                {
-                 ElfW(Addr) *array =
-                   (ElfW(Addr) *) (l->l_addr
-                                   + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
-                 unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
-                                   / sizeof (ElfW(Addr)));
-                 while (i-- > 0)
-                   ((fini_t) array[i]) ();
+                 /* When debugging print a message first.  */
+                 if (__builtin_expect (GLRO(dl_debug_mask)
+                                       & DL_DEBUG_IMPCALLS, 0))
+                   _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
+                                     l->l_name[0] ? l->l_name : rtld_progname,
+                                     cnt);
+
+                 /* First see whether an array is given.  */
+                 if (l->l_info[DT_FINI_ARRAY] != NULL)
+                   {
+                     ElfW(Addr) *array =
+                       (ElfW(Addr) *) (l->l_addr
+                                       + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
+                     unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
+                                       / sizeof (ElfW(Addr)));
+                     while (i-- > 0)
+                       ((fini_t) array[i]) ();
+                   }
+
+                 /* Next try the old-style destructor.  */
+                 if (l->l_info[DT_FINI] != NULL)
+                   ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
                }
 
-             /* Next try the old-style destructor.  */
-             if (l->l_info[DT_FINI] != NULL)
-               ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
+#ifdef SHARED
+             /* Auditing checkpoint: another object closed.  */
+             if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0))
+               {
+                 struct audit_ifaces *afct = GLRO(dl_audit);
+                 for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+                   {
+                     if (afct->objclose != NULL)
+                       /* Return value is ignored.  */
+                       (void) afct->objclose (&l->l_audit[cnt].cookie);
+
+                     afct = afct->next;
+                   }
+               }
+#endif
            }
 
          /* Correct the previous increment.  */
@@ -215,6 +241,14 @@ _dl_fini (void)
        }
     }
 
+#ifdef SHARED
+  if (! do_audit && GLRO(dl_naudit) > 0)
+    {
+      do_audit = 1;
+      goto again;
+    }
+#endif
+
   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
     _dl_debug_printf ("\nruntime linker statistics:\n"
                      "           final number of relocations: %lu\n"
index e700dff..e7b6757 100644 (file)
@@ -93,7 +93,6 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
 {
   ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
   ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
-  struct r_debug *r;
   unsigned int i;
 
   if (__builtin_expect (GL(dl_initfirst) != NULL, 0))
@@ -120,13 +119,6 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
        ((init_t) addrs[cnt]) (argc, argv, env);
     }
 
-  /* Notify the debugger we have added some objects.  We need to call
-     _dl_debug_initialize in a static program in case dynamic linking has
-     not been used before.  */
-  r = _dl_debug_initialize (0);
-  r->r_state = RT_ADD;
-  _dl_debug_state ();
-
   /* Stupid users forced the ELF specification to be changed.  It now
      says that the dynamic loader is responsible for determining the
      order in which the constructors have to run.  The constructors
@@ -141,10 +133,6 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
   while (i-- > 0)
     call_init (main_map->l_initfini[i], argc, argv, env);
 
-  /* Notify the debugger all new objects are now ready to go.  */
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
-
 #ifndef HAVE_INLINED_SYSCALLS
   /* Finished starting up.  */
   INTUSE(_dl_starting_up) = 0;
index 8a3f542..5e76069 100644 (file)
 #include <stdlib.h>
 #include <ldsodefs.h>
 
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+
+extern char **__environ;
+
 /* The purpose of this file is to provide wrappers around the dynamic
    linker error mechanism (similar to dlopen() et al in libdl) which
    are usable from within libc.  Generally we want to throw away the
@@ -77,7 +82,8 @@ do_dlopen (void *ptr)
 {
   struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
   /* Open and relocate the shared object.  */
-  args->map = _dl_open (args->name, args->mode, NULL, __LM_ID_CALLER);
+  args->map = GLRO(dl_open) (args->name, args->mode, NULL, __LM_ID_CALLER,
+                            __libc_argc, __libc_argv, __environ);
 }
 
 static void
@@ -93,7 +99,7 @@ do_dlsym (void *ptr)
 static void
 do_dlclose (void *ptr)
 {
-  _dl_close ((struct link_map *) ptr);
+  GLRO(dl_close) ((struct link_map *) ptr);
 }
 
 /* This code is to support __libc_dlopen from __libc_dlopen'ed shared
@@ -109,7 +115,7 @@ struct dl_open_hook
 #ifdef SHARED
 extern struct dl_open_hook *_dl_open_hook;
 libc_hidden_proto (_dl_open_hook);
-struct dl_open_hook *_dl_open_hook __attribute__((nocommon));
+struct dl_open_hook *_dl_open_hook __attribute__ ((nocommon));
 libc_hidden_data_def (_dl_open_hook);
 #else
 static void
@@ -119,7 +125,7 @@ do_dlsym_private (void *ptr)
   struct r_found_version vers;
   vers.name = "GLIBC_PRIVATE";
   vers.hidden = 1;
-  /* vers.hash = _dl_elf_hash (version);  */
+  /* vers.hash = _dl_elf_hash (vers.name);  */
   vers.hash = 0x0963cf85;
   vers.filename = NULL;
 
index eb1a791..f307dad 100644 (file)
@@ -1,5 +1,5 @@
 /* Map in a shared object's segments from the file.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005 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
@@ -36,6 +36,7 @@
 #include <dl-osinfo.h>
 #include <stackinfo.h>
 #include <caller.h>
+#include <sysdep.h>
 
 #include <dl-dst.h>
 
@@ -105,13 +106,11 @@ ELF_PREFERRED_ADDRESS_DATA;
 
 
 int __stack_prot attribute_hidden attribute_relro
-  = (PROT_READ|PROT_WRITE
 #if _STACK_GROWS_DOWN && defined PROT_GROWSDOWN
-     |PROT_GROWSDOWN
+  = PROT_GROWSDOWN;
 #elif _STACK_GROWS_UP && defined PROT_GROWSUP
-     |PROT_GROWSUP
+  = PROT_GROWSUP;
 #endif
-     );
 
 
 /* Type for the buffer we put the ELF header and hopefully the program
@@ -827,6 +826,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
   /* Initialize to keep the compiler happy.  */
   const char *errstring = NULL;
   int errval = 0;
+  struct r_debug *r = _dl_debug_initialize (0, nsid);
+  bool make_consistent = false;
 
   /* Get file information.  */
   if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st) < 0, 0))
@@ -835,6 +836,12 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
     call_lose_errno:
       errval = errno;
     call_lose:
+      if (make_consistent)
+       {
+         r->r_state = RT_CONSISTENT;
+         _dl_debug_state ();
+       }
+
       lose (errval, fd, name, realname, l, errstring);
     }
 
@@ -905,6 +912,39 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
     }
 #endif
 
+  /* Signal that we are going to add new objects.  */
+  if (r->r_state == RT_CONSISTENT)
+    {
+#ifdef SHARED
+      /* Auditing checkpoint: we are going to add new objects.  */
+      if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+       {
+         struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
+         /* Do not call the functions for any auditing object.  */
+         if (head->l_auditing == 0)
+           {
+             struct audit_ifaces *afct = GLRO(dl_audit);
+             for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+               {
+                 if (afct->activity != NULL)
+                   afct->activity (&head->l_audit[cnt].cookie, LA_ACT_ADD);
+
+                 afct = afct->next;
+               }
+           }
+       }
+#endif
+
+      /* Notify the debugger we have added some objects.  We need to
+        call _dl_debug_initialize in a static program in case dynamic
+        linking has not been used before.  */
+      r->r_state = RT_ADD;
+      _dl_debug_state ();
+      make_consistent = true;
+    }
+  else
+    assert (r->r_state == RT_ADD);
+
   /* Enter the new object in the list of loaded objects.  */
   l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
   if (__builtin_expect (l == NULL, 0))
@@ -1044,7 +1084,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
            }
 
 # ifdef SHARED
-         if (l->l_prev == NULL)
+         if (l->l_prev == NULL || (mode && __RTLD_AUDIT) != 0)
            /* We are loading the executable itself when the dynamic linker
               was executed directly.  The setup will happen later.  */
            break;
@@ -1318,21 +1358,25 @@ cannot allocate TLS data structures for initial thread");
         protection of the variable which contains the flags used in
         the mprotect calls.  */
 #ifdef HAVE_Z_RELRO
-      if (mode & __RTLD_DLOPEN)
+      if ((mode & (__RTLD_DLOPEN | __RTLD_AUDIT)) == __RTLD_DLOPEN)
        {
          uintptr_t p = ((uintptr_t) &__stack_prot) & ~(GLRO(dl_pagesize) - 1);
          size_t s = (uintptr_t) &__stack_prot - p + sizeof (int);
 
          __mprotect ((void *) p, s, PROT_READ|PROT_WRITE);
          if (__builtin_expect (__check_caller (RETURN_ADDRESS (0),
-                                               allow_ldso|allow_libc) == 0,
+                                               allow_ldso) == 0,
                                0))
-           __stack_prot |= PROT_EXEC;
+           __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
          __mprotect ((void *) p, s, PROT_READ);
        }
       else
 #endif
-       __stack_prot |= PROT_EXEC;
+       __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
+
+#ifdef check_consistency
+      check_consistency ();
+#endif
 
       errval = (*GL(dl_make_stack_executable_hook)) (stack_endp);
       if (errval)
@@ -1424,6 +1468,27 @@ cannot enable executable stack as shared object requires");
     add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
                            + l->l_info[DT_SONAME]->d_un.d_val));
 
+#ifdef SHARED
+  /* Auditing checkpoint: we have a new object.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0)
+      && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
+    {
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+       {
+         if (afct->objopen != NULL)
+           {
+             l->l_audit[cnt].bindflags
+               = afct->objopen (l, nsid, &l->l_audit[cnt].cookie);
+
+             l->l_audit_any_plt |= l->l_audit[cnt].bindflags != 0;
+           }
+
+         afct = afct->next;
+       }
+    }
+#endif
+
   return l;
 }
 \f
@@ -1471,7 +1536,8 @@ print_search_path (struct r_search_path_elem **list,
    this could mean there is something wrong in the installation and the
    user might want to know about this.  */
 static int
-open_verify (const char *name, struct filebuf *fbp)
+open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
+            int whatcode)
 {
   /* This is the expected ELF header.  */
 #define ELF32_CLASS ELFCLASS32
@@ -1500,13 +1566,34 @@ open_verify (const char *name, struct filebuf *fbp)
     ElfW(Word) type;
     char vendor[4];
   } expected_note = { 4, 16, 1, "GNU" };
-  int fd;
   /* Initialize it to make the compiler happy.  */
   const char *errstring = NULL;
   int errval = 0;
 
+#ifdef SHARED
+  /* Give the auditing libraries a chance.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0) && whatcode != 0
+      && loader->l_auditing == 0)
+    {
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+       {
+         if (afct->objsearch != NULL)
+           {
+             name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
+                                     whatcode);
+             if (name == NULL)
+               /* Ignore the path.  */
+               return -1;
+           }
+
+         afct = afct->next;
+       }
+    }
+#endif
+
   /* Open the file.  We always open files read-only.  */
-  fd = __open (name, O_RDONLY);
+  int fd = __open (name, O_RDONLY);
   if (fd != -1)
     {
       ElfW(Ehdr) *ehdr;
@@ -1664,7 +1751,7 @@ open_verify (const char *name, struct filebuf *fbp)
 static int
 open_path (const char *name, size_t namelen, int preloaded,
           struct r_search_path_struct *sps, char **realname,
-          struct filebuf *fbp)
+          struct filebuf *fbp, struct link_map *loader, int whatcode)
 {
   struct r_search_path_elem **dirs = sps->dirs;
   char *buf;
@@ -1708,12 +1795,16 @@ open_path (const char *name, size_t namelen, int preloaded,
          if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
            _dl_debug_printf ("  trying file=%s\n", buf);
 
-         fd = open_verify (buf, fbp);
+         fd = open_verify (buf, fbp, loader, whatcode);
          if (this_dir->status[cnt] == unknown)
            {
              if (fd != -1)
                this_dir->status[cnt] = existing;
-             else
+             /* Do not update the directory information when loading
+                auditing code.  We must try to disturb the program as
+                little as possible.  */
+             else if (loader == NULL
+                      || GL(dl_ns)[loader->l_ns]._ns_loaded->l_audit == 0)
                {
                  /* We failed to open machine dependent library.  Let's
                     test whether there is any directory at all.  */
@@ -1731,7 +1822,7 @@ open_path (const char *name, size_t namelen, int preloaded,
            }
 
          /* Remember whether we found any existing directory.  */
-         here_any |= this_dir->status[cnt] == existing;
+         here_any |= this_dir->status[cnt] != nonexisting;
 
          if (fd != -1 && __builtin_expect (preloaded, 0)
              && INTUSE(__libc_enable_secure))
@@ -1788,7 +1879,12 @@ open_path (const char *name, size_t namelen, int preloaded,
         must not be freed using the general free() in libc.  */
       if (sps->malloced)
        free (sps->dirs);
-      sps->dirs = (void *) -1;
+#ifdef HAVE_Z_RELRO
+      /* rtld_search_dirs is attribute_relro, therefore avoid writing
+        into it.  */
+      if (sps != &rtld_search_dirs)
+#endif
+       sps->dirs = (void *) -1;
     }
 
   return -1;
@@ -1847,6 +1943,32 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
                              loader->l_name[0]
                              ? loader->l_name : rtld_progname, loader->l_ns);
 
+#ifdef SHARED
+  /* Give the auditing libraries a chance to change the name before we
+     try anything.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0)
+      && (loader == NULL || loader->l_auditing == 0))
+    {
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+       {
+         if (afct->objsearch != NULL)
+           {
+             name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
+                                     LA_SER_ORIG);
+             if (name == NULL)
+               {
+                 /* Do not try anything further.  */
+                 fd = -1;
+                 goto no_file;
+               }
+           }
+
+         afct = afct->next;
+       }
+    }
+#endif
+
   if (strchr (name, '/') == NULL)
     {
       /* Search for NAME in several places.  */
@@ -1867,7 +1989,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
          for (l = loader; fd == -1 && l; l = l->l_loader)
            if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
              fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
-                             &realname, &fb);
+                             &realname, &fb, loader, LA_SER_RUNPATH);
 
          /* If dynamically linked, try the DT_RPATH of the executable
              itself.  NB: we do this for lookups in any namespace.  */
@@ -1877,21 +1999,24 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
              if (l && l->l_type != lt_loaded && l != loader
                  && cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
                fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
-                               &realname, &fb);
+                               &realname, &fb, loader ?: l, LA_SER_RUNPATH);
            }
        }
 
       /* Try the LD_LIBRARY_PATH environment variable.  */
       if (fd == -1 && env_path_list.dirs != (void *) -1)
        fd = open_path (name, namelen, preloaded, &env_path_list,
-                       &realname, &fb);
+                       &realname, &fb,
+                       loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
+                       LA_SER_LIBPATH);
 
       /* Look at the RUNPATH information for this binary.  */
       if (fd == -1 && loader != NULL
          && cache_rpath (loader, &loader->l_runpath_dirs,
                          DT_RUNPATH, "RUNPATH"))
        fd = open_path (name, namelen, preloaded,
-                       &loader->l_runpath_dirs, &realname, &fb);
+                       &loader->l_runpath_dirs, &realname, &fb, loader,
+                       LA_SER_RUNPATH);
 
       if (fd == -1
          && (__builtin_expect (! preloaded, 1)
@@ -1939,7 +2064,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 
              if (cached != NULL)
                {
-                 fd = open_verify (cached, &fb);
+                 fd = open_verify (cached,
+                                   &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+                                   LA_SER_CONFIG);
                  if (__builtin_expect (fd != -1, 1))
                    {
                      realname = local_strdup (cached);
@@ -1959,7 +2086,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
              || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
          && rtld_search_dirs.dirs != (void *) -1)
        fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
-                       &realname, &fb);
+                       &realname, &fb, l, LA_SER_DEFAULT);
 
       /* Add another newline when we are tracing the library loading.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
@@ -1975,12 +2102,16 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
        fd = -1;
       else
        {
-         fd = open_verify (realname, &fb);
+         fd = open_verify (realname, &fb,
+                           loader ?: GL(dl_ns)[nsid]._ns_loaded, 0);
          if (__builtin_expect (fd, 0) == -1)
            free (realname);
        }
     }
 
+#ifdef SHARED
+ no_file:
+#endif
   /* In case the LOADER information has only been provided to get to
      the appropriate RUNPATH/RPATH information we do not need it
      anymore.  */
index b46ebdc..86f7a8e 100644 (file)
@@ -39,14 +39,24 @@ _dl_new_object (char *realname, const char *libname, int type,
   size_t libname_len = strlen (libname) + 1;
   struct link_map *new;
   struct libname_list *newname;
+#ifdef SHARED
+  /* We create the map for the executable before we know whether we have
+     auditing libraries and if yes, how many.  Assume the worst.  */
+  unsigned int naudit = GLRO(dl_naudit) ?: ((mode & __RTLD_OPENEXEC)
+                                           ? DL_NNS : 0);
+  size_t audit_space = naudit * sizeof (new->l_audit[0]);
+#else
+# define audit_space 0
+#endif
 
-  new = (struct link_map *) calloc (sizeof (*new) + sizeof (*newname)
-                                   + libname_len, 1);
+  new = (struct link_map *) calloc (sizeof (*new) + audit_space
+                                   + sizeof (*newname) + libname_len, 1);
   if (new == NULL)
     return NULL;
 
   new->l_real = new;
-  new->l_libname = newname = (struct libname_list *) (new + 1);
+  new->l_libname = newname = (struct libname_list *) ((char *) (new + 1)
+                                                     + audit_space);
   newname->name = (char *) memcpy (newname + 1, libname, libname_len);
   /* newname->next = NULL;     We use calloc therefore not necessary.  */
   newname->dont_free = 1;
@@ -59,6 +69,14 @@ _dl_new_object (char *realname, const char *libname, int type,
 #endif
   new->l_ns = nsid;
 
+#ifdef SHARED
+  for (unsigned int cnt = 0; cnt < naudit; ++cnt)
+    {
+      new->l_audit[cnt].cookie = (uintptr_t) new;
+      /* new->l_audit[cnt].bindflags = 0; */
+    }
+#endif
+
   /* new->l_global = 0;        We use calloc therefore not necessary.  */
 
   /* Use the 'l_scope_mem' array by default for the the 'l_scope'
index 7e890ad..4de2072 100644 (file)
@@ -1,5 +1,5 @@
 /* Load a shared object at runtime, relocate it, and run its initializer.
-   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 2005 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
@@ -49,11 +49,6 @@ weak_extern (BP_SYM (_dl_sysdep_start))
 
 extern int __libc_multiple_libcs;      /* Defined in init-first.c.  */
 
-extern int __libc_argc attribute_hidden;
-extern char **__libc_argv attribute_hidden;
-
-extern char **__environ;
-
 /* Undefine the following for debugging.  */
 /* #define SCOPE_DEBUG 1 */
 #ifdef SCOPE_DEBUG
@@ -74,6 +69,10 @@ struct dl_open_args
   struct link_map *map;
   /* Namespace ID.  */
   Lmid_t nsid;
+  /* Original parameters to the program and the current environment.  */
+  int argc;
+  char **argv;
+  char **env;
 };
 
 
@@ -115,8 +114,8 @@ add_to_global (struct link_map *new)
        {
          GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
        nomem:
-         GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
-                                N_("cannot extend global scope"));
+         _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
+                           N_("cannot extend global scope"));
          return 1;
        }
 
@@ -171,13 +170,14 @@ dl_open_worker (void *a)
   int lazy;
   unsigned int i;
 #ifdef USE_TLS
-  bool any_tls;
+  bool any_tls = false;
 #endif
   struct link_map *call_map = NULL;
 
   /* Check whether _dl_open() has been called from a valid DSO.  */
-  if (__check_caller (args->caller_dl_open, allow_libc|allow_libdl) != 0)
-    GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
+  if (__check_caller (args->caller_dl_open,
+                     allow_libc|allow_libdl|allow_ldso) != 0)
+    _dl_signal_error (0, "dlopen", NULL, N_("invalid caller"));
 
   /* Determine the caller's map if necessary.  This is needed in case
      we have a DST, when we don't know the namespace ID we have to put
@@ -218,6 +218,8 @@ dl_open_worker (void *a)
        }
     }
 
+  assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
+
   /* Maybe we have to expand a DST.  */
   if (__builtin_expect (dst != NULL, 0))
     {
@@ -226,10 +228,10 @@ dl_open_worker (void *a)
       char *new_file;
 
       /* DSTs must not appear in SUID/SGID programs.  */
-      if (__libc_enable_secure)
+      if (INTUSE(__libc_enable_secure))
        /* This is an error.  */
-       GLRO(dl_signal_error) (0, "dlopen", NULL,
-                              N_("DST not allowed in SUID/SGID programs"));
+       _dl_signal_error (0, "dlopen", NULL,
+                         N_("DST not allowed in SUID/SGID programs"));
 
 
       /* Determine how much space we need.  We have to allocate the
@@ -244,8 +246,8 @@ dl_open_worker (void *a)
 
       /* If the substitution failed don't try to load.  */
       if (*new_file == '\0')
-       GLRO(dl_signal_error) (0, "dlopen", NULL,
-                              N_("empty dynamic string token substitution"));
+       _dl_signal_error (0, "dlopen", NULL,
+                         N_("empty dynamic string token substitution"));
 
       /* Now we have a new file name.  */
       file = new_file;
@@ -256,8 +258,8 @@ dl_open_worker (void *a)
     }
 
   /* Load the named object.  */
-  args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
-                                        mode | __RTLD_CALLMAP, args->nsid);
+  args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0,
+                                   mode | __RTLD_CALLMAP, args->nsid);
 
   /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
      set and the object is not already loaded.  */
@@ -279,8 +281,8 @@ dl_open_worker (void *a)
     {
       /* Let the user know about the opencount.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
-       GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
-                              new->l_name, new->l_ns, new->l_opencount);
+       _dl_debug_printf ("opening file=%s [%lu]; opencount=%u\n\n",
+                         new->l_name, new->l_ns, new->l_opencount);
 
       /* If the user requested the object to be in the global namespace
         but it is not so far, add it now.  */
@@ -296,23 +298,50 @@ dl_open_worker (void *a)
        /* Increment just the reference counter of the object.  */
        ++new->l_opencount;
 
+      assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
+
       return;
     }
 
   /* Load that object's dependencies.  */
-  GLRO(dl_map_object_deps) (new, NULL, 0, 0,
-                           mode & (__RTLD_DLOPEN | RTLD_DEEPBIND));
+  _dl_map_object_deps (new, NULL, 0, 0,
+                      mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));
 
   /* So far, so good.  Now check the versions.  */
   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
     if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
-      (void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i]->l_real,
-                                         0, 0);
+      (void) _dl_check_map_versions (new->l_searchlist.r_list[i]->l_real,
+                                    0, 0);
 
 #ifdef SCOPE_DEBUG
   show_scope (new);
 #endif
 
+#ifdef SHARED
+  /* Auditing checkpoint: we have added all objects.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+    {
+      struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
+      /* Do not call the functions for any auditing object.  */
+      if (head->l_auditing == 0)
+       {
+         struct audit_ifaces *afct = GLRO(dl_audit);
+         for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+           {
+             if (afct->activity != NULL)
+               afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
+
+             afct = afct->next;
+           }
+       }
+    }
+#endif
+
+  /* Notify the debugger all new objects are now ready to go.  */
+  struct r_debug *r = _dl_debug_initialize (0, args->nsid);
+  r->r_state = RT_CONSISTENT;
+  _dl_debug_state ();
+
   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
   lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GLRO(dl_lazy);
 
@@ -336,12 +365,12 @@ dl_open_worker (void *a)
                 start the profiling.  */
              struct link_map *old_profile_map = GL(dl_profile_map);
 
-             GLRO(dl_relocate_object) (l, l->l_scope, 1, 1);
+             _dl_relocate_object (l, l->l_scope, 1, 1);
 
              if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
                {
                  /* We must prepare the profiling.  */
-                 GLRO(dl_start_profile) ();
+                 _dl_start_profile ();
 
                  /* Prevent unloading the object.  */
                  GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
@@ -349,7 +378,7 @@ dl_open_worker (void *a)
            }
          else
 #endif
-           GLRO(dl_relocate_object) (l, l->l_scope, lazy, 0);
+           _dl_relocate_object (l, l->l_scope, lazy, 0);
        }
 
       if (l == new)
@@ -357,22 +386,6 @@ dl_open_worker (void *a)
       l = l->l_prev;
     }
 
-#ifdef USE_TLS
-  /* Do static TLS initialization now if it has been delayed because
-     the TLS template might not be fully relocated at _dl_allocate_static_tls
-     time.  */
-  for (l = new; l; l = l->l_next)
-    if (l->l_need_tls_init)
-      {
-       l->l_need_tls_init = 0;
-       GL(dl_init_static_tls) (l);
-      }
-
-  /* We normally don't bump the TLS generation counter.  There must be
-     actually a need to do this.  */
-  any_tls = false;
-#endif
-
   /* Increment the open count for all dependencies.  If the file is
      not loaded as a dependency here add the search list of the newly
      loaded object to the scope.  */
@@ -412,8 +425,8 @@ dl_open_worker (void *a)
                newp = (struct r_scope_elem **)
                  malloc (new_size * sizeof (struct r_scope_elem *));
                if (newp == NULL)
-                 GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL,
-                                        N_("cannot create scope list"));
+                 _dl_signal_error (ENOMEM, "dlopen", NULL,
+                                   N_("cannot create scope list"));
                imap->l_scope = memcpy (newp, imap->l_scope,
                                        cnt * sizeof (imap->l_scope[0]));
              }
@@ -423,8 +436,8 @@ dl_open_worker (void *a)
                  realloc (imap->l_scope,
                           new_size * sizeof (struct r_scope_elem *));
                if (newp == NULL)
-                 GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL,
-                                        N_("cannot create scope list"));
+                 _dl_signal_error (ENOMEM, "dlopen", NULL,
+                                   N_("cannot create scope list"));
                imap->l_scope = newp;
              }
 
@@ -441,76 +454,35 @@ dl_open_worker (void *a)
                                  > 0, 0))
       {
        /* Now that we know the object is loaded successfully add
-          modules containing TLS data to the dtv info table.  We
+          modules containing TLS data to the slot info table.  We
           might have to increase its size.  */
-       struct dtv_slotinfo_list *listp;
-       struct dtv_slotinfo_list *prevp;
-       size_t idx = new->l_searchlist.r_list[i]->l_tls_modid;
-
-       assert (new->l_searchlist.r_list[i]->l_type == lt_loaded);
+       _dl_add_to_slotinfo (new->l_searchlist.r_list[i]);
 
-       /* Find the place in the dtv slotinfo list.  */
-       listp = GL(dl_tls_dtv_slotinfo_list);
-       prevp = NULL;           /* Needed to shut up gcc.  */
-       do
+       if (new->l_searchlist.r_list[i]->l_need_tls_init)
          {
-           /* Does it fit in the array of this list element?  */
-           if (idx < listp->len)
-             break;
-           idx -= listp->len;
-           prevp = listp;
-           listp = listp->next;
+           new->l_searchlist.r_list[i]->l_need_tls_init = 0;
+# ifdef SHARED
+           /* Update the slot information data for at least the
+              generation of the DSO we are allocating data for.  */
+           _dl_update_slotinfo (new->l_searchlist.r_list[i]->l_tls_modid);
+# endif
+
+           GL(dl_init_static_tls) (new->l_searchlist.r_list[i]);
+           assert (new->l_searchlist.r_list[i]->l_need_tls_init == 0);
          }
-       while (listp != NULL);
-
-       if (listp == NULL)
-         {
-           /* When we come here it means we have to add a new element
-              to the slotinfo list.  And the new module must be in
-              the first slot.  */
-           assert (idx == 0);
-
-           listp = prevp->next = (struct dtv_slotinfo_list *)
-             malloc (sizeof (struct dtv_slotinfo_list)
-                     + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
-           if (listp == NULL)
-             {
-               /* We ran out of memory.  We will simply fail this
-                  call but don't undo anything we did so far.  The
-                  application will crash or be terminated anyway very
-                  soon.  */
-
-               /* We have to do this since some entries in the dtv
-                  slotinfo array might already point to this
-                  generation.  */
-               ++GL(dl_tls_generation);
-
-               GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL, N_("\
-cannot create TLS data structures"));
-             }
-
-           listp->len = TLS_SLOTINFO_SURPLUS;
-           listp->next = NULL;
-           memset (listp->slotinfo, '\0',
-                   TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
-         }
-
-       /* Add the information into the slotinfo data structure.  */
-       listp->slotinfo[idx].map = new->l_searchlist.r_list[i];
-       listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
 
        /* We have to bump the generation counter.  */
        any_tls = true;
       }
 
   /* Bump the generation number if necessary.  */
-  if (any_tls)
-    if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
-      __libc_fatal (_("TLS generation counter wrapped!  Please report this."));
+  if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
+    _dl_fatal_printf (N_("\
+TLS generation counter wrapped!  Please report this."));
 #endif
 
   /* Run the initializer functions of new objects.  */
-  GLRO(dl_init) (new, __libc_argc, __libc_argv, __environ);
+  _dl_init (new, args->argc, args->argv, args->env);
 
   /* Now we can make the new map available in the global scope.  */
   if (mode & RTLD_GLOBAL)
@@ -532,14 +504,14 @@ cannot create TLS data structures"));
 
   /* Let the user know about the opencount.  */
   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
-    GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
-                          new->l_name, new->l_ns, new->l_opencount);
+    _dl_debug_printf ("opening file=%s [%lu]; opencount=%u\n\n",
+                     new->l_name, new->l_ns, new->l_opencount);
 }
 
 
 void *
-internal_function
-_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
+_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
+         int argc, char *argv[], char *env[])
 {
   struct dl_open_args args;
   const char *objname;
@@ -548,8 +520,7 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
 
   if ((mode & RTLD_BINDING_MASK) == 0)
     /* One of the flags must be set.  */
-    GLRO(dl_signal_error) (EINVAL, file, NULL,
-                          N_("invalid mode for dlopen()"));
+    _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()"));
 
   /* Make sure we are alone.  */
   __rtld_lock_lock_recursive (GL(dl_load_lock));
@@ -566,16 +537,20 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
          /* No more namespace available.  */
          __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
-         GLRO(dl_signal_error) (EINVAL, file, NULL, N_("\
+         _dl_signal_error (EINVAL, file, NULL, N_("\
 no more namespaces available for dlmopen()"));
        }
+
+      _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT;
     }
   /* Never allow loading a DSO in a namespace which is empty.  Such
-     direct placements is only causing problems.  */
+     direct placements is only causing problems.  Also don't allow
+     loading into a namespace used for auditing.  */
   else if (nsid != LM_ID_BASE && nsid != __LM_ID_CALLER
-          && GL(dl_ns)[nsid]._ns_nloaded == 0)
-    GLRO(dl_signal_error) (EINVAL, file, NULL,
-                          N_("invalid target namespace in dlmopen()"));
+          && (GL(dl_ns)[nsid]._ns_nloaded == 0
+              || GL(dl_ns)[nsid]._ns_loaded->l_auditing))
+    _dl_signal_error (EINVAL, file, NULL,
+                     N_("invalid target namespace in dlmopen()"));
 
   args.file = file;
   args.mode = mode;
@@ -583,11 +558,14 @@ no more namespaces available for dlmopen()"));
   args.caller_dl_open = RETURN_ADDRESS (0);
   args.map = NULL;
   args.nsid = nsid;
-  errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
+  args.argc = argc;
+  args.argv = argv;
+  args.env = env;
+  errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args);
 
 #ifndef MAP_COPY
   /* We must munmap() the cache file.  */
-  GLRO(dl_unload_cache) ();
+  _dl_unload_cache ();
 #endif
 
   /* Release the lock.  */
@@ -603,21 +581,22 @@ no more namespaces available for dlmopen()"));
         state if relocation failed, for example.  */
       if (args.map)
        {
-         unsigned int i;
-
          /* Increment open counters for all objects since this
             sometimes has not happened yet.  */
          if (args.map->l_searchlist.r_list[0]->l_opencount == 0)
-           for (i = 0; i < args.map->l_searchlist.r_nlist; ++i)
+           for (unsigned int i = 0; i < args.map->l_searchlist.r_nlist; ++i)
              ++args.map->l_searchlist.r_list[i]->l_opencount;
 
 #ifdef USE_TLS
-         /* Maybe some of the modules which were loaded uses TLS.
+         /* Maybe some of the modules which were loaded use TLS.
             Since it will be removed in the following _dl_close call
-            we have to mark the dtv array as having gaps to fill
-            the holes.  This is a pessimistic assumption which won't
-            hurt if not true.  */
-         GL(dl_tls_dtv_gaps) = true;
+            we have to mark the dtv array as having gaps to fill the
+            holes.  This is a pessimistic assumption which won't hurt
+            if not true.  There is no need to do this when we are
+            loading the auditing DSOs since TLS has not yet been set
+            up.  */
+         if ((mode & __RTLD_AUDIT) == 0)
+           GL(dl_tls_dtv_gaps) = true;
 #endif
 
          _dl_close (args.map);
@@ -639,20 +618,23 @@ no more namespaces available for dlmopen()"));
          memcpy (local_errstring, errstring, len_errstring);
        }
 
-      if (errstring != _dl_out_of_memory)
+      if (errstring != INTUSE(_dl_out_of_memory))
        free ((char *) errstring);
 
+      assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
+
       /* Reraise the error.  */
-      GLRO(dl_signal_error) (errcode, objname, NULL, local_errstring);
+      _dl_signal_error (errcode, objname, NULL, local_errstring);
     }
 
+  assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
+
 #ifndef SHARED
   DL_STATIC_INIT (args.map);
 #endif
 
   return args.map;
 }
-libc_hidden_def (_dl_open)
 
 
 #ifdef SCOPE_DEBUG
index 4004316..b680683 100644 (file)
@@ -48,8 +48,6 @@ void
 internal_function __attribute_noinline__
 _dl_allocate_static_tls (struct link_map *map)
 {
-  size_t offset;
-
   /* If the alignment requirements are too high fail.  */
   if (map->l_tls_align > GL(dl_tls_static_align))
     {
@@ -71,15 +69,15 @@ cannot allocate memory in static TLS block"));
 
   n = (freebytes - blsize) / map->l_tls_align;
 
-  offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
-                                    - map->l_tls_firstbyte_offset);
+  size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
+                                           - map->l_tls_firstbyte_offset);
 
   map->l_tls_offset = GL(dl_tls_static_used) = offset;
 # elif TLS_DTV_AT_TP
   size_t used;
   size_t check;
 
-  offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
+  size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
   used = offset + map->l_tls_blocksize;
   check = used;
   /* dl_tls_static_used includes the TCB at the beginning.  */
@@ -93,8 +91,20 @@ cannot allocate memory in static TLS block"));
 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 # endif
 
-  if (map->l_relocated)
-    GL(dl_init_static_tls) (map);
+  /* If the object is not yet relocated we cannot initialize the
+     static TLS region.  Delay it.  */
+  if (map->l_real->l_relocated)
+    {
+#ifdef SHARED
+      if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
+                           0))
+       /* Update the slot information data for at least the generation of
+          the DSO we are allocating data for.  */
+       (void) _dl_update_slotinfo (map->l_tls_modid);
+#endif
+
+      GL(dl_init_static_tls) (map);
+    }
   else
     map->l_need_tls_init = 1;
 }
@@ -114,7 +124,8 @@ _dl_nothread_init_static_tls (struct link_map *map)
 # endif
 
   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
-  THREAD_DTV ()[map->l_tls_modid].pointer = dest;
+  THREAD_DTV ()[map->l_tls_modid].pointer.val = dest;
+  THREAD_DTV ()[map->l_tls_modid].pointer.is_static = true;
 
   /* Initialize the memory.  */
   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
@@ -137,11 +148,17 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   /* Initialize it to make the compiler happy.  */
   const char *errstring = NULL;
 
+#ifdef SHARED
+  /* If we are auditing, install the same handlers we need for profiling.  */
+  consider_profiling |= GLRO(dl_audit) != NULL;
+#endif
+
   if (l->l_relocated)
     return;
 
   /* If DT_BIND_NOW is set relocate all references in this object.  We
      do not do this if we are profiling, of course.  */
+  // XXX Correct for auditing?
   if (!consider_profiling
       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
     lazy = 0;
@@ -225,29 +242,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
             l->l_lookup_cache.ret = (*ref);                                  \
             l->l_lookup_cache.value = _lr; }))                               \
      : l)
-#define RESOLVE(ref, version, r_type) \
-    (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL                            \
-     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)               \
-        && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
-               ? (bump_num_cache_relocations (),                             \
-          (*ref) = l->l_lookup_cache.ret,                                    \
-          l->l_lookup_cache.value)                                           \
-       : ({ lookup_t _lr;                                                    \
-            int _tc = elf_machine_type_class (r_type);                       \
-            l->l_lookup_cache.type_class = _tc;                              \
-            l->l_lookup_cache.sym = (*ref);                                  \
-            const struct r_found_version *v = NULL;                          \
-            int flags = DL_LOOKUP_ADD_DEPENDENCY;                            \
-            if ((version) != NULL && (version)->hash != 0)                   \
-              {                                                              \
-                v = (version);                                               \
-                flags = 0;                                                   \
-              }                                                              \
-            _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref),   \
-                                       scope, v, _tc, flags, NULL);          \
-            l->l_lookup_cache.ret = (*ref);                                  \
-            l->l_lookup_cache.value = _lr; }))                               \
-     : l->l_addr)
 
     /* This macro is used as a callback from elf_machine_rel{a,} when a
        static TLS reloc is about to be performed.  Since (in dl-load.c) we
@@ -276,20 +270,19 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
           will be NULL.  */
        if (l->l_info[DT_PLTRELSZ] == NULL)
          {
-           errstring = N_("%s: profiler found no PLTREL in object %s\n");
+           errstring = N_("%s: no PLTREL found in object %s\n");
          fatal:
            _dl_fatal_printf (errstring,
                              rtld_progname ?: "<program name unknown>",
                              l->l_name);
          }
 
-       l->l_reloc_result =
-         (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)),
-                                l->l_info[DT_PLTRELSZ]->d_un.d_val);
+       l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]),
+                                   l->l_info[DT_PLTRELSZ]->d_un.d_val);
        if (l->l_reloc_result == NULL)
          {
            errstring = N_("\
-%s: profiler out of memory shadowing PLTREL of %s\n");
+%s: out of memory to store relocation results for %s\n");
            goto fatal;
          }
       }
index a0aecda..f92cbe2 100644 (file)
@@ -1,5 +1,5 @@
 /* On-demand PLT fixup for shared objects.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002,2003,2004,2005 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
@@ -22,6 +22,7 @@
 #include <alloca.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/param.h>
 #include <ldsodefs.h>
 #include "dynamic-link.h"
 
    function.  */
 
 #ifndef ELF_MACHINE_NO_PLT
-static ElfW(Addr)
-__attribute ((used, noinline)) ARCH_FIXUP_ATTRIBUTE
-fixup (
+DL_FIXUP_VALUE_TYPE
+__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
+_dl_fixup (
 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
-        ELF_MACHINE_RUNTIME_FIXUP_ARGS,
+          ELF_MACHINE_RUNTIME_FIXUP_ARGS,
 # endif
-       /* GKM FIXME: Fix trampoline to pass bounds so we can do
-          without the `__unbounded' qualifier.  */
-       struct link_map *__unbounded l, ElfW(Word) reloc_offset)
+          /* GKM FIXME: Fix trampoline to pass bounds so we can do
+             without the `__unbounded' qualifier.  */
+          struct link_map *__unbounded l, ElfW(Word) reloc_offset)
 {
   const ElfW(Sym) *const symtab
     = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
@@ -70,7 +71,7 @@ fixup (
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
   lookup_t result;
-  ElfW(Addr) value;
+  DL_FIXUP_VALUE_TYPE value;
 
   /* Sanity check that we're really looking at a PLT relocation.  */
   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
@@ -80,8 +81,6 @@ fixup (
   if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
     {
       const struct r_found_version *version = NULL;
-      // XXX Why exactly do we have the differentiation of the flags here?
-      int flags = DL_LOOKUP_ADD_DEPENDENCY;
 
       if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
        {
@@ -91,8 +90,6 @@ fixup (
          version = &l->l_versions[ndx];
          if (version->hash == 0)
            version = NULL;
-         else
-           flags = 0;
        }
 
       result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
@@ -102,16 +99,16 @@ fixup (
       /* Currently result contains the base load address (or link map)
         of the object that defines sym.  Now add in the symbol
         offset.  */
-      value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
+      value = DL_FIXUP_MAKE_VALUE (result,
+                                  sym ? LOOKUP_VALUE_ADDRESS (result)
+                                        + sym->st_value : 0);
     }
   else
     {
       /* We already found the symbol.  The module (and therefore its load
         address) is also known.  */
-      value = l->l_addr + sym->st_value;
-#ifdef DL_LOOKUP_RETURNS_MAP
+      value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + sym->st_value);
       result = l;
-#endif
     }
 
   /* And now perhaps the relocation addend.  */
@@ -127,45 +124,45 @@ fixup (
 
 #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
 
-static ElfW(Addr)
-__attribute ((used, noinline)) ARCH_FIXUP_ATTRIBUTE
-profile_fixup (
+DL_FIXUP_VALUE_TYPE
+__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
+_dl_profile_fixup (
 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
-       ELF_MACHINE_RUNTIME_FIXUP_ARGS,
+                  ELF_MACHINE_RUNTIME_FIXUP_ARGS,
 #endif
-       struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
+                  struct link_map *l, ElfW(Word) reloc_offset,
+                  ElfW(Addr) retaddr, void *regs, long int *framesizep)
 {
   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
-  ElfW(Addr) *resultp;
-  lookup_t result;
-  ElfW(Addr) value;
 
   /* This is the address in the array where we store the result of previous
      relocations.  */
-  resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+  struct reloc_result *reloc_result
+    = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+  DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
 
-  value = *resultp;
-  if (value == 0)
+  DL_FIXUP_VALUE_TYPE value = *resultp;
+  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
     {
       /* This is the first time we have to relocate this object.  */
       const ElfW(Sym) *const symtab
        = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
-      const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+      const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
 
       const PLTREL *const reloc
        = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
-      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+      const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+      const ElfW(Sym) *defsym = refsym;
+      lookup_t result;
 
       /* Sanity check that we're really looking at a PLT relocation.  */
       assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
 
       /* Look up the target symbol.  If the symbol is marked STV_PROTECTED
         don't look in the global scope.  */
-      if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+      if (__builtin_expect (ELFW(ST_VISIBILITY) (refsym->st_other), 0) == 0)
        {
          const struct r_found_version *version = NULL;
-         // XXX Why exactly do we have the differentiation of the flags here?
-         int flags = DL_LOOKUP_ADD_DEPENDENCY;
 
          if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
            {
@@ -175,11 +172,9 @@ profile_fixup (
              version = &l->l_versions[ndx];
              if (version->hash == 0)
                version = NULL;
-             else
-               flags = 0;
            }
 
-         result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
+         result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym,
                                        l->l_scope, version,
                                        ELF_RTYPE_CLASS_PLT,
                                        DL_LOOKUP_ADD_DEPENDENCY, NULL);
@@ -187,26 +182,188 @@ profile_fixup (
          /* Currently result contains the base load address (or link map)
             of the object that defines sym.  Now add in the symbol
             offset.  */
-         value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0);
+         value = DL_FIXUP_MAKE_VALUE (result,
+                                      defsym != NULL
+                                      ? LOOKUP_VALUE_ADDRESS (result)
+                                        + defsym->st_value : 0);
        }
       else
        {
          /* We already found the symbol.  The module (and therefore its load
             address) is also known.  */
-         value = l->l_addr + sym->st_value;
-#ifdef DL_LOOKUP_RETURNS_MAP
+         value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value);
          result = l;
-#endif
        }
       /* And now perhaps the relocation addend.  */
       value = elf_machine_plt_value (l, reloc, value);
 
+#ifdef SHARED
+      /* Auditing checkpoint: we have a new binding.  Provide the
+        auditing libraries the possibility to change the value and
+        tell us whether further auditing is wanted.  */
+      if (defsym != NULL && GLRO(dl_naudit) > 0)
+       {
+         reloc_result->bound = result;
+         /* Compute index of the symbol entry in the symbol table of
+            the DSO with the definition.  */
+         reloc_result->boundndx = (defsym
+                                   - (ElfW(Sym) *) D_PTR (result,
+                                                          l_info[DT_SYMTAB]));
+
+         /* Determine whether any of the two participating DSOs is
+            interested in auditing.  */
+         if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
+           {
+             unsigned int altvalue = 0;
+             struct audit_ifaces *afct = GLRO(dl_audit);
+             /* Synthesize a symbol record where the st_value field is
+                the result.  */
+             ElfW(Sym) sym = *defsym;
+             sym.st_value = DL_FIXUP_VALUE_ADDR (value);
+
+             /* Keep track whether there is any interest in tracing
+                the call in the lower two bits.  */
+             assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
+             assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
+             reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
+
+             const char *strtab2 = (const void *) D_PTR (result,
+                                                         l_info[DT_STRTAB]);
+
+             for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+               {
+                 /* XXX Check whether both DSOs must request action or
+                    only one */
+                 if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0
+                     && (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0)
+                   {
+                     unsigned int flags = altvalue;
+                     if (afct->symbind != NULL)
+                       {
+                         uintptr_t new_value
+                           = afct->symbind (&sym, reloc_result->boundndx,
+                                            &l->l_audit[cnt].cookie,
+                                            &result->l_audit[cnt].cookie,
+                                            &flags,
+                                            strtab2 + defsym->st_name);
+                         if (new_value != (uintptr_t) sym.st_value)
+                           {
+                             altvalue = LA_SYMB_ALTVALUE;
+                             sym.st_value = new_value;
+                           }
+                       }
+
+                     /* Remember the results for every audit library and
+                        store a summary in the first two bits.  */
+                     reloc_result->enterexit
+                       &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
+                     reloc_result->enterexit
+                       |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
+                           << ((cnt + 1) * 2));
+                   }
+                 else
+                   /* If the bind flags say this auditor is not interested,
+                      set the bits manually.  */
+                   reloc_result->enterexit
+                     |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
+                         << ((cnt + 1) * 2));
+
+                 afct = afct->next;
+               }
+
+             reloc_result->flags = altvalue;
+             value = DL_FIXUP_ADDR_VALUE (sym.st_value);
+           }
+         else
+           /* Set all bits since this symbol binding is not interesting.  */
+           reloc_result->enterexit = (1u << DL_NNS) - 1;
+       }
+#endif
+
       /* Store the result for later runs.  */
       if (__builtin_expect (! GLRO(dl_bind_not), 1))
        *resultp = value;
     }
 
-  (*mcount_fct) (retaddr, value);
+  /* By default we do not call the pltexit function.  */
+  long int framesize = -1;
+
+#ifdef SHARED
+  /* Auditing checkpoint: report the PLT entering and allow the
+     auditors to change the value.  */
+  if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
+      /* Don't do anything if no auditor wants to intercept this call.  */
+      && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
+    {
+      ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
+                                               l_info[DT_SYMTAB])
+                          + reloc_result->boundndx);
+
+      /* Set up the sym parameter.  */
+      ElfW(Sym) sym = *defsym;
+      sym.st_value = DL_FIXUP_VALUE_ADDR (value);
+
+      /* Get the symbol name.  */
+      const char *strtab = (const void *) D_PTR (reloc_result->bound,
+                                                l_info[DT_STRTAB]);
+      const char *symname = strtab + sym.st_name;
+
+      /* Keep track of overwritten addresses.  */
+      unsigned int altvalue = reloc_result->flags;
+
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+       {
+         if (afct->ARCH_LA_PLTENTER != NULL
+             && (reloc_result->enterexit
+                 & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
+           {
+             unsigned int flags = altvalue;
+             long int new_framesize = -1;
+             uintptr_t new_value
+               = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
+                                         &l->l_audit[cnt].cookie,
+                                         &reloc_result->bound->l_audit[cnt].cookie,
+                                         regs, &flags, symname,
+                                         &new_framesize);
+             if (new_value != (uintptr_t) sym.st_value)
+               {
+                 altvalue = LA_SYMB_ALTVALUE;
+                 sym.st_value = new_value;
+               }
+
+             /* Remember the results for every audit library and
+                store a summary in the first two bits.  */
+             reloc_result->enterexit
+               |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
+                   << (2 * (cnt + 1)));
+
+             if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
+                                             << (2 * (cnt + 1))))
+                 == 0 && new_framesize != -1 && framesize != -2)
+               {
+                 /* If this is the first call providing information,
+                    use it.  */
+                 if (framesize == -1)
+                   framesize = new_framesize;
+                 /* If two pltenter calls provide conflicting information,
+                    use the larger value.  */
+                 else if (new_framesize != framesize)
+                   framesize = MAX (new_framesize, framesize);
+               }
+           }
+
+         afct = afct->next;
+       }
+
+      value = DL_FIXUP_ADDR_VALUE (sym.st_value);
+    }
+#endif
+
+  /* Store the frame size information.  */
+  *framesizep = framesize;
+
+  (*mcount_fct) (retaddr, DL_FIXUP_VALUE_CODE_ADDR (value));
 
   return value;
 }
@@ -214,9 +371,45 @@ profile_fixup (
 #endif /* PROF && ELF_MACHINE_NO_PLT */
 
 
-/* This macro is defined in dl-machine.h to define the entry point called
-   by the PLT.  The `fixup' function above does the real work, but a little
-   more twiddling is needed to get the stack right and jump to the address
-   finally resolved.  */
+#include <stdio.h>
+void
+ARCH_FIXUP_ATTRIBUTE
+_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset,
+                 const void *inregs, void *outregs)
+{
+#ifdef SHARED
+  /* This is the address in the array where we store the result of previous
+     relocations.  */
+  // XXX Maybe the bound information must be stored on the stack since
+  // XXX with bind_not a new value could have been stored in the meantime.
+  struct reloc_result *reloc_result
+    = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+  ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
+                                           l_info[DT_SYMTAB])
+                      + reloc_result->boundndx);
+
+  /* Set up the sym parameter.  */
+  ElfW(Sym) sym = *defsym;
+
+  /* Get the symbol name.  */
+  const char *strtab = (const void *) D_PTR (reloc_result->bound,
+                                            l_info[DT_STRTAB]);
+  const char *symname = strtab + sym.st_name;
+
+  struct audit_ifaces *afct = GLRO(dl_audit);
+  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+    {
+      if (afct->ARCH_LA_PLTEXIT != NULL
+         && (reloc_result->enterexit
+             & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
+       {
+         afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
+                                &l->l_audit[cnt].cookie,
+                                &reloc_result->bound->l_audit[cnt].cookie,
+                                inregs, outregs, symname);
+       }
 
-ELF_MACHINE_RUNTIME_TRAMPOLINE
+      afct = afct->next;
+    }
+#endif
+}
index ba00ef5..ca83daf 100644 (file)
@@ -116,14 +116,69 @@ RTLD_NEXT used in code not dynamically loaded"));
 
   if (ref != NULL)
     {
+      void *value;
+
 #if defined USE_TLS && defined SHARED
       if (ELFW(ST_TYPE) (ref->st_info) == STT_TLS)
        /* The found symbol is a thread-local storage variable.
           Return the address for to the current thread.  */
-       return _dl_tls_symaddr (result, ref);
+       value = _dl_tls_symaddr (result, ref);
+      else
+#endif
+       value = DL_SYMBOL_ADDRESS (result, ref);
+
+#ifdef SHARED
+      /* Auditing checkpoint: we have a new binding.  Provide the
+        auditing libraries the possibility to change the value and
+        tell us whether further auditing is wanted.  */
+      if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+       {
+         const char *strtab = (const char *) D_PTR (result,
+                                                    l_info[DT_STRTAB]);
+         /* Compute index of the symbol entry in the symbol table of
+            the DSO with the definition.  */
+         unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
+                                                        l_info[DT_SYMTAB]));
+
+         if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
+           {
+             unsigned int altvalue = 0;
+             struct audit_ifaces *afct = GLRO(dl_audit);
+             /* Synthesize a symbol record where the st_value field is
+                the result.  */
+             ElfW(Sym) sym = *ref;
+             sym.st_value = (ElfW(Addr)) value;
+
+             for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+               {
+                 if (afct->symbind != NULL
+                     && ((match->l_audit[cnt].bindflags & LA_FLG_BINDFROM)
+                         != 0
+                         || ((result->l_audit[cnt].bindflags & LA_FLG_BINDTO)
+                             != 0)))
+                   {
+                     unsigned int flags = altvalue | LA_SYMB_DLSYM;
+                     uintptr_t new_value
+                       = afct->symbind (&sym, ndx,
+                                        &match->l_audit[cnt].cookie,
+                                        &result->l_audit[cnt].cookie,
+                                        &flags, strtab + ref->st_name);
+                     if (new_value != (uintptr_t) sym.st_value)
+                       {
+                         altvalue = LA_SYMB_ALTVALUE;
+                         sym.st_value = new_value;
+                       }
+                   }
+
+                 afct = afct->next;
+               }
+
+             value = (void *) sym.st_value;
+           }
+       }
 #endif
 
-      return DL_SYMBOL_ADDRESS (result, ref);
+      return value;
     }
 
   return NULL;
index f9559dc..5118144 100644 (file)
@@ -20,7 +20,7 @@
 #include <elf.h>
 #include <assert.h>
 
-#ifdef RESOLVE
+#ifdef RESOLVE_MAP
 /* We pass reloc_addr as a pointer to void, as opposed to a pointer to
    ElfW(Addr), because not all architectures can assume that the
    relocated address is properly aligned, whereas the compiler is
@@ -64,7 +64,7 @@ elf_machine_lazy_rel (struct link_map *map,
 
 
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
-#ifndef RESOLVE
+#ifndef RESOLVE_MAP
 static
 #else
 auto
@@ -199,7 +199,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 #endif
 }
 
-#ifdef RESOLVE
+#ifdef RESOLVE_MAP
 
 # ifdef RTLD_BOOTSTRAP
 #  define ELF_DURING_STARTUP (1)
index f8504fb..70f3a8f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -279,7 +279,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"),
           "Andreas Jaeger");
 }
index 4d7c33c..4587efd 100644 (file)
@@ -1,5 +1,5 @@
 #! @BASH@
-# Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1996-2004, 2005 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 @@ while test $# -gt 0; do
     printf $"Copyright (C) %s Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-" "2004"
+" "2005"
     printf $"Written by %s and %s.
 " "Roland McGrath" "Ulrich Drepper"
     exit 0
index 6d5ad9d..fdda019 100644 (file)
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2001, 2004, 2005 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,6 +33,7 @@
 #define _ElfW_1(e,w,t) e##w##t
 
 #include <bits/elfclass.h>             /* Defines __ELF_NATIVE_CLASS.  */
+#include <bits/link.h>
 
 /* Rendezvous structure used by the run-time dynamic linker to communicate
    details of shared object loading to the debugger.  If the executable's
@@ -94,6 +95,47 @@ struct link_map
 
 #ifdef __USE_GNU
 
+/* Version numbers for la_version handshake interface.  */
+#define LAV_CURRENT    1
+
+/* Activity types signaled through la_activity.  */
+enum
+  {
+    LA_ACT_CONSISTENT,         /* Link map consistent again.  */
+    LA_ACT_ADD,                        /* New object will be added.  */
+    LA_ACT_DELETE              /* Objects will be removed.  */
+  };
+
+/* Values representing origin of name for dynamic loading.  */
+enum
+  {
+    LA_SER_ORIG = 0x01,                /* Original name.  */
+    LA_SER_LIBPATH = 0x02,     /* Directory from LD_LIBRARY_PATH.  */
+    LA_SER_RUNPATH = 0x04,     /* Directory from RPATH/RUNPATH.  */
+    LA_SER_CONFIG = 0x08,      /* Found through ldconfig.  */
+    LA_SER_DEFAULT = 0x40,     /* Default directory.  */
+    LA_SER_SECURE = 0x80       /* Unused.  */
+  };
+
+/* Values for la_objopen return value.  */
+enum
+  {
+    LA_FLG_BINDTO = 0x01,      /* Audit symbols bound to this object.  */
+    LA_FLG_BINDFROM = 0x02     /* Audit symbols bound from this object.  */
+  };
+
+/* Values for la_symbind flags parameter.  */
+enum
+  {
+    LA_SYMB_NOPLTENTER = 0x01, /* la_pltenter will not be called.  */
+    LA_SYMB_NOPLTEXIT = 0x02,  /* la_pltexit will not be called.  */
+    LA_SYMB_STRUCTCALL = 0x04, /* Return value is a structure.  */
+    LA_SYMB_DLSYM = 0x08,      /* Binding due to dlsym call.  */
+    LA_SYMB_ALTVALUE = 0x10    /* Value has been changed by a previous
+                                  la_symbind call.  */
+  };
+
+
 struct dl_phdr_info
   {
     ElfW(Addr) dlpi_addr;
@@ -114,9 +156,28 @@ struct dl_phdr_info
 
 __BEGIN_DECLS
 
-extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
-                                            size_t size, void *data),
-                           void *data);
+extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
+                                              size_t, void *),
+                           void *__data);
+
+
+/* Prototypes for the ld.so auditing interfaces.  These are not
+   defined anywhere in ld.so but instead have to be provided by the
+   auditing DSO.  */
+extern unsigned int la_version (unsigned int __version);
+extern void la_activity (uintptr_t *__cookie, unsigned int __flag);
+extern char *la_objsearch (const char *__name, uintptr_t *__cookie,
+                          unsigned int __flag);
+extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid,
+                               uintptr_t *__cookie);
+extern void la_preinit (uintptr_t *__cookie);
+extern uintptr_t la_symbind32 (Elf32_Sym *__sym, unsigned int __ndx,
+                              uintptr_t *__refcook, uintptr_t *__defcook,
+                              unsigned int *__flags, const char *__symname);
+extern uintptr_t la_symbind64 (Elf64_Sym *__sym, unsigned int __ndx,
+                              uintptr_t *__refcook, uintptr_t *__defcook,
+                              unsigned int *__flags, const char *__symname);
+extern unsigned int la_objclose (uintptr_t *__cookie);
 
 __END_DECLS
 
index 3835a20..9fda5b8 100644 (file)
@@ -79,6 +79,13 @@ INTDEF(_dl_argv)
 /* Nonzero if we were run directly.  */
 unsigned int _dl_skip_args attribute_relro attribute_hidden;
 
+/* List of auditing DSOs.  */
+static struct audit_list
+{
+  const char *name;
+  struct audit_list *next;
+} *audit_list;
+
 #ifndef HAVE_INLINED_SYSCALLS
 /* Set nonzero during loading and initialization of executable and
    libraries, cleared before the executable's entry point runs.  This
@@ -126,25 +133,14 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
     ._dl_fpu_control = _FPU_DEFAULT,
 
     /* Function pointers.  */
-    ._dl_get_origin = _dl_get_origin,
-    ._dl_dst_count = _dl_dst_count,
-    ._dl_dst_substitute = _dl_dst_substitute,
-    ._dl_map_object = _dl_map_object,
-    ._dl_map_object_deps = _dl_map_object_deps,
-    ._dl_relocate_object = _dl_relocate_object,
-    ._dl_check_map_versions = _dl_check_map_versions,
-    ._dl_init = _dl_init,
-    ._dl_debug_state = _dl_debug_state,
-#ifndef MAP_COPY
-    ._dl_unload_cache = _dl_unload_cache,
-#endif
     ._dl_debug_printf = _dl_debug_printf,
     ._dl_catch_error = _dl_catch_error,
     ._dl_signal_error = _dl_signal_error,
-    ._dl_start_profile = _dl_start_profile,
     ._dl_mcount = _dl_mcount_internal,
     ._dl_lookup_symbol_x = _dl_lookup_symbol_x,
-    ._dl_check_caller = _dl_check_caller
+    ._dl_check_caller = _dl_check_caller,
+    ._dl_open = _dl_open,
+    ._dl_close = _dl_close
   };
 /* If we would use strong_alias here the compiler would see a
    non-hidden definition.  This would undo the effect of the previous
@@ -267,6 +263,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
   memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
          sizeof GL(dl_rtld_map).l_info);
   GL(dl_rtld_map).l_mach = info->l.l_mach;
+  GL(dl_rtld_map).l_relocated = 1;
 #endif
   _dl_setup_hash (&GL(dl_rtld_map));
   GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
@@ -348,8 +345,6 @@ _dl_start (void *arg)
 #define RTLD_BOOTSTRAP
 #define RESOLVE_MAP(sym, version, flags) \
   ((*(sym))->st_shndx == SHN_UNDEF ? 0 : &bootstrap_map)
-#define RESOLVE(sym, version, flags) \
-  ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
 #include "dynamic-link.h"
 
   if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
@@ -472,7 +467,7 @@ _dl_start (void *arg)
          while (remaining-- > 0)
            *p++ = '\0';
        }
-#endif
+# endif
 
        /* Install the pointer to the dtv.  */
 
@@ -514,6 +509,7 @@ _dl_start (void *arg)
         data access using the global offset table.  */
 
       ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
+      bootstrap_map.l_relocated = 1;
     }
 
   /* Please note that we don't allow profiling of this object and
@@ -566,6 +562,19 @@ struct map_args
   struct link_map *map;
 };
 
+struct dlmopen_args
+{
+  const char *fname;
+  struct link_map *map;
+};
+
+struct lookup_args
+{
+  const char *name;
+  struct link_map *map;
+  void *result;
+};
+
 /* Arguments to version_check_doit.  */
 struct version_check_args
 {
@@ -591,6 +600,28 @@ map_doit (void *a)
 }
 
 static void
+dlmopen_doit (void *a)
+{
+  struct dlmopen_args *args = (struct dlmopen_args *) a;
+  args->map = _dl_open (args->fname, RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT,
+                       dl_main, LM_ID_NEWLM, _dl_argc, INTUSE(_dl_argv),
+                       __environ);
+}
+
+static void
+lookup_doit (void *a)
+{
+  struct lookup_args *args = (struct lookup_args *) a;
+  const ElfW(Sym) *ref = NULL;
+  args->result = NULL;
+  lookup_t l = _dl_lookup_symbol_x (args->name, args->map, &ref,
+                                   args->map->l_local_scope, NULL, 0,
+                                   DL_LOOKUP_RETURN_NEWEST, NULL);
+  if (ref != NULL)
+    args->result = DL_SYMBOL_ADDRESS (l, ref);
+}
+
+static void
 version_check_doit (void *a)
 {
   struct version_check_args *args = (struct version_check_args *) a;
@@ -648,6 +679,80 @@ match_version (const char *string, struct link_map *map)
   return 0;
 }
 
+#ifdef USE_TLS
+static bool tls_init_tp_called;
+
+static void *
+init_tls (void)
+{
+  /* Number of elements in the static TLS block.  */
+  GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
+
+  /* Do not do this twice.  The audit interface might have required
+     the DTV interfaces to be set up early.  */
+  if (GL(dl_initial_dtv) != NULL)
+    return NULL;
+
+  /* Allocate the array which contains the information about the
+     dtv slots.  We allocate a few entries more than needed to
+     avoid the need for reallocation.  */
+  size_t nelem = GL(dl_tls_max_dtv_idx) + 1 + TLS_SLOTINFO_SURPLUS;
+
+  /* Allocate.  */
+  GL(dl_tls_dtv_slotinfo_list) = (struct dtv_slotinfo_list *)
+    calloc (sizeof (struct dtv_slotinfo_list)
+           + nelem * sizeof (struct dtv_slotinfo), 1);
+  /* No need to check the return value.  If memory allocation failed
+     the program would have been terminated.  */
+
+  struct dtv_slotinfo *slotinfo = GL(dl_tls_dtv_slotinfo_list)->slotinfo;
+  GL(dl_tls_dtv_slotinfo_list)->len = nelem;
+  GL(dl_tls_dtv_slotinfo_list)->next = NULL;
+
+  /* Fill in the information from the loaded modules.  No namespace
+     but the base one can be filled at this time.  */
+  assert (GL(dl_ns)[LM_ID_BASE + 1]._ns_loaded == NULL);
+  int i = 0;
+  for (struct link_map *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; l != NULL;
+       l = l->l_next)
+    if (l->l_tls_blocksize != 0)
+      {
+       /* This is a module with TLS data.  Store the map reference.
+          The generation counter is zero.  */
+       slotinfo[i].map = l;
+       /* slotinfo[i].gen = 0; */
+       ++i;
+      }
+  assert (i == GL(dl_tls_max_dtv_idx));
+
+  /* Compute the TLS offsets for the various blocks.  */
+  _dl_determine_tlsoffset ();
+
+  /* Construct the static TLS block and the dtv for the initial
+     thread.  For some platforms this will include allocating memory
+     for the thread descriptor.  The memory for the TLS block will
+     never be freed.  It should be allocated accordingly.  The dtv
+     array can be changed if dynamic loading requires it.  */
+  void *tcbp = _dl_allocate_tls_storage ();
+  if (tcbp == NULL)
+    _dl_fatal_printf ("\
+cannot allocate TLS data structures for initial thread");
+
+  /* Store for detection of the special case by __tls_get_addr
+     so it knows not to pass this dtv to the normal realloc.  */
+  GL(dl_initial_dtv) = GET_DTV (tcbp);
+
+  /* And finally install it for the main thread.  If ld.so itself uses
+     TLS we know the thread pointer was initialized earlier.  */
+  const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD);
+  if (__builtin_expect (lossage != NULL, 0))
+    _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
+  tls_init_tp_called = true;
+
+  return tcbp;
+}
+#endif
+
 #ifdef _LIBC_REENTRANT
 /* _dl_error_catch_tsd points to this for the single-threaded case.
    It's reset by the thread library for multithreaded programs.  */
@@ -702,7 +807,7 @@ dl_main (const ElfW(Phdr) *phdr,
   hp_timing_t diff;
 #endif
 #ifdef USE_TLS
-  void *tcbp;
+  void *tcbp = NULL;
 #endif
 
 #ifdef _LIBC_REENTRANT
@@ -826,6 +931,7 @@ of this helper program; chances are you did not intend to run this program.\n\
         objects.  */
       _dl_init_paths (library_path);
 
+
       /* The initialization of _dl_stack_flags done below assumes the
         executable's PT_GNU_STACK may have been honored by the kernel, and
         so a PT_GNU_STACK with PF_X set means the stack started out with
@@ -887,10 +993,10 @@ of this helper program; chances are you did not intend to run this program.\n\
     {
       /* Create a link_map for the executable itself.
         This will be what dlopen on "" returns.  */
-      _dl_new_object ((char *) "", "", lt_executable, NULL, 0, LM_ID_BASE);
-      main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-      if (main_map == NULL)
-       _dl_fatal_printf ("cannot allocate memory for link map\n");
+      main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
+                                __RTLD_OPENEXEC, LM_ID_BASE);
+      assert (main_map != NULL);
+      assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
       main_map->l_phdr = phdr;
       main_map->l_phnum = phnum;
       main_map->l_entry = *user_entry;
@@ -991,8 +1097,9 @@ of this helper program; chances are you did not intend to run this program.\n\
            main_map->l_text_end = allocend;
        }
        break;
-#ifdef USE_TLS
+
       case PT_TLS:
+#ifdef USE_TLS
        if (ph->p_memsz > 0)
          {
            /* Note that in the case the dynamic linker we duplicate work
@@ -1012,8 +1119,12 @@ of this helper program; chances are you did not intend to run this program.\n\
            /* This image gets the ID one.  */
            GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1;
          }
-       break;
+#else
+       _dl_fatal_printf ("\
+ld.so does not support TLS, but program uses it!\n");
 #endif
+       break;
+
       case PT_GNU_STACK:
        GL(dl_stack_flags) = ph->p_flags;
        break;
@@ -1045,6 +1156,26 @@ of this helper program; chances are you did not intend to run this program.\n\
   else
     assert (GL(dl_rtld_map).l_libname); /* How else did we get here?  */
 
+  /* If the current libname is different from the SONAME, add the
+     latter as well.  */
+  if (GL(dl_rtld_map).l_info[DT_SONAME] != NULL
+      && strcmp (GL(dl_rtld_map).l_libname->name,
+                (const char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
+                + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_val) != 0)
+    {
+      static struct libname_list newname;
+      newname.name = ((char *) D_PTR (&GL(dl_rtld_map), l_info[DT_STRTAB])
+                     + GL(dl_rtld_map).l_info[DT_SONAME]->d_un.d_ptr);
+      newname.next = NULL;
+      newname.dont_free = 1;
+
+      assert (GL(dl_rtld_map).l_libname->next == NULL);
+      GL(dl_rtld_map).l_libname->next = &newname;
+    }
+  /* The ld.so must be relocated since otherwise loading audit modules
+     will fail since they reuse the very same ld.so.  */
+  assert (GL(dl_rtld_map).l_relocated);
+
   if (! rtld_is_main)
     {
       /* Extract the contents of the dynamic section for easy access.  */
@@ -1074,6 +1205,11 @@ of this helper program; chances are you did not intend to run this program.\n\
        objects.  */
     _dl_init_paths (library_path);
 
+  /* Initialize _r_debug.  */
+  struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr,
+                                           LM_ID_BASE);
+  r->r_state = RT_CONSISTENT;
+
   /* Put the link_map for ourselves on the chain so it can be found by
      name.  Note that at this point the global chain of link maps contains
      exactly one element, which is pointed to by dl_loaded.  */
@@ -1148,6 +1284,7 @@ of this helper program; chances are you did not intend to run this program.\n\
   GL(dl_rtld_map).l_phdr = rtld_phdr;
   GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;
 
+
   /* PT_GNU_RELRO is usually the last phdr.  */
   size_t cnt = rtld_ehdr->e_phnum;
   while (cnt-- > 0)
@@ -1158,6 +1295,204 @@ of this helper program; chances are you did not intend to run this program.\n\
        break;
       }
 
+#ifdef USE_TLS
+  /* Add the dynamic linker to the TLS list if it also uses TLS.  */
+  if (GL(dl_rtld_map).l_tls_blocksize != 0)
+    /* Assign a module ID.  Do this before loading any audit modules.  */
+    GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
+#endif
+
+  /* If we have auditing DSOs to load, do it now.  */
+  if (__builtin_expect (audit_list != NULL, 0))
+    {
+      /* Iterate over all entries in the list.  The order is important.  */
+      struct audit_ifaces *last_audit = NULL;
+      struct audit_list *al = audit_list->next;
+      do
+       {
+#ifdef USE_TLS
+         int tls_idx = GL(dl_tls_max_dtv_idx);
+
+         /* Now it is time to determine the layout of the static TLS
+            block and allocate it for the initial thread.  Note that we
+            always allocate the static block, we never defer it even if
+            no DF_STATIC_TLS bit is set.  The reason is that we know
+            glibc will use the static model.  */
+# ifndef TLS_INIT_TP_EXPENSIVE
+#  define TLS_INIT_TP_EXPENSIVE 0
+# endif
+
+         /* Since we start using the auditing DSOs right away we need to
+            initialize the data structures now.  */
+         if (!TLS_INIT_TP_EXPENSIVE)
+           tcbp = init_tls ();
+#endif
+         struct dlmopen_args dlmargs;
+         dlmargs.fname = al->name;
+         dlmargs.map = NULL;
+
+         const char *objname;
+         const char *err_str = NULL;
+         (void) _dl_catch_error (&objname, &err_str, dlmopen_doit, &dlmargs);
+         if (__builtin_expect (err_str != NULL, 0))
+           {
+           not_loaded:
+             _dl_error_printf ("\
+ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+                               al->name, err_str);
+             free ((char *) err_str);
+           }
+         else
+           {
+             struct lookup_args largs;
+             largs.name = "la_version";
+             largs.map = dlmargs.map;
+
+             /* Check whether the interface version matches.  */
+             (void) _dl_catch_error (&objname, &err_str, lookup_doit, &largs);
+
+             unsigned int (*laversion) (unsigned int);
+             unsigned int lav;
+             if  (err_str == NULL
+                  && (laversion = largs.result) != NULL
+                  && (lav = laversion (LAV_CURRENT)) > 0
+                  && lav <= LAV_CURRENT)
+               {
+                 /* Allocate structure for the callback function pointers.
+                    This call can never fail.  */
+                 union
+                 {
+                   struct audit_ifaces ifaces;
+#define naudit_ifaces 8
+                   void (*fptr[naudit_ifaces]) (void);
+                 } *newp = malloc (sizeof (*newp));
+
+                 /* Names of the auditing interfaces.  All in one
+                    long string.  */
+                 static const char audit_iface_names[] =
+                   "la_activity\0"
+                   "la_objsearch\0"
+                   "la_objopen\0"
+                   "la_preinit\0"
+#if __ELF_NATIVE_CLASS == 32
+                   "la_symbind32\0"
+#elif __ELF_NATIVE_CLASS == 64
+                   "la_symbind64\0"
+#else
+# error "__ELF_NATIVE_CLASS must be defined"
+#endif
+#define STRING(s) __STRING (s)
+                   "la_" STRING (ARCH_LA_PLTENTER) "\0"
+                   "la_" STRING (ARCH_LA_PLTEXIT) "\0"
+                   "la_objclose\0";
+                 unsigned int cnt = 0;
+                 const char *cp = audit_iface_names;
+                 do
+                   {
+                     largs.name = cp;
+                     (void) _dl_catch_error (&objname, &err_str, lookup_doit,
+                                             &largs);
+
+                     /* Store the pointer.  */
+                     if (err_str == NULL && largs.result != NULL)
+                       {
+                         newp->fptr[cnt] = largs.result;
+
+                         /* The dynamic linker link map is statically
+                            allocated, initialize the data now.   */
+                         GL(dl_rtld_map).l_audit[cnt].cookie
+                           = (intptr_t) &GL(dl_rtld_map);
+                       }
+                     else
+                       newp->fptr[cnt] = NULL;
+                     ++cnt;
+
+                     cp = (char *) rawmemchr (cp, '\0') + 1;
+                   }
+                 while (*cp != '\0');
+                 assert (cnt == naudit_ifaces);
+
+                 /* Now append the new auditing interface to the list.  */
+                 newp->ifaces.next = NULL;
+                 if (last_audit == NULL)
+                   last_audit = GLRO(dl_audit) = &newp->ifaces;
+                 else
+                   last_audit = last_audit->next = &newp->ifaces;
+                 ++GLRO(dl_naudit);
+
+                 /* Mark the DSO as being used for auditing.  */
+                 dlmargs.map->l_auditing = 1;
+               }
+             else
+               {
+                 /* We cannot use the DSO, it does not have the
+                    appropriate interfaces or it expects something
+                    more recent.  */
+#ifndef NDEBUG
+                 Lmid_t ns = dlmargs.map->l_ns;
+#endif
+                 _dl_close (dlmargs.map);
+
+                 /* Make sure the namespace has been cleared entirely.  */
+                 assert (GL(dl_ns)[ns]._ns_loaded == NULL);
+                 assert (GL(dl_ns)[ns]._ns_nloaded == 0);
+
+#ifdef USE_TLS
+                 GL(dl_tls_max_dtv_idx) = tls_idx;
+#endif
+                 goto not_loaded;
+               }
+           }
+
+         al = al->next;
+       }
+      while (al != audit_list->next);
+
+      /* If we have any auditing modules, announce that we already
+        have two objects loaded.  */
+      if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+       {
+         struct link_map *ls[2] = { main_map, &GL(dl_rtld_map) };
+
+         for (unsigned int outer = 0; outer < 2; ++outer)
+           {
+             struct audit_ifaces *afct = GLRO(dl_audit);
+             for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+               {
+                 if (afct->objopen != NULL)
+                   {
+                     ls[outer]->l_audit[cnt].bindflags
+                       = afct->objopen (ls[outer], LM_ID_BASE,
+                                        &ls[outer]->l_audit[cnt].cookie);
+
+                     ls[outer]->l_audit_any_plt
+                       |= ls[outer]->l_audit[cnt].bindflags != 0;
+                   }
+
+                 afct = afct->next;
+               }
+           }
+       }
+    }
+
+  /* We start adding objects.  */
+  r->r_state = RT_ADD;
+  _dl_debug_state ();
+
+  /* Auditing checkpoint: we are ready to signal that the initial map
+     is being constructed.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+    {
+      struct audit_ifaces *afct = GLRO(dl_audit);
+      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+       {
+         if (afct->activity != NULL)
+           afct->activity (&main_map->l_audit[cnt].cookie, LA_ACT_ADD);
+
+         afct = afct->next;
+       }
+    }
+
   /* We have two ways to specify objects to preload: via environment
      variable and via the file /etc/ld.so.preload.  The latter can also
      be used when security is enabled.  */
@@ -1418,6 +1753,9 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
                           && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
                    l->l_text_end = ph->p_vaddr + ph->p_memsz;
                }
+             else
+               /* There must be no TLS segment.  */
+               assert (ph->p_type != PT_TLS);
            }
          l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
          l->l_addr = l->l_map_start - l->l_addr;
@@ -1533,20 +1871,6 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
   }
 
 #ifdef USE_TLS
-  /* Now it is time to determine the layout of the static TLS block
-     and allocate it for the initial thread.  Note that we always
-     allocate the static block, we never defer it even if no
-     DF_STATIC_TLS bit is set.  The reason is that we know glibc will
-     use the static model.  First add the dynamic linker to the list
-     if it also uses TLS.  */
-  if (GL(dl_rtld_map).l_tls_blocksize != 0)
-    /* Assign a module ID.  */
-    GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
-
-# ifndef TLS_INIT_TP_EXPENSIVE
-#  define TLS_INIT_TP_EXPENSIVE 0
-# endif
-
   /* We do not initialize any of the TLS functionality unless any of the
      initial modules uses TLS.  This makes dynamic loading of modules with
      TLS impossible, but to support it requires either eagerly doing setup
@@ -1554,57 +1878,9 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
      an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
      used.  Trying to do it lazily is too hairy to try when there could be
      multiple threads (from a non-TLS-using libpthread).  */
-  if (!TLS_INIT_TP_EXPENSIVE || GL(dl_tls_max_dtv_idx) > 0)
-    {
-      struct link_map *l;
-      size_t nelem;
-      struct dtv_slotinfo *slotinfo;
-
-      /* Number of elements in the static TLS block.  */
-      GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
-
-      /* Allocate the array which contains the information about the
-        dtv slots.  We allocate a few entries more than needed to
-        avoid the need for reallocation.  */
-      nelem = GL(dl_tls_max_dtv_idx) + 1 + TLS_SLOTINFO_SURPLUS;
-
-      /* Allocate.  */
-      GL(dl_tls_dtv_slotinfo_list) = (struct dtv_slotinfo_list *)
-       malloc (sizeof (struct dtv_slotinfo_list)
-               + nelem * sizeof (struct dtv_slotinfo));
-      /* No need to check the return value.  If memory allocation failed
-        the program would have been terminated.  */
-
-      slotinfo = memset (GL(dl_tls_dtv_slotinfo_list)->slotinfo, '\0',
-                        nelem * sizeof (struct dtv_slotinfo));
-      GL(dl_tls_dtv_slotinfo_list)->len = nelem;
-      GL(dl_tls_dtv_slotinfo_list)->next = NULL;
-
-      /* Fill in the information from the loaded modules.  */
-      for (l = main_map, i = 0; l != NULL; l = l->l_next)
-       if (l->l_tls_blocksize != 0)
-         /* This is a module with TLS data.  Store the map reference.
-            The generation counter is zero.  */
-         slotinfo[++i].map = l;
-      assert (i == GL(dl_tls_max_dtv_idx));
-
-      /* Compute the TLS offsets for the various blocks.  */
-      _dl_determine_tlsoffset ();
-
-      /* Construct the static TLS block and the dtv for the initial
-        thread.  For some platforms this will include allocating memory
-        for the thread descriptor.  The memory for the TLS block will
-        never be freed.  It should be allocated accordingly.  The dtv
-        array can be changed if dynamic loading requires it.  */
-      tcbp = _dl_allocate_tls_storage ();
-      if (tcbp == NULL)
-       _dl_fatal_printf ("\
-cannot allocate TLS data structures for initial thread");
-
-      /* Store for detection of the special case by __tls_get_addr
-        so it knows not to pass this dtv to the normal realloc.  */
-      GL(dl_initial_dtv) = GET_DTV (tcbp);
-    }
+  bool was_tls_init_tp_called = tls_init_tp_called;
+  if (tcbp == NULL && (!TLS_INIT_TP_EXPENSIVE || GL(dl_tls_max_dtv_idx) > 0))
+    tcbp = init_tls ();
 #endif
 
   if (__builtin_expect (mode, normal) != normal)
@@ -1885,8 +2161,6 @@ cannot allocate TLS data structures for initial thread");
     }
 
 
-  /* Initialize _r_debug.  */
-  struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
   {
     struct link_map *l = main_map;
 
@@ -1921,8 +2195,6 @@ cannot allocate TLS data structures for initial thread");
 
   if (prelinked)
     {
-      struct link_map *l;
-
       if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
        {
          ElfW(Rela) *conflict, *conflictend;
@@ -1945,11 +2217,17 @@ cannot allocate TLS data structures for initial thread");
 
 
       /* Mark all the objects so we know they have been already relocated.  */
-      for (l = main_map; l != NULL; l = l->l_next)
+      for (struct link_map *l = main_map; l != NULL; l = l->l_next)
        {
          l->l_relocated = 1;
          if (l->l_relro_size)
            _dl_protect_relro (l);
+
+#ifdef USE_TLS
+         /* Add object to slot information data if necessasy.  */
+         if (l->l_tls_blocksize != 0 && tls_init_tp_called)
+           _dl_add_to_slotinfo (l);
+#endif
        }
 
       _dl_sysdep_start_cleanup ();
@@ -1965,7 +2243,6 @@ cannot allocate TLS data structures for initial thread");
         the dynamic linker out of order because it has no copy relocs (we
         know that because it is self-contained).  */
 
-      struct link_map *l;
       int consider_profiling = GLRO(dl_profile) != NULL;
 #ifndef HP_TIMING_NONAVAIL
       hp_timing_t start;
@@ -1976,7 +2253,7 @@ cannot allocate TLS data structures for initial thread");
       /* If we are profiling we also must do lazy reloaction.  */
       GLRO(dl_lazy) |= consider_profiling;
 
-      l = main_map;
+      struct link_map *l = main_map;
       while (l->l_next)
        l = l->l_next;
 
@@ -1998,6 +2275,12 @@ cannot allocate TLS data structures for initial thread");
            _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
                                 consider_profiling);
 
+#ifdef USE_TLS
+         /* Add object to slot information data if necessasy.  */
+         if (l->l_tls_blocksize != 0 && tls_init_tp_called)
+           _dl_add_to_slotinfo (l);
+#endif
+
          l = l->l_prev;
        }
       while (l);
@@ -2025,6 +2308,8 @@ cannot allocate TLS data structures for initial thread");
          /* There was an explicit ref to the dynamic linker as a shared lib.
             Re-relocate ourselves with user-controlled symbol definitions.  */
          HP_TIMING_NOW (start);
+         /* Mark the link map as not yet relocated again.  */
+         GL(dl_rtld_map).l_relocated = 0;
          _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
          HP_TIMING_NOW (stop);
          HP_TIMING_DIFF (add, start, stop);
@@ -2039,6 +2324,9 @@ cannot allocate TLS data structures for initial thread");
 #ifdef USE_TLS
   if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD || !TLS_INIT_TP_EXPENSIVE)
     {
+      if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
+       ++GL(dl_tls_generation);
+
       /* Now that we have completed relocation, the initializer data
         for the TLS blocks has its final values and we can copy them
         into the main thread's TLS area, which we allocated above.  */
@@ -2046,16 +2334,42 @@ cannot allocate TLS data structures for initial thread");
 
       /* And finally install it for the main thread.  If ld.so itself uses
         TLS we know the thread pointer was initialized earlier.  */
-      const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD);
-      if (__builtin_expect (lossage != NULL, 0))
-       _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
+      if (! tls_init_tp_called)
+       {
+         const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD);
+         if (__builtin_expect (lossage != NULL, 0))
+           _dl_fatal_printf ("cannot set up thread-local storage: %s\n",
+                             lossage);
+       }
     }
   else
 #endif
     NONTLS_INIT_TP;
 
-  /* Notify the debugger that all objects are now mapped in.  */
-  r->r_state = RT_ADD;
+#ifdef SHARED
+  /* Auditing checkpoint: we have added all objects.  */
+  if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+    {
+      struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+      /* Do not call the functions for any auditing object.  */
+      if (head->l_auditing == 0)
+       {
+         struct audit_ifaces *afct = GLRO(dl_audit);
+         for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
+           {
+             if (afct->activity != NULL)
+               afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
+
+             afct = afct->next;
+           }
+       }
+    }
+#endif
+
+  /* Notify the debugger all new objects are now ready to go.  We must re-get
+     the address since by now the variable might be in another object.  */
+  r = _dl_debug_initialize (0, LM_ID_BASE);
+  r->r_state = RT_CONSISTENT;
   _dl_debug_state ();
 
 #ifndef MAP_COPY
@@ -2187,6 +2501,32 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
     }
 }
 \f
+static void
+process_dl_audit (char *str)
+{
+  /* The parameter is a colon separated list of DSO names.  */
+  char *p;
+
+  while ((p = (strsep) (&str, ":")) != NULL)
+    if (p[0] != '\0'
+       && (__builtin_expect (! INTUSE(__libc_enable_secure), 1)
+           || strchr (p, '/') == NULL))
+      {
+       /* This is using the local malloc, not the system malloc.  The
+          memory can never be freed.  */
+       struct audit_list *newp = malloc (sizeof (*newp));
+       newp->name = p;
+
+       if (audit_list == NULL)
+         audit_list = newp->next = newp;
+       else
+         {
+           newp->next = audit_list->next;
+           audit_list = audit_list->next = newp;
+         }
+      }
+}
+\f
 /* Process all environments variables the dynamic linker must recognize.
    Since all of them start with `LD_' we are a bit smarter while finding
    all the entries.  */
@@ -2229,7 +2569,12 @@ process_envvars (enum mode *modep)
        case 5:
          /* Debugging of the dynamic linker?  */
          if (memcmp (envline, "DEBUG", 5) == 0)
-           process_dl_debug (&envline[6]);
+           {
+             process_dl_debug (&envline[6]);
+             break;
+           }
+         if (memcmp (envline, "AUDIT", 5) == 0)
+           process_dl_audit (&envline[6]);
          break;
 
        case 7:
index afe3955..9567e46 100644 (file)
@@ -1,5 +1,5 @@
 /* Read and display shared object profiling data.
-   Copyright (C) 1997-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1997-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -357,7 +357,7 @@ Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 "),
-          "2004");
+          "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
diff --git a/elf/tst-align2.c b/elf/tst-align2.c
new file mode 100644 (file)
index 0000000..4fc0330
--- /dev/null
@@ -0,0 +1,157 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
+
+   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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <tst-stack-align.h>
+#include <unistd.h>
+
+static int res, fds[2], result;
+static bool test_destructors;
+
+extern void in_dso (int *, bool *, int *);
+
+static void __attribute__ ((constructor)) con (void)
+{
+  res = TEST_STACK_ALIGN () ? -1 : 1;
+}
+
+static void __attribute__ ((destructor)) des (void)
+{
+  if (!test_destructors)
+    return;
+
+  char c = TEST_STACK_ALIGN () ? 'B' : 'A';
+  write (fds[1], &c, 1);
+}
+
+static int
+do_test (void)
+{
+  if (!res)
+    {
+      puts ("binary's constructor has not been run");
+      result = 1;
+    }
+  else if (res != 1)
+    {
+      puts ("binary's constructor has been run without sufficient alignment");
+      result = 1;
+    }
+
+  if (TEST_STACK_ALIGN ())
+    {
+      puts ("insufficient stack alignment in do_test");
+      result = 1;
+    }
+
+  in_dso (&result, &test_destructors, &fds[1]);
+
+  if (pipe (fds) < 0)
+    {
+      printf ("couldn't create pipe: %m\n");
+      return 1;
+    }
+
+  pid_t pid = fork ();
+  if (pid < 0)
+    {
+      printf ("fork failed: %m\n");
+      return 1;
+    }
+
+  if (!pid)
+    {
+      close (fds[0]);
+      test_destructors = true;
+      exit (0);
+    }
+
+  close (fds[1]);
+
+  unsigned char c;
+  ssize_t len;
+  int des_seen = 0, dso_des_seen = 0;
+  while ((len = TEMP_FAILURE_RETRY (read (fds[0], &c, 1))) > 0)
+    {
+      switch (c)
+        {
+        case 'B':
+          puts ("insufficient alignment in binary's destructor");
+          result = 1;
+          /* FALLTHROUGH */
+        case 'A':
+          des_seen++;
+          break;
+        case 'D':
+          puts ("insufficient alignment in DSO destructor");
+          result = 1;
+          /* FALLTHROUGH */
+        case 'C':
+          dso_des_seen++;
+          break;
+        default:
+          printf ("unexpected character %x read from pipe", c);
+          result = 1;
+          break;
+        }
+    }
+
+  close (fds[0]);
+
+  if (des_seen != 1)
+    {
+      printf ("binary destructor run %d times instead of once\n", des_seen);
+      result = 1;
+    }
+
+  if (dso_des_seen != 1)
+    {
+      printf ("DSO destructor run %d times instead of once\n", dso_des_seen);
+      result = 1;
+    }
+
+  int status;
+  pid_t termpid;
+  termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+  if (termpid == -1)
+    {
+      printf ("waitpid failed: %m\n");
+      result = 1;
+    }
+  else if (termpid != pid)
+    {
+      printf ("waitpid returned %ld != %ld\n",
+             (long int) termpid, (long int) pid);
+      result = 1;
+    }
+  else if (!WIFEXITED (status) || WEXITSTATUS (status))
+    {
+      puts ("child hasn't exited with exit status 0");
+      result = 1;
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-alignmod2.c b/elf/tst-alignmod2.c
new file mode 100644 (file)
index 0000000..21dcc53
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <tst-stack-align.h>
+#include <unistd.h>
+
+static int res, *fdp;
+static bool *test_destructorsp;
+
+static void __attribute__((constructor))
+con (void)
+{
+  res = TEST_STACK_ALIGN () ? -1 : 1;
+}
+
+void
+in_dso (int *result, bool *test_destructors, int *fd)
+{
+  if (!res)
+    {
+      puts ("constructor has not been run");
+      *result = 1;
+    }
+  else if (res != 1)
+    {
+      puts ("constructor has been run without sufficient alignment");
+      *result = 1;
+    }
+
+  test_destructorsp = test_destructors;
+  fdp = fd;
+}
+
+static void __attribute__((destructor))
+des (void)
+{
+  if (!test_destructorsp || !*test_destructorsp)
+    return;
+
+  char c = TEST_STACK_ALIGN () ? 'D' : 'C';
+  write (*fdp, &c, 1);
+}
diff --git a/elf/tst-audit1.c b/elf/tst-audit1.c
new file mode 100644 (file)
index 0000000..63656b4
--- /dev/null
@@ -0,0 +1 @@
+#include "../io/pwd.c"
diff --git a/elf/tst-auditmod1.c b/elf/tst-auditmod1.c
new file mode 100644 (file)
index 0000000..9b07588
--- /dev/null
@@ -0,0 +1,190 @@
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <bits/wordsize.h>
+#include <gnu/lib-names.h>
+
+
+unsigned int
+la_version (unsigned int v)
+{
+  setlinebuf (stdout);
+
+  printf ("version: %u\n", v);
+
+  char buf[20];
+  sprintf (buf, "%u", v);
+
+  return v;
+}
+
+void
+la_activity (uintptr_t *cookie, unsigned int flag)
+{
+  if (flag == LA_ACT_CONSISTENT)
+    printf ("activity: consistent\n");
+  else if (flag == LA_ACT_ADD)
+    printf ("activity: add\n");
+  else if (flag == LA_ACT_DELETE)
+    printf ("activity: delete\n");
+  else
+    printf ("activity: unknown activity %u\n", flag);
+}
+
+char *
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
+{
+  char buf[100];
+  const char *flagstr;
+  if (flag == LA_SER_ORIG)
+    flagstr = "LA_SET_ORIG";
+  else if (flag == LA_SER_LIBPATH)
+    flagstr = "LA_SER_LIBPATH";
+  else if (flag == LA_SER_RUNPATH)
+    flagstr = "LA_SER_RUNPATH";
+  else if (flag == LA_SER_CONFIG)
+    flagstr = "LA_SER_CONFIG";
+  else if (flag == LA_SER_DEFAULT)
+    flagstr = "LA_SER_DEFAULT";
+  else if (flag == LA_SER_SECURE)
+    flagstr = "LA_SER_SECURE";
+  else
+    {
+       sprintf (buf, "unknown flag %d", flag);
+       flagstr = buf;
+    }
+  printf ("objsearch: %s, %s\n", name, flagstr);
+
+  return (char *) name;
+}
+
+unsigned int
+la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie)
+{
+  printf ("objopen: %ld, %s\n", lmid, l->l_name);
+
+  return 3;
+}
+
+void
+la_preinit (uintptr_t *cookie)
+{
+  printf ("preinit\n");
+}
+
+unsigned int
+la_objclose  (uintptr_t *cookie)
+{
+  printf ("objclose\n");
+  return 0;
+}
+
+uintptr_t
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
+             uintptr_t *defcook, unsigned int *flags, const char *symname)
+{
+  printf ("symbind32: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+         symname, (long int) sym->st_value, ndx, *flags);
+
+  return sym->st_value;
+}
+
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
+             uintptr_t *defcook, unsigned int *flags, const char *symname)
+{
+  printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+         symname, (long int) sym->st_value, ndx, *flags);
+
+  return sym->st_value;
+}
+
+#ifdef __i386__
+# define pltenter la_i86_gnu_pltenter
+# define pltexit la_i86_gnu_pltexit
+# define La_regs La_i86_regs
+# define La_retval La_i86_retval
+# define int_retval lrv_eax
+#elif defined __x86_64__
+# define pltenter la_x86_64_gnu_pltenter
+# define pltexit la_x86_64_gnu_pltexit
+# define La_regs La_x86_64_regs
+# define La_retval La_x86_64_retval
+# define int_retval lrv_rax
+#elif defined __powerpc__ && __WORDSIZE == 32
+# define pltenter la_ppc32_gnu_pltenter
+# define pltexit la_ppc32_gnu_pltexit
+# define La_regs La_ppc32_regs
+# define La_retval La_ppc32_retval
+# define int_retval lrv_r3
+#elif defined __powerpc__ && __WORDSIZE == 64
+# define pltenter la_ppc64_gnu_pltenter
+# define pltexit la_ppc64_gnu_pltexit
+# define La_regs La_ppc64_regs
+# define La_retval La_ppc64_retval
+# define int_retval lrv_r3
+#elif defined __sh__
+# define pltenter la_sh_gnu_pltenter
+# define pltexit la_sh_gnu_pltexit
+# define La_regs La_sh_regs
+# define La_retval La_sh_retval
+# define int_retval lrv_r0
+#elif defined __mc68000__
+# define pltenter la_m68k_gnu_pltenter
+# define pltexit la_m68k_gnu_pltexit
+# define La_regs La_m68k_regs
+# define La_retval La_m68k_retval
+# define int_retval lrv_d0
+#elif defined __alpha__
+# define pltenter la_alpha_gnu_pltenter
+# define pltexit la_alpha_gnu_pltexit
+# define La_regs La_alpha_regs
+# define La_retval La_alpha_retval
+# define int_retval lrv_r0
+#elif defined __s390__ && __WORDSIZE == 32
+# define pltenter la_s390_32_gnu_pltenter
+# define pltexit la_s390_32_gnu_pltexit
+# define La_regs La_s390_32_regs
+# define La_retval La_s390_32_retval
+# define int_retval lrv_r2
+#elif defined __s390__ && __WORDSIZE == 64
+# define pltenter la_s390_64_gnu_pltenter
+# define pltexit la_s390_64_gnu_pltexit
+# define La_regs La_s390_64_regs
+# define La_retval La_s390_64_retval
+# define int_retval lrv_r2
+#elif defined __ia64__
+# define pltenter la_ia64_gnu_pltenter
+# define pltexit la_ia64_gnu_pltexit
+# define La_regs La_ia64_regs
+# define La_retval La_ia64_retval
+# define int_retval lrv_r8
+#else
+# error "architecture specific code needed"
+#endif
+
+
+ElfW(Addr)
+pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+         uintptr_t *defcook, La_regs *regs, unsigned int *flags,
+         const char *symname, long int *framesizep)
+{
+  printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
+         symname, (long int) sym->st_value, ndx, *flags);
+
+  return sym->st_value;
+}
+
+unsigned int
+pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
+        uintptr_t *defcook, const La_regs *inregs, La_retval *outregs,
+        const char *symname)
+{
+  printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n",
+         symname, (long int) sym->st_value, ndx, outregs->int_retval);
+
+  return 0;
+}
index 4c1e1f0..96a37d0 100644 (file)
@@ -1,5 +1,5 @@
 # This file is updated automatically by Makefile.
 glibc-branch := fedora
 glibc-base := HEAD
-fedora-sync-date := 2005-01-06 22:03 UTC
-fedora-sync-tag := fedora-glibc-20050106T2203
+fedora-sync-date := 2005-02-08 09:48 UTC
+fedora-sync-tag := fedora-glibc-20050208T0948
index d063010..f508a0d 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 5
+%define glibcrelease 6
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define prelinkarches noarch
 %define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@@ -1270,6 +1270,33 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Tue Feb  8 2005 Jakub Jelinek <jakub@redhat.com> 2.3.4-6
+- update from CVS
+  - ld.so auditing
+  - fix segfault if chrooted app attempts to dlopen a library
+    and no standard library directory exists at all (#147067, #144303)
+  - fix initgroups when nscd is running, but has group caching disabled
+    (#146588)
+  - fix pthread_key_{create,destroy} in LinuxThreads when pthread_create
+    has not been called yet (#146710)
+  - fix ppc64 swapcontext and setcontext (#146736, BZ#700)
+  - service nscd cosmetic fixes (#146776)
+  - fix IA-32 and x86-64 stack alignment in DSO constructors (#145689)
+  - fix zdump -v segfaults on x86-64 (#146210)
+  - avoid calling sigaction (SIGPIPE, ...) inside syslog (#146021, IT#56686)
+  - fix errno values for futimes (BZ#633)
+  - unconditionally include <features.h> in malloc.h (BZ#650)
+  - change regex \B handling to match old GNU regex as well as perl/grep's dfa
+    (from empty string inside of word to empty string not at a word boundary,
+     BZ#693)
+  - slightly optimize i686 TLS accesses, use direct TLS %gs access in sem_*
+    and allow building -mno-tls-direct-seg-refs glibc that is free of direct TLS
+    %gs access with negative offsets
+  - fix addseverity
+  - fix fmemopen
+  - fix rewinddir
+  - increase svc{tcp,unix}_create listen backlog
+
 * Thu Jan  6 2005 Jakub Jelinek <jakub@redhat.com> 2.3.4-5
 - update from CVS
   - add some warn_unused_result marking
@@ -1279,7 +1306,7 @@ rm -f *.filelist*
 * Thu Jan  6 2005 Jakub Jelinek <jakub@redhat.com> 2.3.4-4
 - update from CVS
   - fix IA-32 stack alignment for LinuxThreads thread functions
-  and functions passed to clone(2) directly
+    and functions passed to clone(2) directly
   - fix ecvt{,_r} on denormals (#143279)
   - fix __tls_get_addr typo
   - fix rounding in IA-64 alarm (#143710)
index cb9b6b1..382d6a4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 96, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,96,98,99,2000,2005 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
@@ -44,8 +44,13 @@ putgrent (gr, stream)
 
   flockfile (stream);
 
-  retval = fprintf (stream, "%s:%s:%u:",
-                   gr->gr_name, _S (gr->gr_passwd), gr->gr_gid);
+  if (gr->gr_name[0] == '+' || gr->gr_name[0] == '-')
+    retval = fprintf (stream, "%s:%s::",
+                     gr->gr_name, _S (gr->gr_passwd));
+  else
+    retval = fprintf (stream, "%s:%s:%lu:",
+                     gr->gr_name, _S (gr->gr_passwd),
+                     (unsigned long int) gr->gr_gid);
   if (__builtin_expect (retval, 0) < 0)
     {
       funlockfile (stream);
index 450a385..1c6489b 100644 (file)
@@ -1,5 +1,5 @@
 /* longjmp cleanup function for unwinding past signal handlers.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2005 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
@@ -111,7 +111,7 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val)
       link = (void *) &scp[1];
       assert (! link->resource.next && ! link->resource.prevp);
       assert (link->thread.next == ss->active_resources);
-      assert (link->thread.prevp = &ss->active_resources);
+      assert (link->thread.prevp == &ss->active_resources);
       if (link->thread.next)
        link->thread.next->thread.prevp = &link->thread.next;
       ss->active_resources = link;
index 8685285..5b3d35e 100644 (file)
@@ -1,5 +1,5 @@
 /* Convert text in given files from the specified from-set to the to-set.
-   Copyright (C) 1998-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -239,26 +239,30 @@ main (int argc, char *argv[])
              if (from_wrong)
                {
                  if (to_wrong)
-                   error (EXIT_FAILURE, 0,
+                   error (0, 0,
                           _("\
 conversion from `%s' and to `%s' are not supported"),
                           from_pretty, to_pretty);
                  else
-                   error (EXIT_FAILURE, 0,
+                   error (0, 0,
                           _("conversion from `%s' is not supported"),
                           from_pretty);
                }
              else
                {
                  if (to_wrong)
-                   error (EXIT_FAILURE, 0,
+                   error (0, 0,
                           _("conversion to `%s' is not supported"),
                           to_pretty);
                  else
-                   error (EXIT_FAILURE, 0,
+                   error (0, 0,
                           _("conversion from `%s' to `%s' is not supported"),
                           from_pretty, to_pretty);
                }
+
+             argp_help (&argp, stderr, ARGP_HELP_SEE,
+                        program_invocation_short_name);
+             exit (1);
            }
          else
            error (EXIT_FAILURE, errno,
@@ -424,7 +428,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
index 0ed210b..8c56d29 100644 (file)
@@ -1,5 +1,5 @@
 /* Generate fastloading iconv module configuration files.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000-2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -397,7 +397,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
index e6feb2c..4a8f29a 100644 (file)
@@ -1,5 +1,5 @@
 /* C string table handling.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
    This program is free software; you can redistribute it and/or modify
@@ -326,7 +326,7 @@ strtabfinalize (struct Strtab *st, size_t *size)
   copylen = 1;
   copystrings (st->root, &endp, &copylen);
   assert (copylen == st->total + 1);
-  assert (endp = retval + st->total + 1);
+  assert (endp == retval + st->total + 1);
   *size = copylen;
 
   return retval;
index 9dea389..8255baf 100644 (file)
@@ -1,5 +1,5 @@
 /* Access functions for JISX0208 conversion.
-   Copyright (C) 1997, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,1999,2000,2003,2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
 #include <gconv.h>
 #include <stdint.h>
 
-/* Conversion table.  */
-extern const uint16_t __jis0208_to_ucs[];
-
-extern const char __jisx0208_from_ucs4_lat1[256][2];
-extern const char __jisx0208_from_ucs4_greek[0xc1][2];
-extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[];
-extern const char __jisx0208_from_ucs_tab[][2];
-
-
 /* Struct for table with indeces in UCS mapping table.  */
 struct jisx0208_ucs_idx
 {
@@ -42,6 +33,15 @@ struct jisx0208_ucs_idx
 };
 
 
+/* Conversion table.  */
+extern const uint16_t __jis0208_to_ucs[];
+
+extern const char __jisx0208_from_ucs4_lat1[256][2];
+extern const char __jisx0208_from_ucs4_greek[0xc1][2];
+extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[];
+extern const char __jisx0208_from_ucs_tab[][2];
+
+
 static inline uint32_t
 __attribute ((always_inline))
 jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
index bfa1b90..460c037 100644 (file)
@@ -7,9 +7,24 @@
 #define __RTLD_SPROF   0x40000000
 #define __RTLD_OPENEXEC        0x20000000
 #define __RTLD_CALLMAP 0x10000000
+#define __RTLD_AUDIT   0x08000000
 
 #define __LM_ID_CALLER -2
 
+#ifdef SHARED
+/* Locally stored program arguments.  */
+extern int __dlfcn_argc attribute_hidden;
+extern char **__dlfcn_argv attribute_hidden;
+#else
+/* These variables are defined and initialized in the startup code.  */
+extern int __libc_argc attribute_hidden;
+extern char **__libc_argv attribute_hidden;
+
+# define __dlfcn_argc __libc_argc
+# define __dlfcn_argv __libc_argv
+#endif
+
+
 /* Now define the internal interfaces.  */
 
 #define __libc_dlopen(name) \
@@ -29,18 +44,8 @@ extern int _dl_addr (const void *address, Dl_info *info,
 libc_hidden_proto (_dl_addr)
 #endif
 
-/* Open the shared object NAME, relocate it, and run its initializer if it
-   hasn't already been run.  MODE is as for `dlopen' (see <dlfcn.h>).  If
-   the object is already opened, returns its existing map.  */
-extern void *_dl_open (const char *name, int mode, const void *caller,
-                      Lmid_t nsid)
-     internal_function;
-libc_hidden_proto (_dl_open)
-
 /* Close an object previously opened by _dl_open.  */
-extern void _dl_close (void *map)
-     internal_function;
-libc_hidden_proto (_dl_close)
+extern void _dl_close (void *map) attribute_hidden;
 
 /* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or
    RTLD_NEXT).  WHO is the calling function, for RTLD_NEXT.  Returns
index 3078b72..9654191 100644 (file)
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005 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
@@ -34,6 +34,7 @@
 
 #include <bits/elfclass.h>             /* Defines __ELF_NATIVE_CLASS.  */
 #include <bits/link.h>
+#include <bits/linkmap.h>
 #include <dl-lookupcfg.h>
 #include <tls.h>               /* Defines USE_TLS.  */
 
@@ -199,6 +200,10 @@ struct link_map
                                       should be called on this link map
                                       when relocation finishes.  */
     unsigned int l_used:1;     /* Nonzero if the DSO is used.  */
+    unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing.  */
+    unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
+                                      is interested in the PLT interception.*/
+
     /* Array with version names.  */
     unsigned int l_nversions;
     struct r_found_version *l_versions;
@@ -207,7 +212,14 @@ struct link_map
     struct r_search_path_struct l_rpath_dirs;
 
     /* Collected results of relocation while profiling.  */
-    ElfW(Addr) *l_reloc_result;
+    struct reloc_result
+    {
+      DL_FIXUP_VALUE_TYPE addr;
+      struct link_map *bound;
+      unsigned int boundndx;
+      uint32_t enterexit;
+      unsigned int flags;
+    } *l_reloc_result;
 
     /* Pointer to the version information if available.  */
     ElfW(Versym) *l_versyms;
@@ -263,11 +275,7 @@ struct link_map
     {
       const ElfW(Sym) *sym;
       int type_class;
-#ifdef DL_LOOKUP_RETURNS_MAP
       struct link_map *value;
-#else
-      ElfW(Addr) value;
-#endif
       const ElfW(Sym) *ret;
     } l_lookup_cache;
 
@@ -297,8 +305,64 @@ struct link_map
        done.  */
     ElfW(Addr) l_relro_addr;
     size_t l_relro_size;
+
+    /* Audit information.  This array apparent must be the last in the
+       structure.  Never add something after it.  */
+    struct auditstate
+    {
+      uintptr_t cookie;
+      unsigned int bindflags;
+    } l_audit[0];
+  };
+
+/* Version numbers for la_version handshake interface.  */
+#define LAV_CURRENT    1
+
+/* Activity types signaled through la_activity.  */
+enum
+  {
+    LA_ACT_CONSISTENT,
+    LA_ACT_ADD,
+    LA_ACT_DELETE
+  };
+
+/* Values representing origin of name for dynamic loading.  */
+enum
+  {
+    LA_SER_ORIG = 0x01,                /* Original name.  */
+    LA_SER_LIBPATH = 0x02,     /* Directory from LD_LIBRARY_PATH.  */
+    LA_SER_RUNPATH = 0x04,     /* Directory from RPATH/RUNPATH.  */
+    LA_SER_CONFIG = 0x08,      /* Found through ldconfig.  */
+    LA_SER_DEFAULT = 0x40,     /* Default directory.  */
+    LA_SER_SECURE = 0x80       /* Unused.  */
+  };
+
+/* Values for la_objopen return value.  */
+enum
+  {
+    LA_FLG_BINDTO = 0x01,      /* Audit symbols bound to this object.  */
+    LA_FLG_BINDFROM = 0x02     /* Audit symbols bound from this object.  */
   };
 
+/* Values for la_symbind flags parameter.  */
+enum
+  {
+    LA_SYMB_NOPLTENTER = 0x01, /* la_pltenter will not be called.  */
+    LA_SYMB_NOPLTEXIT = 0x02,  /* la_pltexit will not be called.  */
+    LA_SYMB_STRUCTCALL = 0x04, /* Return value is a structure.  */
+    LA_SYMB_DLSYM = 0x08,      /* Binding due to dlsym call.  */
+    LA_SYMB_ALTVALUE = 0x10    /* Value has been changed by a previous
+                                  la_symbind call.  */
+  };
+
+#if __ELF_NATIVE_CLASS == 32
+# define symbind symbind32
+#elif __ELF_NATIVE_CLASS == 64
+# define symbind symbind64
+#else
+# error "__ELF_NATIVE_CLASS must be defined"
+#endif
+
 struct dl_phdr_info
   {
     ElfW(Addr) dlpi_addr;
index 51e849e..7c8769a 100644 (file)
@@ -71,6 +71,7 @@
 #include <libio.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
 #include "libioP.h"
index eba3d43..9c5503d 100644 (file)
@@ -37,6 +37,8 @@ static _IO_ssize_t _IO_cookie_read (register _IO_FILE* fp, void* buf,
 static _IO_ssize_t _IO_cookie_write (register _IO_FILE* fp,
                                     const void* buf, _IO_ssize_t size);
 static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir);
+static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
+                                      int dir, int mode);
 static int _IO_cookie_close (_IO_FILE* fp);
 
 static _IO_ssize_t
index 9b529dd..ac42b3e 100644 (file)
@@ -151,9 +151,9 @@ extern struct _IO_FILE *stderr;             /* Standard error output stream.  */
 
 __BEGIN_NAMESPACE_STD
 /* Remove file FILENAME.  */
-extern int remove (__const char *__filename) __THROW __wur;
+extern int remove (__const char *__filename) __THROW;
 /* Rename file OLD to NEW.  */
-extern int rename (__const char *__old, __const char *__new) __THROW __wur;
+extern int rename (__const char *__old, __const char *__new) __THROW;
 __END_NAMESPACE_STD
 
 
index ff1b7fe..329f2d8 100644 (file)
@@ -1,3 +1,26 @@
+2005-02-07  Jakub Jelinek  <jakub@redhat.com>
+
+       * specific.c (pthread_key_delete): If pthread_create has not been
+       called yet, clear p_specific for the current thread.
+       * Makefile (tests): Add tst-tsd1.
+       * tst-tsd1.c: New test.
+
+2005-01-08  Andreas Jaeger  <aj@suse.de>
+
+       * pthread.c (init_one_static_tls): Adjust initialization of DTV
+       entry for static tls deallocation fix.
+
+       * sysdeps/alpha/tls.h (dtv_t): Change pointer type to be struct which
+       also contains information whether the memory pointed to is static
+       TLS or not, include <stdbool.h>.
+       * sysdeps/i386/tls.h: Likewise.
+       * sysdeps/ia64/tls.h: Likewise.
+       * sysdeps/powerpc/tls.h: Likewise.
+       * sysdeps/s390/tls.h: Likewise.
+       * sysdeps/sh/tls.h: Likewise.
+       * sysdeps/sparc/tls.h: Likewise.
+       * sysdeps/x86_64/tls.h: Likewise.
+
 2004-12-21  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile (tests): Add tst-align.
index d9bf476..c2b548b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1996-2003, 2004, 2005 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
@@ -111,7 +111,7 @@ tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
        ex17 ex18 tst-cancel tst-context bug-sleep \
        tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
        tst-cancel6 tst-cancel7 tst-cancel8 tst-popen tst-popen2 tst-attr1 \
-       tst-stack1 tst-align
+       tst-stack1 tst-align tst-tsd1
 test-srcs = tst-signal
 # These tests are linked with libc before libpthread
 tests-reverse += tst-cancel5
index 24f0eb0..39863f2 100644 (file)
@@ -482,7 +482,8 @@ init_one_static_tls (pthread_descr descr, struct link_map *map)
 # endif
 
   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
-  dtv[map->l_tls_modid].pointer = dest;
+  dtv[map->l_tls_modid].pointer.val = dest;
+  dtv[map->l_tls_modid].pointer.is_static = true;
 
   /* Initialize the memory.  */
   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
index f54faba..92eec3d 100644 (file)
@@ -104,15 +104,16 @@ int pthread_key_delete(pthread_key_t key)
      that if the key is reallocated later by pthread_key_create, its
      associated values will be NULL in all threads.
 
-     Do nothing if no threads have been created yet.  */
+     If no threads have been created yet, clear it just in the
+     current thread.  */
 
+  struct pthread_key_delete_helper_args args;
+  args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
+  args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
   if (__pthread_manager_request != -1)
     {
-      struct pthread_key_delete_helper_args args;
       struct pthread_request request;
 
-      args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
-      args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
       args.self = 0;
 
       request.req_thread = self;
@@ -124,6 +125,11 @@ int pthread_key_delete(pthread_key_t key)
                                          (char *) &request, sizeof(request)));
       suspend(self);
     }
+  else
+    {
+      if (self->p_specific[args.idx1st] != NULL)
+       self->p_specific[args.idx1st][args.idx2nd] = NULL;
+    }
 
   pthread_mutex_unlock(&pthread_keys_mutex);
   return 0;
index 9e15318..1eabf5b 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/Alpha version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 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
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
index d296340..f5d555b 100644 (file)
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  linuxthreads/i386 version.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 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
@@ -24,6 +24,7 @@
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
index 6bdf819..fe8fcd1 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/IA-64 version.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 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
 
 # include <dl-sysdep.h>
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
index fda9539..3547208 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/PPC version.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005 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
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
@@ -107,9 +112,9 @@ typedef struct
 /* 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.
-   
-   The global register variable is declared in pt-machine.h with the 
-   wrong type, so we need some extra casts to get the desired result.  
+
+   The global register variable is declared in pt-machine.h with the
+   wrong type, so we need some extra casts to get the desired result.
    This avoids a lvalue cast that gcc-3.4 does not like.  */
 # define TLS_INIT_TP(TCBP, SECONDCALL) \
     (__thread_self = (struct _pthread_descr_struct *) \
index f420195..00a4df9 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/s390 version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 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
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
index bc9d44f..fbc6f01 100644 (file)
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  linuxthreads/SH version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 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
@@ -24,6 +24,7 @@
 # include <pt-machine.h>
 
 #ifndef __ASSEMBLER__
+# include <stdbool.h>
 # include <stddef.h>
 # include <stdint.h>
 
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 #else /* __ASSEMBLER__ */
index 5053824..3e550fa 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/sparc version.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2005 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
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 typedef struct
index d979bbd..67d80b2 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  linuxthreads/x86-64 version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2005 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
 #ifndef __ASSEMBLER__
 
 # include <pt-machine.h>
+# include <stdbool.h>
 # include <stddef.h>
 
 /* Type for the dtv.  */
 typedef union dtv
 {
   size_t counter;
-  void *pointer;
+  struct
+  {
+    void *val;
+    bool is_static;
+  } pointer;
 } dtv_t;
 
 
diff --git a/linuxthreads/tst-tsd1.c b/linuxthreads/tst-tsd1.c
new file mode 100644 (file)
index 0000000..ba7973f
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   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 <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+
+static int
+do_test (void)
+{
+  pthread_key_t key1;
+  pthread_key_t key2;
+  void *value;
+  int result = 0;
+  int err;
+
+  err = pthread_key_create (&key1, NULL);
+  if (err != 0)
+    {
+      printf ("1st key_create failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  /* Initial value must be NULL.  */
+  value = pthread_getspecific (key1);
+  if (value != NULL)
+    {
+      puts ("1st getspecific != NULL");
+      result = 1;
+    }
+
+  err = pthread_setspecific (key1, (void *) -2l);
+  if (err != 0)
+    {
+      printf ("1st setspecific failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  value = pthread_getspecific (key1);
+  if (value == NULL)
+    {
+      puts ("2nd getspecific == NULL\n");
+      result = 1;
+    }
+  else if (value != (void *) -2l)
+    {
+      puts ("2nd getspecific != -2l\n");
+      result = 1;
+    }
+
+  err = pthread_setspecific (key1, (void *) -3l);
+  if (err != 0)
+    {
+      printf ("2nd setspecific failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  value = pthread_getspecific (key1);
+  if (value == NULL)
+    {
+      puts ("3rd getspecific == NULL\n");
+      result = 1;
+    }
+  else if (value != (void *) -3l)
+    {
+      puts ("3rd getspecific != -2l\n");
+      result = 1;
+    }
+
+  err = pthread_key_delete (key1);
+  if (err != 0)
+    {
+      printf ("key_delete failed: %s\n", strerror (err));
+      result = 1;
+    }
+
+
+  err = pthread_key_create (&key2, NULL);
+  if (err != 0)
+    {
+      printf ("2nd key_create failed: %s\n", strerror (err));
+      return 1;
+    }
+
+  if (key1 != key2)
+    puts ("key1 != key2; no more tests performed");
+  else
+    {
+      value = pthread_getspecific (key2);
+      if (value != NULL)
+       {
+         puts ("4th getspecific != NULL");
+         result = 1;
+       }
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 338bf82..4bda6fb 100644 (file)
@@ -1,3 +1,7 @@
+2005-01-09  Andreas Jaeger  <aj@suse.de>
+
+       * td_thr_tlsbase.c (td_thr_tlsbase): Adjust for dtv change.
+
 2004-05-01  Jakub Jelinek  <jakub@redhat.com>
 
        * thread_dbP.h (LOG): Use write instead of __libc_write.
index 081e8d0..5a7e31b 100644 (file)
@@ -1,5 +1,5 @@
 /* Locate TLS data for a thread.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005 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
@@ -59,10 +59,10 @@ td_thr_tlsbase (const td_thrhandle_t *th,
 
   /* It could be that the memory for this module is not allocated for
      the given thread.  */
-  if (pdtv.pointer == TLS_DTV_UNALLOCATED)
+  if (pdtv.pointer.val == TLS_DTV_UNALLOCATED)
     return TD_TLSDEFER;
 
-  *base = (char *) pdtv.pointer;
+  *base = (char *) pdtv.pointer.val;
 
   return TD_OK;
 #else
index adf9944..d64bb0b 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of the locale program according to POSIX 9945-2.
-   Copyright (C) 1995-1997, 1999-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 1999-2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1995.
 
@@ -277,7 +277,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
index 28cb7b3..326113c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1995.
 
@@ -389,7 +389,7 @@ print_version (FILE *stream, struct argp_state *state)
 Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2004");
+"), "2005");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
index e3ccbde..4d2169b 100644 (file)
@@ -1,5 +1,5 @@
   /* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>
    and Doug Lea <dl@cs.oswego.edu>, 2001.
@@ -5508,6 +5508,8 @@ int mALLOPt(param_number, value) int param_number; int value;
 
 /* Helper code.  */
 
+extern char **__libc_argv attribute_hidden;
+
 static void
 malloc_printerr(int action, const char *str, void *ptr)
 {
@@ -5522,8 +5524,8 @@ malloc_printerr(int action, const char *str, void *ptr)
 
       __libc_message (action & 2,
                      action & 4
-                     ? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n",
-                     str, cp);
+                     ? "%s\n" : "*** glibc detected *** %s: %s: 0x%s ***\n",
+                     __libc_argv[0] ?: "<unknown>", str, cp);
     }
   else if (action & 2)
     abort ();
index 753539e..0f99e83 100644 (file)
@@ -1,5 +1,5 @@
 /* Prototypes and definition for malloc implementation.
-   Copyright (C) 1996,97,99,2000,2002,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1996,97,99,2000,2002-2004,2005 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
 #ifndef _MALLOC_H
 #define _MALLOC_H 1
 
-#ifdef _LIBC
 #include <features.h>
-#endif
-
-/*
-  $Id$
-  `ptmalloc2', a malloc implementation for multiple threads without
-  lock contention, by Wolfram Gloger <wg@malloc.de>.
-
-  VERSION 2.7.0
-
-  This work is mainly derived from malloc-2.7.0 by Doug Lea
-  <dl@cs.oswego.edu>, which is available from:
-
-                 ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-
-  This trimmed-down header file only provides function prototypes and
-  the exported data structures.  For more detailed function
-  descriptions and compile-time options, see the source file
-  `malloc.c'.
-*/
-
-#if defined(__STDC__) || defined (__cplusplus)
-# include <stddef.h>
+#include <stddef.h>
 # define __malloc_ptr_t  void *
-#else
-# undef  size_t
-# define size_t          unsigned int
-# undef  ptrdiff_t
-# define ptrdiff_t       int
-# define __malloc_ptr_t  char *
-#endif
 
-#ifdef _LIBC
 /* Used by GNU libc internals. */
-# define __malloc_size_t size_t
-# define __malloc_ptrdiff_t ptrdiff_t
-#elif !defined __attribute_malloc__
-# define __attribute_malloc__
-#endif
+#define __malloc_size_t size_t
+#define __malloc_ptrdiff_t ptrdiff_t
 
 #ifdef __GNUC__
 
-/* GCC can always grok prototypes.  For C++ programs we add throw()
-   to help it optimize the function calls.  But this works only with
-   gcc 2.8.x and egcs.  */
-# ifndef __THROW
-#  if defined __cplusplus && (__GNUC__ >= 3 || __GNUC_MINOR__ >= 8)
-#   define __THROW     throw ()
-#  else
-#   define __THROW
-#  endif
-# endif
 # define __MALLOC_P(args)      args __THROW
 /* This macro will be used for functions which might take C++ callback
    functions.  */
 
 #else  /* Not GCC.  */
 
-# define __THROW
-
-# if (defined __STDC__ && __STDC__) || defined __cplusplus
-
-#  define __MALLOC_P(args)     args
-#  define __MALLOC_PMT(args)   args
-
-#  ifndef __const
-#   define __const      const
-#  endif
-
-# else /* Not ANSI C or C++.  */
-
-#  define __MALLOC_P(args)     ()      /* No prototypes.  */
-#  define __MALLOC_PMT(args)   ()
-
-#  ifndef __const
-#   define __const
-#  endif
-
-# endif        /* ANSI C or C++.  */
+# define __MALLOC_P(args)      args
+# define __MALLOC_PMT(args)    args
 
 #endif /* GCC.  */
 
-#ifndef NULL
-# ifdef __cplusplus
-#  define NULL 0
-# else
-#  define NULL ((__malloc_ptr_t) 0)
-# endif
-#endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /* Allocate SIZE bytes of memory.  */
-extern __malloc_ptr_t malloc __MALLOC_P ((size_t __size)) __attribute_malloc__;
+extern void *malloc __MALLOC_P ((size_t __size)) __attribute_malloc__ __wur;
 
 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0.  */
-extern __malloc_ptr_t calloc __MALLOC_P ((size_t __nmemb, size_t __size))
-       __attribute_malloc__;
+extern void *calloc __MALLOC_P ((size_t __nmemb, size_t __size))
+       __attribute_malloc__ __wur;
 
 /* Re-allocate the previously allocated block in __ptr, making the new
    block SIZE bytes long.  */
-extern __malloc_ptr_t realloc __MALLOC_P ((__malloc_ptr_t __ptr,
-                                          size_t __size))
-       __attribute_malloc__;
+extern void *realloc __MALLOC_P ((void *__ptr, size_t __size))
+       __attribute_malloc__ __attribute_warn_unused_result__;
 
 /* Free a block allocated by `malloc', `realloc' or `calloc'.  */
-extern void free __MALLOC_P ((__malloc_ptr_t __ptr));
+extern void free __MALLOC_P ((void *__ptr));
 
 /* Free a block allocated by `calloc'. */
-extern void cfree __MALLOC_P ((__malloc_ptr_t __ptr));
+extern void cfree __MALLOC_P ((void *__ptr));
 
 /* Allocate SIZE bytes allocated to ALIGNMENT bytes.  */
-extern __malloc_ptr_t memalign __MALLOC_P ((size_t __alignment, size_t __size));
+extern void *memalign __MALLOC_P ((size_t __alignment, size_t __size))
+       __attribute_malloc__ __wur;
 
 /* Allocate SIZE bytes on a page boundary.  */
-extern __malloc_ptr_t valloc __MALLOC_P ((size_t __size)) __attribute_malloc__;
+extern void *valloc __MALLOC_P ((size_t __size))
+       __attribute_malloc__ __wur;
 
 /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
    __size to nearest pagesize. */
-extern __malloc_ptr_t  pvalloc __MALLOC_P ((size_t __size))
-       __attribute_malloc__;
+extern void * pvalloc __MALLOC_P ((size_t __size))
+       __attribute_malloc__ __wur;
 
 /* Underlying allocation function; successive calls should return
    contiguous pieces of memory.  */
-extern __malloc_ptr_t (*__morecore) __MALLOC_PMT ((ptrdiff_t __size));
+extern void *(*__morecore) __MALLOC_PMT ((ptrdiff_t __size));
 
 /* Default value of `__morecore'.  */
-extern __malloc_ptr_t __default_morecore __MALLOC_P ((ptrdiff_t __size))
+extern void *__default_morecore __MALLOC_P ((ptrdiff_t __size))
        __attribute_malloc__;
 
 /* SVID2/XPG mallinfo structure */
@@ -202,41 +132,38 @@ extern int malloc_trim __MALLOC_P ((size_t __pad));
 
 /* Report the number of usable allocated bytes associated with allocated
    chunk __ptr. */
-extern size_t malloc_usable_size __MALLOC_P ((__malloc_ptr_t __ptr));
+extern size_t malloc_usable_size __MALLOC_P ((void *__ptr));
 
 /* Prints brief summary statistics on stderr. */
 extern void malloc_stats __MALLOC_P ((void));
 
 /* Record the state of all malloc variables in an opaque data structure. */
-extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void));
+extern void *malloc_get_state __MALLOC_P ((void));
 
 /* Restore the state of all malloc variables from data obtained with
    malloc_get_state(). */
-extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr));
+extern int malloc_set_state __MALLOC_P ((void *__ptr));
 
 /* Called once when malloc is initialized; redefining this variable in
    the application provides the preferred way to set up the hook
    pointers. */
 extern void (*__malloc_initialize_hook) __MALLOC_PMT ((void));
 /* Hooks for debugging and user-defined versions. */
-extern void (*__free_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
+extern void (*__free_hook) __MALLOC_PMT ((void *__ptr,
                                        __const __malloc_ptr_t));
-extern __malloc_ptr_t (*__malloc_hook) __MALLOC_PMT ((size_t __size,
-                                                   __const __malloc_ptr_t));
-extern __malloc_ptr_t (*__realloc_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
-                                                    size_t __size,
-                                                    __const __malloc_ptr_t));
-extern __malloc_ptr_t (*__memalign_hook) __MALLOC_PMT ((size_t __alignment,
-                                                     size_t __size,
-                                                     __const __malloc_ptr_t));
+extern void *(*__malloc_hook) __MALLOC_PMT ((size_t __size,
+                                            __const __malloc_ptr_t));
+extern void *(*__realloc_hook) __MALLOC_PMT ((void *__ptr, size_t __size,
+                                             __const __malloc_ptr_t));
+extern void *(*__memalign_hook) __MALLOC_PMT ((size_t __alignment,
+                                              size_t __size,
+                                              __const __malloc_ptr_t));
 extern void (*__after_morecore_hook) __MALLOC_PMT ((void));
 
 /* Activate a standard set of debugging hooks. */
 extern void __malloc_check_init __MALLOC_P ((void));
 
 
-#ifdef __cplusplus
-} /* end of extern "C" */
-#endif
+__END_DECLS
 
 #endif /* malloc.h */
index be8f755..b2e08c6 100755 (executable)
@@ -1,5 +1,5 @@
 #! @BASH@
-# Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+# Copyright (C) 1999-2004, 2005 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@gnu.org>, 1999.
 
@@ -71,7 +71,7 @@ do_version() {
   printf $"Copyright (C) %s Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-" "2004"
+" "2005"
   printf $"Written by %s.
 " "Ulrich Drepper"
   exit 0
index 1640fa6..0036f33 100644 (file)
@@ -45,7 +45,7 @@ arglist: while (@ARGV) {
        $ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
        $ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
        print "mtrace (GNU $PACKAGE) $VERSION\n";
-       print "Copyright (C) 2004 Free Software Foundation, Inc.\n";
+       print "Copyright (C) 2005 Free Software Foundation, Inc.\n";
        print "This is free software; see the source for copying conditions.  There is NO\n";
        print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
        print "Written by Ulrich Drepper <drepper\@gnu.org>\n";
index f1254e9..54abbbb 100644 (file)
@@ -9,6 +9,6 @@ glibc-*
 *.cp *.cps *.fn *.fns *.vr *.vrs *.tp *.tps *.ky *.kys *.pg *.pgs
 
 texis top-menu.texi chapters.texi summary.texi stamp-*
-distinfo dir-add.texinfo
+distinfo dir-add.texinfo dir-add.texi
 
 libm-err.texi
index 91abb7f..ee2cd75 100644 (file)
@@ -2384,7 +2384,7 @@ exceed the process' data storage limit.
 
 @comment unistd.h
 @comment BSD
-@deftypefun int sbrk (ptrdiff_t @var{delta})
+@deftypefun void *sbrk (ptrdiff_t @var{delta})
 This function is the same as @code{brk} except that you specify the new
 end of the data segment as an offset @var{delta} from the current end
 and on success the return value is the address of the resulting end of
index 21ab714..d9de129 100644 (file)
@@ -1781,9 +1781,9 @@ uppercase and lowercase characters are related.
 
 For example,
 @smallexample
-strstr ("hello, world", "L")
+strcasestr ("hello, world", "L")
     @result{} "llo, world"
-strstr ("hello, World", "wo")
+strcasestr ("hello, World", "wo")
     @result{} "World"
 @end smallexample
 @end deftypefun
index 20deeab..b52ee44 100644 (file)
@@ -1690,6 +1690,9 @@ extended information about users, adding an entry using this function
 would inevitably leave out much of the important information.
 @c Then how are programmers to modify the password file? -zw
 
+The group and user ID fields are left empty if the group or user name
+starts with a - or +.
+
 The function @code{putpwent} is declared in @file{pwd.h}.
 @end deftypefun
 
index f545841..a6a85d3 100644 (file)
@@ -192,6 +192,10 @@ extern int    __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*);
 /* internal functions.  */
 extern double __copysign (double x, double __y);
 
+#if __GNUC_PREREQ (4, 0)
+extern inline double __copysign (double x, double y)
+{ return __builtin_copysign (x, y); }
+#endif
 
 /* ieee style elementary float functions */
 extern float __ieee754_sqrtf (float);
@@ -235,6 +239,10 @@ extern int   __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*);
 /* internal functions.  */
 extern float __copysignf (float x, float __y);
 
+#if __GNUC_PREREQ (4, 0)
+extern inline float __copysignf (float x, float y)
+{ return __builtin_copysignf (x, y); }
+#endif
 
 /* ieee style elementary long double functions */
 extern long double __ieee754_sqrtl (long double);
@@ -298,6 +306,12 @@ extern long double fabsl (long double x);
 extern void __sincosl (long double, long double *, long double *);
 extern long double __logbl (long double x);
 extern long double __significandl (long double x);
+
+#if __GNUC_PREREQ (4, 0)
+extern inline long double __copysignl (long double x, long double y)
+{ return __builtin_copysignl (x, y); }
+#endif
+
 #endif
 
 /* Prototypes for functions of the IBM Accurate Mathematical Library.  */
index 6ac2101..8d529bf 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2001, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2001, 2002, 2004, 2005 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
 
 /* If fortification mode, we warn about unused results of certain
    function calls which can lead to problems.  */
-#if __GNUC_PREREQ (3,4) && __USE_FORTIFY_LEVEL > 0
-# define __wur __attribute__ ((__warn_unused_result__))
+#if __GNUC_PREREQ (3,4)
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+# if __USE_FORTIFY_LEVEL > 0
+#  define __wur __attribute_warn_unused_result__
+# endif
 #else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+#ifndef __wur
 # define __wur /* Ignore */
 #endif
 
diff --git a/misc/syslog.c b/misc/syslog.c
deleted file mode 100644 (file)
index 6916356..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright (c) 1983, 1988, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)syslog.c   8.4 (Berkeley) 3/18/94";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <sys/uio.h>
-#include <netdb.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <bits/libc-lock.h>
-#include <signal.h>
-#include <locale.h>
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#include <libio/iolibio.h>
-#define ftell(s) INTUSE(_IO_ftell) (s)
-
-static int     LogType = SOCK_DGRAM;   /* type of socket connection */
-static int     LogFile = -1;           /* fd for log */
-static int     connected;              /* have done connect */
-static int     LogStat;                /* status bits, set by openlog() */
-static const char *LogTag;             /* string to tag the entry with */
-static int     LogFacility = LOG_USER; /* default facility code */
-static int     LogMask = 0xff;         /* mask of priorities to be logged */
-extern char    *__progname;            /* Program name, from crt0. */
-
-/* Define the lock.  */
-__libc_lock_define_initialized (static, syslog_lock)
-
-static void openlog_internal(const char *, int, int) internal_function;
-static void closelog_internal(void);
-static void sigpipe_handler (int);
-
-
-struct cleanup_arg
-{
-  void *buf;
-  struct sigaction *oldaction;
-};
-
-static void
-cancel_handler (void *ptr)
-{
-  /* Restore the old signal handler.  */
-  struct cleanup_arg *clarg = (struct cleanup_arg *) ptr;
-
-  if (clarg != NULL && clarg->oldaction != NULL)
-    __sigaction (SIGPIPE, clarg->oldaction, NULL);
-
-  /* Free the lock.  */
-  __libc_lock_unlock (syslog_lock);
-}
-
-
-/*
- * syslog, vsyslog --
- *     print message on log file; output is intended for syslogd(8).
- */
-void
-#if __STDC__
-syslog(int pri, const char *fmt, ...)
-#else
-syslog(pri, fmt, va_alist)
-       int pri;
-       char *fmt;
-       va_dcl
-#endif
-{
-       va_list ap;
-
-#if __STDC__
-       va_start(ap, fmt);
-#else
-       va_start(ap);
-#endif
-       vsyslog(pri, fmt, ap);
-       va_end(ap);
-}
-libc_hidden_def (syslog)
-
-void
-vsyslog(pri, fmt, ap)
-       int pri;
-       register const char *fmt;
-       va_list ap;
-{
-       struct tm now_tm;
-       time_t now;
-       int fd;
-       FILE *f;
-       char *buf = 0;
-       size_t bufsize = 0;
-       size_t prioff, msgoff;
-       struct sigaction action, oldaction;
-       int sigpipe;
-       int saved_errno = errno;
-       char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];
-
-#define        INTERNALLOG     LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
-       /* Check for invalid bits. */
-       if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
-               syslog(INTERNALLOG,
-                   "syslog: unknown facility/priority: %x", pri);
-               pri &= LOG_PRIMASK|LOG_FACMASK;
-       }
-
-       /* Check priority against setlogmask values. */
-       if ((LOG_MASK (LOG_PRI (pri)) & LogMask) == 0)
-               return;
-
-       /* Set default facility if none specified. */
-       if ((pri & LOG_FACMASK) == 0)
-               pri |= LogFacility;
-
-       /* Build the message in a memory-buffer stream.  */
-       f = open_memstream (&buf, &bufsize);
-       if (f == NULL)
-         {
-           /* We cannot get a stream.  There is not much we can do but
-              emitting an error messages.  */
-           char numbuf[3 * sizeof (pid_t)];
-           char *nump;
-           char *endp = __stpcpy (failbuf, "out of memory [");
-           pid_t pid = __getpid ();
-
-           nump = numbuf + sizeof (numbuf);
-           /* The PID can never be zero.  */
-           do
-             *--nump = '0' + pid % 10;
-           while ((pid /= 10) != 0);
-
-           endp = __mempcpy (endp, nump, (numbuf + sizeof (numbuf)) - nump);
-           *endp++ = ']';
-           *endp = '\0';
-           buf = failbuf;
-           bufsize = endp - failbuf;
-           msgoff = 0;
-         }
-       else
-         {
-           __fsetlocking (f, FSETLOCKING_BYCALLER);
-           prioff = fprintf (f, "<%d>", pri);
-           (void) time (&now);
-           f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
-                                             f->_IO_write_end
-                                             - f->_IO_write_ptr,
-                                             "%h %e %T ",
-                                             __localtime_r (&now, &now_tm),
-                                             &_nl_C_locobj);
-           msgoff = ftell (f);
-           if (LogTag == NULL)
-             LogTag = __progname;
-           if (LogTag != NULL)
-             fputs_unlocked (LogTag, f);
-           if (LogStat & LOG_PID)
-             fprintf (f, "[%d]", (int) __getpid ());
-           if (LogTag != NULL)
-             {
-               putc_unlocked (':', f);
-               putc_unlocked (' ', f);
-             }
-
-           /* Restore errno for %m format.  */
-           __set_errno (saved_errno);
-
-           /* We have the header.  Print the user's format into the
-               buffer.  */
-           vfprintf (f, fmt, ap);
-
-           /* Close the memory stream; this will finalize the data
-              into a malloc'd buffer in BUF.  */
-           fclose (f);
-         }
-
-       /* Output to stderr if requested. */
-       if (LogStat & LOG_PERROR) {
-               struct iovec iov[2];
-               register struct iovec *v = iov;
-
-               v->iov_base = buf + msgoff;
-               v->iov_len = bufsize - msgoff;
-               /* Append a newline if necessary.  */
-               if (buf[bufsize - 1] != '\n')
-                 {
-                   ++v;
-                   v->iov_base = (char *) "\n";
-                   v->iov_len = 1;
-                 }
-
-               __libc_cleanup_push (free, buf == failbuf ? NULL : buf);
-
-               /* writev is a cancellation point.  */
-               (void)__writev(STDERR_FILENO, iov, v - iov + 1);
-
-               __libc_cleanup_pop (0);
-       }
-
-       /* Prepare for multiple users.  We have to take care: open and
-          write are cancellation points.  */
-       struct cleanup_arg clarg;
-       clarg.buf = buf;
-       clarg.oldaction = NULL;
-       __libc_cleanup_push (cancel_handler, &clarg);
-       __libc_lock_lock (syslog_lock);
-
-       /* Prepare for a broken connection.  */
-       memset (&action, 0, sizeof (action));
-       action.sa_handler = sigpipe_handler;
-       sigemptyset (&action.sa_mask);
-       sigpipe = __sigaction (SIGPIPE, &action, &oldaction);
-       if (sigpipe == 0)
-         clarg.oldaction = &oldaction;
-
-       /* Get connected, output the message to the local logger. */
-       if (!connected)
-               openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
-
-       /* If we have a SOCK_STREAM connection, also send ASCII NUL as
-          a record terminator.  */
-       if (LogType == SOCK_STREAM)
-         ++bufsize;
-
-       if (!connected || __send(LogFile, buf, bufsize, 0) < 0)
-         {
-           if (connected)
-             {
-               /* Try to reopen the syslog connection.  Maybe it went
-                  down.  */
-               closelog_internal ();
-               openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
-             }
-
-           if (!connected || __send(LogFile, buf, bufsize, 0) < 0)
-             {
-               closelog_internal ();   /* attempt re-open next time */
-               /*
-                * Output the message to the console; don't worry
-                * about blocking, if console blocks everything will.
-                * Make sure the error reported is the one from the
-                * syslogd failure.
-                */
-               if (LogStat & LOG_CONS &&
-                   (fd = __open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)
-                 {
-                   dprintf (fd, "%s\r\n", buf + msgoff);
-                   (void)__close(fd);
-                 }
-             }
-         }
-
-       if (sigpipe == 0)
-               __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
-
-       /* End of critical section.  */
-       __libc_cleanup_pop (0);
-       __libc_lock_unlock (syslog_lock);
-
-       if (buf != failbuf)
-               free (buf);
-}
-libc_hidden_def (vsyslog)
-
-static struct sockaddr SyslogAddr;     /* AF_UNIX address of local logger */
-
-
-static void
-internal_function
-openlog_internal(const char *ident, int logstat, int logfac)
-{
-       if (ident != NULL)
-               LogTag = ident;
-       LogStat = logstat;
-       if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
-               LogFacility = logfac;
-
-       int retry = 0;
-       while (retry < 2) {
-               if (LogFile == -1) {
-                       SyslogAddr.sa_family = AF_UNIX;
-                       (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
-                                     sizeof(SyslogAddr.sa_data));
-                       if (LogStat & LOG_NDELAY) {
-                               if ((LogFile = __socket(AF_UNIX, LogType, 0))
-                                   == -1)
-                                       return;
-                               (void)__fcntl(LogFile, F_SETFD, 1);
-                       }
-               }
-               if (LogFile != -1 && !connected)
-               {
-                       int old_errno = errno;
-                       if (__connect(LogFile, &SyslogAddr, sizeof(SyslogAddr))
-                           == -1)
-                       {
-                               int saved_errno = errno;
-                               int fd = LogFile;
-                               LogFile = -1;
-                               (void)__close(fd);
-                               __set_errno (old_errno);
-                               if (saved_errno == EPROTOTYPE)
-                               {
-                                       /* retry with the other type: */
-                                       LogType = (LogType == SOCK_DGRAM
-                                                  ? SOCK_STREAM : SOCK_DGRAM);
-