This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Move ldsodefs.h audit definitions to sysdeps directories


On 07/19/2012 02:36 AM, Joseph S. Myers wrote:
> Continuing the process of moving system-specific configuration to
> sysdeps directories (making libc targets more like ports ones), this
> patch moves the architecture-specific pltenter and pltexit members of
> struct audit_ifaces in sysdeps/generic/ldsodefs.h to
> architecture-specific ldsodefs.h files, in the same way already used
> for ports architectures.
> 
> Tested x86 and x86_64.  Could architecture maintainers test/review for
> the other architectures?

No regressions on s390 and s390x.

Bye,

-Andreas-

> 2012-07-18  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* sysdeps/generic/ldsodefs.h (struct La_i86_regs): Remove.
> 	(struct La_i86_retval): Likewise.
> 	(struct La_x86_64_regs): Likewise.
> 	(struct La_x86_64_retval): Likewise.
> 	(struct La_x32_regs): Likewise.
> 	(struct La_x32_retval): Likewise.
> 	(struct La_ppc32_regs): Likewise.
> 	(struct La_ppc32_retval): Likewise.
> 	(struct La_ppc64_regs): Likewise.
> 	(struct La_ppc64_retval): Likewise.
> 	(struct La_sh_regs): Likewise.
> 	(struct La_sh_retval): Likewise.
> 	(struct La_s390_32_regs): Likewise.
> 	(struct La_s390_32_retval): Likewise.
> 	(struct La_s390_64_regs): Likewise.
> 	(struct La_s390_64_retval): Likewise.
> 	(struct La_sparc32_regs): Likewise.
> 	(struct La_sparc32_retval): Likewise.
> 	(struct La_sparc64_regs): Likewise.
> 	(struct La_sparc64_retval): Likewise.
> 	(struct audit_ifaces): Remove architecture-specific pltenter and
> 	pltexit members.
> 	* sysdeps/i386/ldsodefs.h: New file.
> 	* sysdeps/powerpc/ldsodefs.h: Likewise.
> 	* sysdeps/s390/ldsodefs.h: Likewise.
> 	* sysdeps/sh/ldsodefs.h: Likewise.
> 	* sysdeps/sparc/ldsodefs.h: Likewise.
> 	* sysdeps/x86_64/ldsodefs.h: Likewise.
> 
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index 98cc123..39c6339 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -182,28 +182,6 @@ enum allowmask
>    };
> 
> 
> -/* Type for list of auditing interfaces.  */
> -struct La_i86_regs;
> -struct La_i86_retval;
> -struct La_x86_64_regs;
> -struct La_x86_64_retval;
> -struct La_x32_regs;
> -struct La_x32_retval;
> -struct La_ppc32_regs;
> -struct La_ppc32_retval;
> -struct La_ppc64_regs;
> -struct La_ppc64_retval;
> -struct La_sh_regs;
> -struct La_sh_retval;
> -struct La_s390_32_regs;
> -struct La_s390_32_retval;
> -struct La_s390_64_regs;
> -struct La_s390_64_retval;
> -struct La_sparc32_regs;
> -struct La_sparc32_retval;
> -struct La_sparc64_regs;
> -struct La_sparc64_retval;
> -
>  struct audit_ifaces
>  {
>    void (*activity) (uintptr_t *, unsigned int);
> @@ -219,98 +197,12 @@ struct audit_ifaces
>    };
>    union
>    {
> -    Elf32_Addr (*i86_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				    uintptr_t *, struct La_i86_regs *,
> -				    unsigned int *, const char *name,
> -				    long int *framesizep);
> -    Elf64_Addr (*x86_64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
> -				       uintptr_t *, struct La_x86_64_regs *,
> -				       unsigned int *, const char *name,
> -				       long int *framesizep);
> -    Elf32_Addr (*x32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				    uintptr_t *, struct La_x32_regs *,
> -				    unsigned int *, const char *name,
> -				    long int *framesizep);
> -    Elf32_Addr (*ppc32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				      uintptr_t *, struct La_ppc32_regs *,
> -				      unsigned int *, const char *name,
> -				      long int *framesizep);
> -    Elf64_Addr (*ppc64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
> -				      uintptr_t *, struct La_ppc64_regs *,
> -				      unsigned int *, const char *name,
> -				      long int *framesizep);
> -    uintptr_t (*sh_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				  uintptr_t *, const struct La_sh_regs *,
> -				  unsigned int *, const char *name,
> -				  long int *framesizep);
> -    Elf32_Addr (*s390_32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *,
> -					uintptr_t *, struct La_s390_32_regs *,
> -					unsigned int *, const char *name,
> -					long int *framesizep);
> -    Elf64_Addr (*s390_64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *,
> -					uintptr_t *, struct La_s390_64_regs *,
> -					unsigned int *, const char *name,
> -					long int *framesizep);
> -    Elf32_Addr (*sparc32_gnu_pltenter) (Elf32_Sym *, unsigned int,
> -					uintptr_t *, uintptr_t *,
> -					const struct La_sparc32_regs *,
> -					unsigned int *, const char *name,
> -					long int *framesizep);
> -    Elf64_Addr (*sparc64_gnu_pltenter) (Elf64_Sym *, unsigned int,
> -					uintptr_t *, uintptr_t *,
> -					const struct La_sparc64_regs *,
> -					unsigned int *, const char *name,
> -					long int *framesizep);
>  #ifdef ARCH_PLTENTER_MEMBERS
>      ARCH_PLTENTER_MEMBERS;
>  #endif
>    };
>    union
>    {
> -    unsigned int (*i86_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				     uintptr_t *, const struct La_i86_regs *,
> -				     struct La_i86_retval *, const char *);
> -    unsigned int (*x86_64_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
> -					uintptr_t *,
> -					const struct La_x86_64_regs *,
> -					struct La_x86_64_retval *,
> -					const char *);
> -    unsigned int (*x32_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				     uintptr_t *,
> -				     const struct La_x32_regs *,
> -				     struct La_x86_64_retval *,
> -				     const char *);
> -    unsigned int (*ppc32_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				       uintptr_t *,
> -				       const struct La_ppc32_regs *,
> -				       struct La_ppc32_retval *, const char *);
> -    unsigned int (*ppc64_gnu_pltexit) (Elf64_Sym *, unsigned int, uintptr_t *,
> -				       uintptr_t *,
> -				       const struct La_ppc64_regs *,
> -				       struct La_ppc64_retval *, const char *);
> -    unsigned int (*sh_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *,
> -				    uintptr_t *, const struct La_sh_regs *,
> -				    struct La_sh_retval *, const char *);
> -    unsigned int (*s390_32_gnu_pltexit) (Elf32_Sym *, unsigned int,
> -					 uintptr_t *, uintptr_t *,
> -					 const struct La_s390_32_regs *,
> -					 struct La_s390_32_retval *,
> -					 const char *);
> -    unsigned int (*s390_64_gnu_pltexit) (Elf64_Sym *, unsigned int,
> -					 uintptr_t *, uintptr_t *,
> -					 const struct La_s390_64_regs *,
> -					 struct La_s390_64_retval *,
> -					 const char *);
> -    unsigned int (*sparc32_gnu_pltexit) (Elf32_Sym *, unsigned int,
> -					 uintptr_t *, uintptr_t *,
> -					 const struct La_sparc32_regs *,
> -					 struct La_sparc32_retval *,
> -					 const char *);
> -    unsigned int (*sparc64_gnu_pltexit) (Elf64_Sym *, unsigned int,
> -					 uintptr_t *, uintptr_t *,
> -					 const struct La_sparc32_regs *,
> -					 struct La_sparc32_retval *,
> -					 const char *);
>  #ifdef ARCH_PLTEXIT_MEMBERS
>      ARCH_PLTEXIT_MEMBERS;
>  #endif
> diff --git a/sysdeps/i386/ldsodefs.h b/sysdeps/i386/ldsodefs.h
> new file mode 100644
> index 0000000..74880e9
> --- /dev/null
> +++ b/sysdeps/i386/ldsodefs.h
> @@ -0,0 +1,40 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_I386_LDSODEFS_H
> +#define	_I386_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_i86_regs;
> +struct La_i86_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    Elf32_Addr (*i86_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				    uintptr_t *, struct La_i86_regs *,	\
> +				    unsigned int *, const char *name,	\
> +				    long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*i86_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				     uintptr_t *, const struct La_i86_regs *, \
> +				     struct La_i86_retval *, const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> diff --git a/sysdeps/powerpc/ldsodefs.h b/sysdeps/powerpc/ldsodefs.h
> new file mode 100644
> index 0000000..4a54349
> --- /dev/null
> +++ b/sysdeps/powerpc/ldsodefs.h
> @@ -0,0 +1,54 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_POWERPC_LDSODEFS_H
> +#define	_POWERPC_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_ppc32_regs;
> +struct La_ppc32_retval;
> +struct La_ppc64_regs;
> +struct La_ppc64_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    Elf32_Addr (*ppc32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				      uintptr_t *, struct La_ppc32_regs *, \
> +				      unsigned int *, const char *name,	\
> +				      long int *framesizep);		\
> +    Elf64_Addr (*ppc64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *, \
> +				      uintptr_t *, struct La_ppc64_regs *, \
> +				      unsigned int *, const char *name,	\
> +				      long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*ppc32_gnu_pltexit) (Elf32_Sym *, unsigned int,	\
> +				       uintptr_t *,			\
> +				       uintptr_t *,			\
> +				       const struct La_ppc32_regs *,	\
> +				       struct La_ppc32_retval *,	\
> +				       const char *);			\
> +    unsigned int (*ppc64_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
> +				       uintptr_t *,			\
> +				       uintptr_t *,			\
> +				       const struct La_ppc64_regs *,	\
> +				       struct La_ppc64_retval *, const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> diff --git a/sysdeps/s390/ldsodefs.h b/sysdeps/s390/ldsodefs.h
> new file mode 100644
> index 0000000..e5e3168
> --- /dev/null
> +++ b/sysdeps/s390/ldsodefs.h
> @@ -0,0 +1,57 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_S390_LDSODEFS_H
> +#define	_S390_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_s390_32_regs;
> +struct La_s390_32_retval;
> +struct La_s390_64_regs;
> +struct La_s390_64_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    Elf32_Addr (*s390_32_gnu_pltenter) (Elf32_Sym *, unsigned int,	\
> +					uintptr_t *,			\
> +					uintptr_t *,			\
> +					struct La_s390_32_regs *,	\
> +					unsigned int *, const char *name, \
> +					long int *framesizep);		\
> +    Elf64_Addr (*s390_64_gnu_pltenter) (Elf64_Sym *, unsigned int,	\
> +					uintptr_t *,			\
> +					uintptr_t *,			\
> +					struct La_s390_64_regs *,	\
> +					unsigned int *, const char *name, \
> +					long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*s390_32_gnu_pltexit) (Elf32_Sym *, unsigned int,	\
> +					 uintptr_t *, uintptr_t *,	\
> +					 const struct La_s390_32_regs *, \
> +					 struct La_s390_32_retval *,	\
> +					 const char *);			\
> +    unsigned int (*s390_64_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
> +					 uintptr_t *, uintptr_t *,	\
> +					 const struct La_s390_64_regs *, \
> +					 struct La_s390_64_retval *,	\
> +					 const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> diff --git a/sysdeps/sh/ldsodefs.h b/sysdeps/sh/ldsodefs.h
> new file mode 100644
> index 0000000..66d1e2f
> --- /dev/null
> +++ b/sysdeps/sh/ldsodefs.h
> @@ -0,0 +1,40 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_SH_LDSODEFS_H
> +#define	_SH_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_sh_regs;
> +struct La_sh_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    uintptr_t (*sh_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				  uintptr_t *, const struct La_sh_regs *, \
> +				  unsigned int *, const char *name,	\
> +				  long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*sh_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				    uintptr_t *, const struct La_sh_regs *, \
> +				    struct La_sh_retval *, const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> diff --git a/sysdeps/sparc/ldsodefs.h b/sysdeps/sparc/ldsodefs.h
> new file mode 100644
> index 0000000..2cfdc49
> --- /dev/null
> +++ b/sysdeps/sparc/ldsodefs.h
> @@ -0,0 +1,55 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_SPARC_LDSODEFS_H
> +#define	_SPARC_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_sparc32_regs;
> +struct La_sparc32_retval;
> +struct La_sparc64_regs;
> +struct La_sparc64_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    Elf32_Addr (*sparc32_gnu_pltenter) (Elf32_Sym *, unsigned int,	\
> +					uintptr_t *, uintptr_t *,	\
> +					const struct La_sparc32_regs *,	\
> +					unsigned int *, const char *name, \
> +					long int *framesizep);		\
> +    Elf64_Addr (*sparc64_gnu_pltenter) (Elf64_Sym *, unsigned int,	\
> +					uintptr_t *, uintptr_t *,	\
> +					const struct La_sparc64_regs *,	\
> +					unsigned int *, const char *name, \
> +					long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*sparc32_gnu_pltexit) (Elf32_Sym *, unsigned int,	\
> +					 uintptr_t *, uintptr_t *,	\
> +					 const struct La_sparc32_regs *, \
> +					 struct La_sparc32_retval *,	\
> +					 const char *);			\
> +    unsigned int (*sparc64_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
> +					 uintptr_t *, uintptr_t *,	\
> +					 const struct La_sparc32_regs *, \
> +					 struct La_sparc32_retval *,	\
> +					 const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> diff --git a/sysdeps/x86_64/ldsodefs.h b/sysdeps/x86_64/ldsodefs.h
> new file mode 100644
> index 0000000..bf06837
> --- /dev/null
> +++ b/sysdeps/x86_64/ldsodefs.h
> @@ -0,0 +1,55 @@
> +/* Run-time dynamic linker data structures for loaded ELF shared objects.
> +   Copyright (C) 1995-2012 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, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef	_X86_64_LDSODEFS_H
> +#define	_X86_64_LDSODEFS_H	1
> +
> +#include <elf.h>
> +
> +struct La_x86_64_regs;
> +struct La_x86_64_retval;
> +struct La_x32_regs;
> +struct La_x32_retval;
> +
> +#define ARCH_PLTENTER_MEMBERS						\
> +    Elf64_Addr (*x86_64_gnu_pltenter) (Elf64_Sym *, unsigned int,	\
> +				       uintptr_t *,			\
> +				       uintptr_t *, struct La_x86_64_regs *, \
> +				       unsigned int *, const char *name, \
> +				       long int *framesizep);		\
> +    Elf32_Addr (*x32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				    uintptr_t *, struct La_x32_regs *,	\
> +				    unsigned int *, const char *name,	\
> +				    long int *framesizep)
> +
> +#define ARCH_PLTEXIT_MEMBERS						\
> +    unsigned int (*x86_64_gnu_pltexit) (Elf64_Sym *, unsigned int,	\
> +					uintptr_t *,			\
> +					uintptr_t *,			\
> +					const struct La_x86_64_regs *,	\
> +					struct La_x86_64_retval *,	\
> +					const char *);			\
> +    unsigned int (*x32_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, \
> +				     uintptr_t *,			\
> +				     const struct La_x32_regs *,	\
> +				     struct La_x86_64_retval *,		\
> +				     const char *)
> +
> +#include_next <ldsodefs.h>
> +
> +#endif
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]