[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r1142 - in /fsf/trunk/ports: ./ sysdeps/arm/bits/ sysdeps/arm/eabi/ sysdeps/arm/fpu/bits/ sysdeps/mips/ sysdeps/mips/elf/ sy...



Author: eglibc
Date: Tue Jan  9 00:02:04 2007
New Revision: 1142

Log:
Import glibc-ports-mainline for 2007-01-09

Added:
    fsf/trunk/ports/sysdeps/arm/bits/mathdef.h
    fsf/trunk/ports/sysdeps/arm/eabi/jmpbuf-offsets.h
    fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/check_pf.c
    fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/eabi/check_pf.c
Removed:
    fsf/trunk/ports/sysdeps/arm/fpu/bits/mathdef.h
    fsf/trunk/ports/sysdeps/mips/elf/ldsodefs.h
Modified:
    fsf/trunk/ports/ChangeLog.arm
    fsf/trunk/ports/ChangeLog.mips
    fsf/trunk/ports/ChangeLog.powerpc
    fsf/trunk/ports/sysdeps/mips/dl-machine.h
    fsf/trunk/ports/sysdeps/mips/ldsodefs.h
    fsf/trunk/ports/sysdeps/powerpc/nofpu/fesetenv.c

Modified: fsf/trunk/ports/ChangeLog.arm
==============================================================================
--- fsf/trunk/ports/ChangeLog.arm (original)
+++ fsf/trunk/ports/ChangeLog.arm Tue Jan  9 00:02:04 2007
@@ -1,3 +1,17 @@
+2007-01-08  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/arm/check_pf.c: New file.
+	* sysdeps/unix/sysv/linux/arm/eabi/check_pf.c: New file.
+
+2007-01-08  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/arm/fpu/bits/mathdef.h: Move to
+	sysdeps/arm/bits/mathdef.h.  Remove comment about FPA.
+
+2007-01-08  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/arm/eabi/jmpbuf-offsets.h: New.
+
 2006-10-31  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h

Modified: fsf/trunk/ports/ChangeLog.mips
==============================================================================
--- fsf/trunk/ports/ChangeLog.mips (original)
+++ fsf/trunk/ports/ChangeLog.mips Tue Jan  9 00:02:04 2007
@@ -1,3 +1,23 @@
+2007-01-08  Richard Sandiford  <richard@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NO_RELA): Delete.
+	(elf_machine_reloc): New function, retaining the body of
+	elf_machine_rel.  Take the reloc's r_info field as an argument,
+	not the reloc itself.  Add extra r_addend and inplace_p arguments.
+	When inplace_p is false, use r_addend as the addend, not the contents
+	of the relocation field.  Hoist the conversion of reloc_addr to
+	"ELFW(Addr) *".  Don't try to apply TLS relocations against
+	undefined symbols.  Add R_MIPS_GLOB_DAT support.
+	(elf_machine_rel, elf_machine_rela): Use elf_machine_reloc.
+	(elf_machine_lazy_rel): Change the reloc type from ElfW(Rel)
+	to ElfW(Rela).
+
+2007-01-08  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/mips/ldsodefs.h: Merge sysdeps/mips/elf/ldsodefs.h.  Correct
+	multiple inclusion guard.
+	* sysdeps/mips/elf/ldsodefs.h: Delete file.
+
 2007-01-04  Thiemo Seufer  <ths@xxxxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/mips/bits/msq.h (struct msqid_ds): Update

Modified: fsf/trunk/ports/ChangeLog.powerpc
==============================================================================
--- fsf/trunk/ports/ChangeLog.powerpc (original)
+++ fsf/trunk/ports/ChangeLog.powerpc Tue Jan  9 00:02:04 2007
@@ -1,3 +1,8 @@
+2007-01-08  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/powerpc/nofpu/fesetenv.c (__sim_exceptions,
+	__sim_disabled_exceptions, __sim_round_mode): Remove declarations.
+
 2006-10-05  Steven Munroe  <sjmunroe@xxxxxxxxxx>
 
 	[BZ #2749]

Added: fsf/trunk/ports/sysdeps/arm/bits/mathdef.h
==============================================================================
--- fsf/trunk/ports/sysdeps/arm/bits/mathdef.h (added)
+++ fsf/trunk/ports/sysdeps/arm/bits/mathdef.h Tue Jan  9 00:02:04 2007
@@ -1,0 +1,43 @@
+/* Copyright (C) 1999, 2000, 2004, 2006, 2007
+   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.  */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined  __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF	1
+
+/* GCC does not promote `float' values to `double'.  */
+typedef float float_t;		/* `float' expressions are evaluated as
+				   `float'.  */
+typedef double double_t;	/* `double' expressions are evaluated as
+				   `double'.  */
+
+/* The values returned by `ilogb' for 0 and NaN respectively.  */
+# define FP_ILOGB0	(-2147483647)
+# define FP_ILOGBNAN	(2147483647)
+
+#endif	/* ISO C99 */
+
+#ifndef __NO_LONG_DOUBLE_MATH
+/* Signal that we do not really have a `long double'.  This disables the
+   declaration of all the `long double' function variants.  */
+# define __NO_LONG_DOUBLE_MATH	1
+#endif

Added: fsf/trunk/ports/sysdeps/arm/eabi/jmpbuf-offsets.h
==============================================================================
--- fsf/trunk/ports/sysdeps/arm/eabi/jmpbuf-offsets.h (added)
+++ fsf/trunk/ports/sysdeps/arm/eabi/jmpbuf-offsets.h Tue Jan  9 00:02:04 2007
@@ -1,0 +1,20 @@
+/* Private macros for accessing __jmp_buf contents.  ARM EABI version.
+   Copyright (C) 2007 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.  */
+
+#define __JMP_BUF_SP		8

Modified: fsf/trunk/ports/sysdeps/mips/dl-machine.h
==============================================================================
--- fsf/trunk/ports/sysdeps/mips/dl-machine.h (original)
+++ fsf/trunk/ports/sysdeps/mips/dl-machine.h Tue Jan  9 00:02:04 2007
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  MIPS version.
-   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Kazumoto Kojima <kkojima@xxxxxxxxxxxxxxxxxxxxx>.
@@ -282,9 +282,6 @@
 	".previous"\
 );
 
-/* The MIPS never uses Elfxx_Rela relocations.  */
-#define ELF_MACHINE_NO_RELA 1
-
 /* Names of the architecture-specific auditing callback functions.  */
 # if _MIPS_SIM == _ABIO32
 #  define ARCH_LA_PLTENTER mips_o32_gnu_pltenter
@@ -301,16 +298,18 @@
 
 #ifdef RESOLVE_MAP
 
-/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+/* Perform a relocation described by R_INFO at the location pointed to
+   by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
    MAP is the object containing the reloc.  */
 
 auto inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
-		 const ElfW(Sym) *sym, const struct r_found_version *version,
-		 void *const reloc_addr)
-{
-  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
+elf_machine_reloc (struct link_map *map, ElfW(Word) r_info,
+		   const ElfW(Sym) *sym, const struct r_found_version *version,
+		   void *reloc_addr, ElfW(Addr) r_addend, int inplace_p)
+{
+  const unsigned long int r_type = ELFW(R_TYPE) (r_info);
+  ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
 
 #if !defined RTLD_BOOTSTRAP && !defined SHARED
   /* This is defined in rtld.c, but nowhere in the static libc.a;
@@ -342,18 +341,28 @@
 	  case R_MIPS_TLS_DTPMOD64:
 	  case R_MIPS_TLS_DTPMOD32:
 	    if (sym_map)
-	      *(ElfW(Addr) *)reloc_addr = sym_map->l_tls_modid;
+	      *addr_field = sym_map->l_tls_modid;
 	    break;
 
 	  case R_MIPS_TLS_DTPREL64:
 	  case R_MIPS_TLS_DTPREL32:
-	    *(ElfW(Addr) *)reloc_addr += TLS_DTPREL_VALUE (sym);
+	    if (sym)
+	      {
+		if (inplace_p)
+		  r_addend = *addr_field;
+		*addr_field = r_addend + TLS_DTPREL_VALUE (sym);
+	      }
 	    break;
 
 	  case R_MIPS_TLS_TPREL32:
 	  case R_MIPS_TLS_TPREL64:
-	    CHECK_STATIC_TLS (map, sym_map);
-	    *(ElfW(Addr) *)reloc_addr += TLS_TPREL_VALUE (sym_map, sym);
+	    if (sym)
+	      {
+		CHECK_STATIC_TLS (map, sym_map);
+		if (inplace_p)
+		  r_addend = *addr_field;
+		*addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym);
+	      }
 	    break;
 	  }
 
@@ -367,13 +376,14 @@
     case R_MIPS_REL32:
 #endif
       {
-	int symidx = ELFW(R_SYM) (reloc->r_info);
+	int symidx = ELFW(R_SYM) (r_info);
 	ElfW(Addr) reloc_value;
 
-	/* Support relocations on mis-aligned offsets.  Should we ever
-	   implement RELA, this should be replaced with an assignment
-	   from reloc->r_addend.  */
-	__builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
+	if (inplace_p)
+	  /* Support relocations on mis-aligned offsets.  */
+	  __builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
+	else
+	  reloc_value = r_addend;
 
 	if (symidx)
 	  {
@@ -424,6 +434,31 @@
 	__builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
       }
       break;
+#ifndef RTLD_BOOTSTRAP
+#if _MIPS_SIM == _ABI64
+    case (R_MIPS_64 << 8) | R_MIPS_GLOB_DAT:
+#else
+    case R_MIPS_GLOB_DAT:
+#endif
+      {
+	int symidx = ELFW(R_SYM) (r_info);
+	const ElfW(Word) gotsym
+	  = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
+
+	if (__builtin_expect ((ElfW(Word)) symidx >= gotsym, 1))
+	  {
+	    const ElfW(Addr) *got
+	      = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
+	    const ElfW(Word) local_gotno
+	      = ((const ElfW(Word))
+		 map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val);
+
+	    ElfW(Addr) reloc_value = got[symidx + local_gotno - gotsym];
+	    __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
+	  }
+      }
+      break;
+#endif
     case R_MIPS_NONE:		/* Alright, Wilbur.  */
       break;
 #if _MIPS_SIM == _ABI64
@@ -436,7 +471,7 @@
 	 itself.  For ABI compliance, we ignore such _64 dummy
 	 relocations.  For RELA, this may be simply removed, since
 	 it's totally unnecessary.  */
-      if (ELFW(R_SYM) (reloc->r_info) == 0)
+      if (ELFW(R_SYM) (r_info) == 0)
 	break;
       /* Fall through.  */
 #endif
@@ -446,6 +481,18 @@
     }
 }
 
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+   MAP is the object containing the reloc.  */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
+		 const ElfW(Sym) *sym, const struct r_found_version *version,
+		 void *const reloc_addr)
+{
+  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1);
+}
+
 auto inline void
 __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
@@ -457,7 +504,7 @@
 auto inline void
 __attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc)
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc)
 {
   /* Do nothing.  */
 }
@@ -468,6 +515,8 @@
 		  const ElfW(Sym) *sym, const struct r_found_version *version,
 		 void *const reloc_addr)
 {
+  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr,
+		     reloc->r_addend, 0);
 }
 
 auto inline void

Modified: fsf/trunk/ports/sysdeps/mips/ldsodefs.h
==============================================================================
--- fsf/trunk/ports/sysdeps/mips/ldsodefs.h (original)
+++ fsf/trunk/ports/sysdeps/mips/ldsodefs.h Tue Jan  9 00:02:04 2007
@@ -1,5 +1,5 @@
 /* Run-time dynamic linker data structures for loaded ELF shared objects.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002, 2003, 2006, 2007 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
@@ -17,7 +17,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#ifndef __LDSODEFS_H \
+#ifndef _MIPS_LDSODEFS_H
 #define _MIPS_LDSODEFS_H 1
 
 #include <elf.h>
@@ -61,6 +61,90 @@
 					  struct La_mips_64_retval *,	    \
 					  const char *);
 
+/* The MIPS ABI specifies that the dynamic section has to be read-only.  */
+
+#define DL_RO_DYN_SECTION 1
+
 #include_next <ldsodefs.h>
 
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format.  Each
+   relocation entry specifies up to three actual relocations, all at
+   the same address.  The first relocation which required a symbol
+   uses the symbol in the r_sym field.  The second relocation which
+   requires a symbol uses the symbol in the r_ssym field.  If all
+   three relocations require a symbol, the third one uses a zero
+   value.
+
+   We define these structures in internal headers because we're not
+   sure we want to make them part of the ABI yet.  Eventually, some of
+   this may move into elf/elf.h.  */
+
+/* An entry in a 64 bit SHT_REL section.  */
+
+typedef struct
+{
+  Elf32_Word    r_sym;		/* Symbol index */
+  unsigned char r_ssym;		/* Special symbol for 2nd relocation */
+  unsigned char r_type3;	/* 3rd relocation type */
+  unsigned char r_type2;	/* 2nd relocation type */
+  unsigned char r_type1;	/* 1st relocation type */
+} _Elf64_Mips_R_Info;
+
+typedef union
+{
+  Elf64_Xword	r_info_number;
+  _Elf64_Mips_R_Info r_info_fields;
+} _Elf64_Mips_R_Info_union;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  _Elf64_Mips_R_Info_union r_info;	/* Relocation type and symbol index */
+} Elf64_Mips_Rel;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  _Elf64_Mips_R_Info_union r_info;	/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Mips_Rela;
+
+#define ELF64_MIPS_R_SYM(i) \
+  ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+#define ELF64_MIPS_R_TYPE(i) \
+  (((_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1 \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_type2 << 8) \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_type3 << 16) \
+   | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+		   ).r_info_fields.r_ssym << 24))
+#define ELF64_MIPS_R_INFO(sym, type) \
+  (__extension__ (_Elf64_Mips_R_Info_union) \
+   (__extension__ (_Elf64_Mips_R_Info) \
+   { (sym), ELF64_MIPS_R_SSYM (type), \
+       ELF64_MIPS_R_TYPE3 (type), \
+       ELF64_MIPS_R_TYPE2 (type), \
+       ELF64_MIPS_R_TYPE1 (type) \
+   }).r_info_number)
+/* These macros decompose the value returned by ELF64_MIPS_R_TYPE, and
+   compose it back into a value that it can be used as an argument to
+   ELF64_MIPS_R_INFO.  */
+#define ELF64_MIPS_R_SSYM(i) (((i) >> 24) & 0xff)
+#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff)
+#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff)
+#define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff)
+#define ELF64_MIPS_R_TYPEENC(type1, type2, type3, ssym) \
+  ((type1) \
+   | ((Elf32_Word)(type2) << 8) \
+   | ((Elf32_Word)(type3) << 16) \
+   | ((Elf32_Word)(ssym) << 24))
+
+#undef ELF64_R_SYM
+#define ELF64_R_SYM(i) ELF64_MIPS_R_SYM (i)
+#undef ELF64_R_TYPE
+#define ELF64_R_TYPE(i) ELF64_MIPS_R_TYPE (i)
+#undef ELF64_R_INFO
+#define ELF64_R_INFO(sym, type) ELF64_MIPS_R_INFO ((sym), (type))
+
 #endif

Modified: fsf/trunk/ports/sysdeps/powerpc/nofpu/fesetenv.c
==============================================================================
--- fsf/trunk/ports/sysdeps/powerpc/nofpu/fesetenv.c (original)
+++ fsf/trunk/ports/sysdeps/powerpc/nofpu/fesetenv.c Tue Jan  9 00:02:04 2007
@@ -1,5 +1,5 @@
 /* Set floating point environment (soft-float edition).
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2007 Free Software Foundation, Inc.
    Contributed by Aldy Hernandez <aldyh@xxxxxxxxxx>, 2002.
    This file is part of the GNU C Library.
 
@@ -22,10 +22,6 @@
 #include "soft-supp.h"
 #include <bp-sym.h>
 
-extern int __sim_exceptions attribute_hidden;
-extern int __sim_disabled_exceptions attribute_hidden;
-extern int __sim_round_mode attribute_hidden;
-
 int
 __fesetenv (const fenv_t *envp)
 {

Added: fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/check_pf.c
==============================================================================
--- fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/check_pf.c (added)
+++ fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/check_pf.c Tue Jan  9 00:02:04 2007
@@ -1,0 +1,274 @@
+/* Determine protocol families for which interfaces exist.  ARM Linux version.
+   Copyright (C) 2003, 2006 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 <assert.h>
+#include <errno.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+#include <stddef.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <not-cancel.h>
+#include <kernel-features.h>
+
+
+#ifndef IFA_F_TEMPORARY
+# define IFA_F_TEMPORARY IFA_F_SECONDARY
+#endif
+#ifndef IFA_F_HOMEADDRESS
+# define IFA_F_HOMEADDRESS 0
+#endif
+
+
+static int
+make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
+	      struct in6addrinfo **in6ai, size_t *in6ailen)
+{
+  struct req
+  {
+    struct nlmsghdr nlh;
+    struct rtgenmsg g;
+  } req;
+  struct sockaddr_nl nladdr;
+
+  /* struct rtgenmsg consists of a single byte but the ARM ABI rounds
+     it up to a word.  Clear the padding explicitly here.  */
+  assert (sizeof (req.g) == 4);
+  memset (&req.g, '\0', sizeof (req.g));
+
+  req.nlh.nlmsg_len = sizeof (req);
+  req.nlh.nlmsg_type = RTM_GETADDR;
+  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+  req.nlh.nlmsg_pid = 0;
+  req.nlh.nlmsg_seq = time (NULL);
+  req.g.rtgen_family = AF_UNSPEC;
+
+  memset (&nladdr, '\0', sizeof (nladdr));
+  nladdr.nl_family = AF_NETLINK;
+
+  if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
+				    (struct sockaddr *) &nladdr,
+				    sizeof (nladdr))) < 0)
+    return -1;
+
+  *seen_ipv4 = false;
+  *seen_ipv6 = false;
+
+  bool done = false;
+  char buf[4096];
+  struct iovec iov = { buf, sizeof (buf) };
+  struct in6ailist
+  {
+    struct in6addrinfo info;
+    struct in6ailist *next;
+  } *in6ailist = NULL;
+  size_t in6ailistlen = 0;
+
+  do
+    {
+      struct msghdr msg =
+	{
+	  (void *) &nladdr, sizeof (nladdr),
+	  &iov, 1,
+	  NULL, 0,
+	  0
+	};
+
+      ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
+      if (read_len < 0)
+	return -1;
+
+      if (msg.msg_flags & MSG_TRUNC)
+	return -1;
+
+      struct nlmsghdr *nlmh;
+      for (nlmh = (struct nlmsghdr *) buf;
+	   NLMSG_OK (nlmh, (size_t) read_len);
+	   nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
+	{
+	  if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
+	      || nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
+	    continue;
+
+	  if (nlmh->nlmsg_type == RTM_NEWADDR)
+	    {
+	      struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
+
+	      switch (ifam->ifa_family)
+		{
+		case AF_INET:
+		  *seen_ipv4 = true;
+		  break;
+		case AF_INET6:
+		  *seen_ipv6 = true;
+
+		  if (ifam->ifa_flags & (IFA_F_DEPRECATED
+					 | IFA_F_TEMPORARY
+					 | IFA_F_HOMEADDRESS))
+		    {
+		      struct rtattr *rta = IFA_RTA (ifam);
+		      size_t len = (nlmh->nlmsg_len
+				    - NLMSG_LENGTH (sizeof (*ifam)));
+		      void *local = NULL;
+		      void *address = NULL;
+		      while (RTA_OK (rta, len))
+			{
+			  switch (rta->rta_type)
+			    {
+			    case IFA_LOCAL:
+			      local = RTA_DATA (rta);
+			      break;
+
+			    case IFA_ADDRESS:
+			      address = RTA_DATA (rta);
+			      break;
+			    }
+
+			  rta = RTA_NEXT (rta, len);
+			}
+
+		      struct in6ailist *newp = alloca (sizeof (*newp));
+		      newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED)
+					   ? in6ai_deprecated : 0)
+					  | ((ifam->ifa_flags
+					      & IFA_F_TEMPORARY)
+					     ? in6ai_temporary : 0)
+					  | ((ifam->ifa_flags
+					      & IFA_F_HOMEADDRESS)
+					     ? in6ai_homeaddress : 0));
+		      memcpy (newp->info.addr, address ?: local,
+			      sizeof (newp->info.addr));
+		      newp->next = in6ailist;
+		      in6ailist = newp;
+		      ++in6ailistlen;
+		    }
+		  break;
+		default:
+		  /* Ignore.  */
+		  break;
+		}
+	    }
+	  else if (nlmh->nlmsg_type == NLMSG_DONE)
+	    /* We found the end, leave the loop.  */
+	    done = true;
+	}
+    }
+  while (! done);
+
+  close_not_cancel_no_status (fd);
+
+  if (in6ailist != NULL)
+    {
+      *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
+      if (*in6ai == NULL)
+	return -1;
+
+      *in6ailen = in6ailistlen;
+
+      do
+	{
+	  (*in6ai)[--in6ailistlen] = in6ailist->info;
+	  in6ailist = in6ailist->next;
+	}
+      while (in6ailist != NULL);
+    }
+
+  return 0;
+}
+
+
+/* We don't know if we have NETLINK support compiled in in our
+   Kernel.  */
+#if __ASSUME_NETLINK_SUPPORT == 0
+/* Define in ifaddrs.h.  */
+extern int __no_netlink_support attribute_hidden;
+#else
+# define __no_netlink_support 0
+#endif
+
+
+void
+attribute_hidden
+__check_pf (bool *seen_ipv4, bool *seen_ipv6,
+	    struct in6addrinfo **in6ai, size_t *in6ailen)
+{
+  *in6ai = NULL;
+  *in6ailen = 0;
+
+  if (! __no_netlink_support)
+    {
+      int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+
+      struct sockaddr_nl nladdr;
+      memset (&nladdr, '\0', sizeof (nladdr));
+      nladdr.nl_family = AF_NETLINK;
+
+      socklen_t addr_len = sizeof (nladdr);
+
+      if (fd >= 0
+	  && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
+	  && __getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
+	  && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6,
+			   in6ai, in6ailen) == 0)
+	/* It worked.  */
+	return;
+
+      if (fd >= 0)
+	__close (fd);
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+      /* Remember that there is no netlink support.  */
+      __no_netlink_support = 1;
+#else
+      /* We cannot determine what interfaces are available.  Be
+	 pessimistic.  */
+      *seen_ipv4 = true;
+      *seen_ipv6 = true;
+#endif
+    }
+
+#if __ASSUME_NETLINK_SUPPORT == 0
+  /* No netlink.  Get the interface list via getifaddrs.  */
+  struct ifaddrs *ifa = NULL;
+  if (getifaddrs (&ifa) != 0)
+    {
+      /* We cannot determine what interfaces are available.  Be
+	 pessimistic.  */
+      *seen_ipv4 = true;
+      *seen_ipv6 = true;
+      return;
+    }
+
+  struct ifaddrs *runp;
+  for (runp = ifa; runp != NULL; runp = runp->ifa_next)
+    if (runp->ifa_addr->sa_family == PF_INET)
+      *seen_ipv4 = true;
+    else if (runp->ifa_addr->sa_family == PF_INET6)
+      *seen_ipv6 = true;
+
+  (void) freeifaddrs (ifa);
+#endif
+}

Added: fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/eabi/check_pf.c
==============================================================================
--- fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/eabi/check_pf.c (added)
+++ fsf/trunk/ports/sysdeps/unix/sysv/linux/arm/eabi/check_pf.c Tue Jan  9 00:02:04 2007
@@ -1,0 +1,1 @@
+#include <sysdeps/unix/sysv/linux/check_pf.c>