diff --git a/ctypes-libffi-aarch64.patch b/ctypes-libffi-aarch64.patch
new file mode 100644
index 0000000..a0fdf63
--- /dev/null
+++ b/ctypes-libffi-aarch64.patch
@@ -0,0 +1,3220 @@
+Index: Python-2.7.3/Modules/_ctypes/libffi/Makefile.am
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/Makefile.am
++++ Python-2.7.3/Modules/_ctypes/libffi/Makefile.am
+@@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = foreign subdir-object
+ SUBDIRS = include testsuite man
+
+ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
++ src/aarch64/ffi.c src/aarch64/ffitarget.h \
+ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
+ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
+ src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
+@@ -139,6 +140,9 @@ endif
+ if POWERPC_FREEBSD
+ nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+ endif
++if AARCH64
++nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
++endif
+ if ARM
+ nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
+ endif
+Index: Python-2.7.3/Modules/_ctypes/libffi/Makefile.in
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/Makefile.in
++++ Python-2.7.3/Modules/_ctypes/libffi/Makefile.in
+@@ -51,33 +51,37 @@ target_triplet = @target@
+ @POWERPC_AIX_TRUE@am__append_13 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+ @POWERPC_DARWIN_TRUE@am__append_14 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+ @POWERPC_FREEBSD_TRUE@am__append_15 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+-@ARM_TRUE@am__append_16 = src/arm/sysv.S src/arm/ffi.c
+-@AVR32_TRUE@am__append_17 = src/avr32/sysv.S src/avr32/ffi.c
+-@LIBFFI_CRIS_TRUE@am__append_18 = src/cris/sysv.S src/cris/ffi.c
+-@FRV_TRUE@am__append_19 = src/frv/eabi.S src/frv/ffi.c
+-@S390_TRUE@am__append_20 = src/s390/sysv.S src/s390/ffi.c
+-@X86_64_TRUE@am__append_21 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+-@SH_TRUE@am__append_22 = src/sh/sysv.S src/sh/ffi.c
+-@SH64_TRUE@am__append_23 = src/sh64/sysv.S src/sh64/ffi.c
+-@PA_LINUX_TRUE@am__append_24 = src/pa/linux.S src/pa/ffi.c
+-@PA_HPUX_TRUE@am__append_25 = src/pa/hpux32.S src/pa/ffi.c
++@AARCH64_TRUE@am__append_16 = src/aarch64/sysv.S src/aarch64/ffi.c
++@ARM_TRUE@am__append_17 = src/arm/sysv.S src/arm/ffi.c
++@AVR32_TRUE@am__append_18 = src/avr32/sysv.S src/avr32/ffi.c
++@LIBFFI_CRIS_TRUE@am__append_19 = src/cris/sysv.S src/cris/ffi.c
++@FRV_TRUE@am__append_20 = src/frv/eabi.S src/frv/ffi.c
++@S390_TRUE@am__append_21 = src/s390/sysv.S src/s390/ffi.c
++@X86_64_TRUE@am__append_22 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
++@SH_TRUE@am__append_23 = src/sh/sysv.S src/sh/ffi.c
++@SH64_TRUE@am__append_24 = src/sh64/sysv.S src/sh64/ffi.c
++@PA_LINUX_TRUE@am__append_25 = src/pa/linux.S src/pa/ffi.c
++@PA_HPUX_TRUE@am__append_26 = src/pa/hpux32.S src/pa/ffi.c
+ subdir = .
+ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
+ $(srcdir)/doc/version.texi $(srcdir)/fficonfig.h.in \
+- $(srcdir)/libffi.pc.in $(top_srcdir)/configure ChangeLog \
+- compile config.guess config.sub depcomp install-sh ltmain.sh \
+- mdate-sh missing texinfo.tex
++ $(srcdir)/fficonfig.py.in $(srcdir)/libffi.pc.in \
++ $(top_srcdir)/configure ChangeLog compile config.guess \
++ config.sub depcomp install-sh ltmain.sh mdate-sh missing \
++ texinfo.tex
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+-am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+- $(top_srcdir)/configure.ac
++am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
++ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
++ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
++ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+ mkinstalldirs = $(install_sh) -d
+ CONFIG_HEADER = fficonfig.h
+-CONFIG_CLEAN_FILES = libffi.pc
++CONFIG_CLEAN_FILES = libffi.pc fficonfig.py
+ CONFIG_CLEAN_VPATH_FILES =
+ am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+ am__vpath_adj = case $$p in \
+@@ -134,17 +138,18 @@ am_libffi_la_OBJECTS = src/debug.lo src/
+ @POWERPC_FREEBSD_TRUE@am__objects_15 = src/powerpc/ffi.lo \
+ @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
+ @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
+-@ARM_TRUE@am__objects_16 = src/arm/sysv.lo src/arm/ffi.lo
+-@AVR32_TRUE@am__objects_17 = src/avr32/sysv.lo src/avr32/ffi.lo
+-@LIBFFI_CRIS_TRUE@am__objects_18 = src/cris/sysv.lo src/cris/ffi.lo
+-@FRV_TRUE@am__objects_19 = src/frv/eabi.lo src/frv/ffi.lo
+-@S390_TRUE@am__objects_20 = src/s390/sysv.lo src/s390/ffi.lo
+-@X86_64_TRUE@am__objects_21 = src/x86/ffi64.lo src/x86/unix64.lo \
++@AARCH64_TRUE@am__objects_16 = src/aarch64/sysv.lo src/aarch64/ffi.lo
++@ARM_TRUE@am__objects_17 = src/arm/sysv.lo src/arm/ffi.lo
++@AVR32_TRUE@am__objects_18 = src/avr32/sysv.lo src/avr32/ffi.lo
++@LIBFFI_CRIS_TRUE@am__objects_19 = src/cris/sysv.lo src/cris/ffi.lo
++@FRV_TRUE@am__objects_20 = src/frv/eabi.lo src/frv/ffi.lo
++@S390_TRUE@am__objects_21 = src/s390/sysv.lo src/s390/ffi.lo
++@X86_64_TRUE@am__objects_22 = src/x86/ffi64.lo src/x86/unix64.lo \
+ @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
+-@SH_TRUE@am__objects_22 = src/sh/sysv.lo src/sh/ffi.lo
+-@SH64_TRUE@am__objects_23 = src/sh64/sysv.lo src/sh64/ffi.lo
+-@PA_LINUX_TRUE@am__objects_24 = src/pa/linux.lo src/pa/ffi.lo
+-@PA_HPUX_TRUE@am__objects_25 = src/pa/hpux32.lo src/pa/ffi.lo
++@SH_TRUE@am__objects_23 = src/sh/sysv.lo src/sh/ffi.lo
++@SH64_TRUE@am__objects_24 = src/sh64/sysv.lo src/sh64/ffi.lo
++@PA_LINUX_TRUE@am__objects_25 = src/pa/linux.lo src/pa/ffi.lo
++@PA_HPUX_TRUE@am__objects_26 = src/pa/hpux32.lo src/pa/ffi.lo
+ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3) $(am__objects_4) $(am__objects_5) \
+ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+@@ -153,17 +158,17 @@ nodist_libffi_la_OBJECTS = $(am__objects
+ $(am__objects_15) $(am__objects_16) $(am__objects_17) \
+ $(am__objects_18) $(am__objects_19) $(am__objects_20) \
+ $(am__objects_21) $(am__objects_22) $(am__objects_23) \
+- $(am__objects_24) $(am__objects_25)
++ $(am__objects_24) $(am__objects_25) $(am__objects_26)
+ libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
+ $(nodist_libffi_la_OBJECTS)
+ libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
+ libffi_convenience_la_LIBADD =
+-am__objects_26 = src/debug.lo src/prep_cif.lo src/types.lo \
++am__objects_27 = src/debug.lo src/prep_cif.lo src/types.lo \
+ src/raw_api.lo src/java_raw_api.lo src/closures.lo
+-am_libffi_convenience_la_OBJECTS = $(am__objects_26)
+-am__objects_27 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
++am_libffi_convenience_la_OBJECTS = $(am__objects_27)
++am__objects_28 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+ $(am__objects_4) $(am__objects_5) $(am__objects_6) \
+ $(am__objects_7) $(am__objects_8) $(am__objects_9) \
+ $(am__objects_10) $(am__objects_11) $(am__objects_12) \
+@@ -171,8 +176,8 @@ am__objects_27 = $(am__objects_1) $(am__
+ $(am__objects_16) $(am__objects_17) $(am__objects_18) \
+ $(am__objects_19) $(am__objects_20) $(am__objects_21) \
+ $(am__objects_22) $(am__objects_23) $(am__objects_24) \
+- $(am__objects_25)
+-nodist_libffi_convenience_la_OBJECTS = $(am__objects_27)
++ $(am__objects_25) $(am__objects_26)
++nodist_libffi_convenience_la_OBJECTS = $(am__objects_28)
+ libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
+ $(nodist_libffi_convenience_la_OBJECTS)
+ DEFAULT_INCLUDES = -I.@am__isrc@
+@@ -319,6 +324,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+ PACKAGE_NAME = @PACKAGE_NAME@
+ PACKAGE_STRING = @PACKAGE_STRING@
+ PACKAGE_TARNAME = @PACKAGE_TARNAME@
++PACKAGE_URL = @PACKAGE_URL@
+ PACKAGE_VERSION = @PACKAGE_VERSION@
+ PATH_SEPARATOR = @PATH_SEPARATOR@
+ RANLIB = @RANLIB@
+@@ -390,6 +396,7 @@ top_srcdir = @top_srcdir@
+ AUTOMAKE_OPTIONS = foreign subdir-objects
+ SUBDIRS = include testsuite man
+ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
++ src/aarch64/ffi.c src/aarch64/ffitarget.h \
+ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
+ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
+ src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \
+@@ -475,11 +482,11 @@ nodist_libffi_la_SOURCES = $(am__append_
+ $(am__append_15) $(am__append_16) $(am__append_17) \
+ $(am__append_18) $(am__append_19) $(am__append_20) \
+ $(am__append_21) $(am__append_22) $(am__append_23) \
+- $(am__append_24) $(am__append_25)
++ $(am__append_24) $(am__append_25) $(am__append_26)
+ libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+ nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
+ AM_CFLAGS = -Wall -g -fexceptions
+-libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(AM_LTLDFLAGS)
++libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
+ AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+ AM_CCASFLAGS = $(AM_CPPFLAGS)
+ all: fficonfig.h
+@@ -540,6 +547,8 @@ distclean-hdr:
+ -rm -f fficonfig.h stamp-h1
+ libffi.pc: $(top_builddir)/config.status $(srcdir)/libffi.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
++fficonfig.py: $(top_builddir)/config.status $(srcdir)/fficonfig.py.in
++ cd $(top_builddir) && $(SHELL) ./config.status $@
+ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+@@ -704,6 +713,16 @@ src/powerpc/darwin.lo: src/powerpc/$(am_
+ src/powerpc/$(DEPDIR)/$(am__dirstamp)
+ src/powerpc/darwin_closure.lo: src/powerpc/$(am__dirstamp) \
+ src/powerpc/$(DEPDIR)/$(am__dirstamp)
++src/aarch64/$(am__dirstamp):
++ @$(MKDIR_P) src/aarch64
++ @: > src/aarch64/$(am__dirstamp)
++src/aarch64/$(DEPDIR)/$(am__dirstamp):
++ @$(MKDIR_P) src/aarch64/$(DEPDIR)
++ @: > src/aarch64/$(DEPDIR)/$(am__dirstamp)
++src/aarch64/sysv.lo: src/aarch64/$(am__dirstamp) \
++ src/aarch64/$(DEPDIR)/$(am__dirstamp)
++src/aarch64/ffi.lo: src/aarch64/$(am__dirstamp) \
++ src/aarch64/$(DEPDIR)/$(am__dirstamp)
+ src/arm/$(am__dirstamp):
+ @$(MKDIR_P) src/arm
+ @: > src/arm/$(am__dirstamp)
+@@ -793,6 +812,10 @@ libffi_convenience.la: $(libffi_convenie
+
+ mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
++ -rm -f src/aarch64/ffi.$(OBJEXT)
++ -rm -f src/aarch64/ffi.lo
++ -rm -f src/aarch64/sysv.$(OBJEXT)
++ -rm -f src/aarch64/sysv.lo
+ -rm -f src/alpha/ffi.$(OBJEXT)
+ -rm -f src/alpha/ffi.lo
+ -rm -f src/alpha/osf.$(OBJEXT)
+@@ -915,6 +938,8 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/prep_cif.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/raw_api.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/types.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/ffi.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/sysv.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/ffi.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/osf.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/ffi.Plo@am__quote@
+@@ -1020,6 +1045,7 @@ mostlyclean-libtool:
+ clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf src/.libs src/_libs
++ -rm -rf src/aarch64/.libs src/aarch64/_libs
+ -rm -rf src/alpha/.libs src/alpha/_libs
+ -rm -rf src/arm/.libs src/arm/_libs
+ -rm -rf src/avr32/.libs src/avr32/_libs
+@@ -1232,7 +1258,7 @@ uninstall-pkgconfigDATA:
+ # (which will cause the Makefiles to be regenerated when you run `make');
+ # (2) otherwise, pass the desired values on the `make' command line.
+ $(RECURSIVE_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+@@ -1257,7 +1283,7 @@ $(RECURSIVE_TARGETS):
+ fi; test -z "$$fail"
+
+ $(RECURSIVE_CLEAN_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+@@ -1424,7 +1450,8 @@ distdir: $(DISTFILES)
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+ -test -n "$(am__skip_mode_fix)" \
+- || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
++ || find "$(distdir)" -type d ! -perm -755 \
++ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+@@ -1468,17 +1495,17 @@ dist dist-all: distdir
+ distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
++ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
++ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+- unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
++ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
++ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+@@ -1569,6 +1596,8 @@ distclean-generic:
+ -rm -f doc/$(am__dirstamp)
+ -rm -f src/$(DEPDIR)/$(am__dirstamp)
+ -rm -f src/$(am__dirstamp)
++ -rm -f src/aarch64/$(DEPDIR)/$(am__dirstamp)
++ -rm -f src/aarch64/$(am__dirstamp)
+ -rm -f src/alpha/$(DEPDIR)/$(am__dirstamp)
+ -rm -f src/alpha/$(am__dirstamp)
+ -rm -f src/arm/$(DEPDIR)/$(am__dirstamp)
+@@ -1612,7 +1641,7 @@ clean-am: clean-aminfo clean-generic cle
+
+ distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+- -rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
++ -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
+ -rm -f Makefile
+ distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+@@ -1732,7 +1761,7 @@ installcheck-am:
+ maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+- -rm -rf src/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
++ -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/x86/$(DEPDIR)
+ -rm -f Makefile
+ maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti
+Index: Python-2.7.3/Modules/_ctypes/libffi/config.guess
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/config.guess
++++ Python-2.7.3/Modules/_ctypes/libffi/config.guess
+@@ -1,14 +1,14 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
++# 2011, 2012, 2013 Free Software Foundation, Inc.
+
+-timestamp='2009-11-19'
++timestamp='2012-12-30'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+@@ -17,26 +17,22 @@ timestamp='2009-11-19'
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see .
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner. Please send patches (context
+-# diff format) to and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub. If it succeeds, it prints the system name on stdout, and
+-# exits with 0. Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+
+ me=`echo "$0" | sed -e 's,.*/,,'`
+
+@@ -56,8 +52,9 @@ version="\
+ GNU config.guess ($timestamp)
+
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
++2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
++2012, 2013 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."
+@@ -144,7 +141,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` |
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+@@ -180,7 +177,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ fi
+ ;;
+ *)
+- os=netbsd
++ os=netbsd
+ ;;
+ esac
+ # The OS release
+@@ -201,6 +198,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
++ *:Bitrig:*:*)
++ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+@@ -223,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+@@ -269,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- exit ;;
++ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++ exitcode=$?
++ trap '' 0
++ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+@@ -295,12 +299,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+- echo powerpc-ibm-os400
++ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+- arm:riscos:*:*|arm:RISCOS:*:*)
++ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+@@ -333,6 +337,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
++ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
++ echo i386-pc-auroraux${UNAME_RELEASE}
++ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+@@ -391,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+- exit ;;
++ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+- echo m68k-milan-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-milan-mint${UNAME_RELEASE}
++ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+- echo m68k-hades-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-hades-mint${UNAME_RELEASE}
++ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+- echo m68k-unknown-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-unknown-mint${UNAME_RELEASE}
++ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+@@ -477,8 +484,8 @@ EOF
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+- # DG/UX returns AViiON for all architectures
+- UNAME_PROCESSOR=`/usr/bin/uname -p`
++ # DG/UX returns AViiON for all architectures
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+@@ -491,7 +498,7 @@ EOF
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+@@ -548,7 +555,7 @@ EOF
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+- *:AIX:*:[456])
++ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+@@ -591,52 +598,52 @@ EOF
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+- case "${sc_cpu_version}" in
+- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+- 532) # CPU_PA_RISC2_0
+- case "${sc_kernel_bits}" in
+- 32) HP_ARCH="hppa2.0n" ;;
+- 64) HP_ARCH="hppa2.0w" ;;
++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++ case "${sc_cpu_version}" in
++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++ 532) # CPU_PA_RISC2_0
++ case "${sc_kernel_bits}" in
++ 32) HP_ARCH="hppa2.0n" ;;
++ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+- esac ;;
+- esac
++ esac ;;
++ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
++ sed 's/^ //' << EOF >$dummy.c
+
+- #define _HPUX_SOURCE
+- #include
+- #include
+-
+- int main ()
+- {
+- #if defined(_SC_KERNEL_BITS)
+- long bits = sysconf(_SC_KERNEL_BITS);
+- #endif
+- long cpu = sysconf (_SC_CPU_VERSION);
+-
+- switch (cpu)
+- {
+- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+- case CPU_PA_RISC2_0:
+- #if defined(_SC_KERNEL_BITS)
+- switch (bits)
+- {
+- case 64: puts ("hppa2.0w"); break;
+- case 32: puts ("hppa2.0n"); break;
+- default: puts ("hppa2.0"); break;
+- } break;
+- #else /* !defined(_SC_KERNEL_BITS) */
+- puts ("hppa2.0"); break;
+- #endif
+- default: puts ("hppa1.0"); break;
+- }
+- exit (0);
+- }
++ #define _HPUX_SOURCE
++ #include
++ #include
++
++ int main ()
++ {
++ #if defined(_SC_KERNEL_BITS)
++ long bits = sysconf(_SC_KERNEL_BITS);
++ #endif
++ long cpu = sysconf (_SC_CPU_VERSION);
++
++ switch (cpu)
++ {
++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++ case CPU_PA_RISC2_0:
++ #if defined(_SC_KERNEL_BITS)
++ switch (bits)
++ {
++ case 64: puts ("hppa2.0w"); break;
++ case 32: puts ("hppa2.0n"); break;
++ default: puts ("hppa2.0"); break;
++ } break;
++ #else /* !defined(_SC_KERNEL_BITS) */
++ puts ("hppa2.0"); break;
++ #endif
++ default: puts ("hppa1.0"); break;
++ }
++ exit (0);
++ }
+ EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+@@ -727,22 +734,22 @@ EOF
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+- exit ;;
++ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+- exit ;;
++ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+- exit ;;
++ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+- exit ;;
++ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+- exit ;;
++ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+@@ -766,14 +773,14 @@ EOF
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+- exit ;;
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+@@ -785,30 +792,35 @@ EOF
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+- case ${UNAME_MACHINE} in
+- pc98)
+- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
++ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
++ *:MINGW64*:*)
++ echo ${UNAME_MACHINE}-pc-mingw64
++ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
++ i*:MSYS*:*)
++ echo ${UNAME_MACHINE}-pc-msys
++ exit ;;
+ i*:windows32*:*)
+- # uname -m includes "-pc" on this system.
+- echo ${UNAME_MACHINE}-mingw32
++ # uname -m includes "-pc" on this system.
++ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+- case ${UNAME_MACHINE} in
++ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+@@ -854,6 +866,13 @@ EOF
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
++ aarch64:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ aarch64_be:Linux:*:*)
++ UNAME_MACHINE=aarch64_be
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+@@ -863,7 +882,7 @@ EOF
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+- esac
++ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+@@ -875,20 +894,29 @@ EOF
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++ | grep -q __ARM_PCS_VFP
++ then
++ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++ else
++ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
++ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+- echo cris-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+- echo crisv32-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+- echo frv-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ hexagon:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+@@ -930,7 +958,7 @@ EOF
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+- echo or32-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+@@ -956,7 +984,7 @@ EOF
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+@@ -964,14 +992,17 @@ EOF
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
++ tile*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+- echo x86_64-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+@@ -980,11 +1011,11 @@ EOF
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+- # Unixware is an offshoot of SVR4, but it has its own version
+- # number series starting with 2...
+- # I am not positive that other SVR4 systems won't match this,
++ # Unixware is an offshoot of SVR4, but it has its own version
++ # number series starting with 2...
++ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+- # Use sysv4.2uw... so that sysv4* matches it.
++ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+@@ -1016,7 +1047,7 @@ EOF
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+- # UnixWare 7.x, OpenUNIX and OpenServer 6.
++ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+@@ -1044,13 +1075,13 @@ EOF
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+- # uname -m prints for DJGPP always 'pc', but it prints nothing about
+- # the processor, so we play safe by assuming i586.
++ # uname -m prints for DJGPP always 'pc', but it prints nothing about
++ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+- exit ;;
++ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+@@ -1085,8 +1116,8 @@ EOF
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+- && { echo i486-ncr-sysv4; exit; } ;;
++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+@@ -1129,10 +1160,10 @@ EOF
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+- # says
+- echo i586-unisys-sysv4
+- exit ;;
++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++ # says
++ echo i586-unisys-sysv4
++ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes .
+ # How about differentiating between stratus architectures? -djm
+@@ -1158,11 +1189,11 @@ EOF
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+- echo mips-nec-sysv${UNAME_RELEASE}
++ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+- echo mips-unknown-sysv${UNAME_RELEASE}
++ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+@@ -1175,6 +1206,9 @@ EOF
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
++ x86_64:Haiku:*:*)
++ echo x86_64-unknown-haiku
++ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+@@ -1227,7 +1261,10 @@ EOF
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+- NSE-?:NONSTOP_KERNEL:*:*)
++ NEO-?:NONSTOP_KERNEL:*:*)
++ echo neo-tandem-nsk${UNAME_RELEASE}
++ exit ;;
++ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+@@ -1272,13 +1309,13 @@ EOF
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+- echo mips-sei-seiux${UNAME_RELEASE}
++ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+- UNAME_MACHINE=`(uname -p) 2>/dev/null`
++ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+@@ -1296,11 +1333,11 @@ EOF
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
++ x86_64:VMkernel:*:*)
++ echo ${UNAME_MACHINE}-unknown-esx
++ exit ;;
+ esac
+
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+ eval $set_cc_for_build
+ cat >$dummy.c <
+ printf ("m68k-sony-newsos%s\n",
+ #ifdef NEWSOS4
+- "4"
++ "4"
+ #else
+- ""
++ ""
+ #endif
+- ); exit (0);
++ ); exit (0);
+ #endif
+ #endif
+
+Index: Python-2.7.3/Modules/_ctypes/libffi/config.sub
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/config.sub
++++ Python-2.7.3/Modules/_ctypes/libffi/config.sub
+@@ -1,38 +1,33 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
++# 2011, 2012, 2013 Free Software Foundation, Inc.
+
+-timestamp='2009-11-07'
++timestamp='2013-01-23'
+
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine. It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program 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 General Public License for more details.
++# This program 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
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see .
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+
+
+-# Please send patches to . Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+@@ -75,8 +70,9 @@ Report bugs and patches to conftest.$ac_ext
+- (eval echo "\"\$as_me:5045: $ac_compile\"" >&5)
++ (eval echo "\"\$as_me:5047: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+- (eval echo "\"\$as_me:5048: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
++ (eval echo "\"\$as_me:5050: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+- (eval echo "\"\$as_me:5051: output\"" >&5)
++ (eval echo "\"\$as_me:5053: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+@@ -6254,7 +6256,7 @@ ia64-*-hpux*)
+ ;;
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 6257 "configure"' > conftest.$ac_ext
++ echo '#line 6259 "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+@@ -7784,11 +7786,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:7787: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:7789: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:7791: \$? = $ac_status" >&5
++ echo "$as_me:7793: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -8123,11 +8125,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:8126: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:8128: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+- echo "$as_me:8130: \$? = $ac_status" >&5
++ echo "$as_me:8132: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+@@ -8228,11 +8230,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:8231: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:8233: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:8235: \$? = $ac_status" >&5
++ echo "$as_me:8237: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -8283,11 +8285,11 @@ else
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+- (eval echo "\"\$as_me:8286: $lt_compile\"" >&5)
++ (eval echo "\"\$as_me:8288: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+- echo "$as_me:8290: \$? = $ac_status" >&5
++ echo "$as_me:8292: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+@@ -10653,7 +10655,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 10656 "configure"
++#line 10658 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -10749,7 +10751,7 @@ else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+-#line 10752 "configure"
++#line 10754 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -11178,6 +11180,10 @@ fi
+
+ TARGETDIR="unknown"
+ case "$host" in
++ aarch64*-*-*)
++ TARGET=AARCH64; TARGETDIR=aarch64
++ ;;
++
+ alpha*-*-*)
+ TARGET=ALPHA; TARGETDIR=alpha;
+ # Support 128-bit long double, changable via command-line switch.
+@@ -11434,6 +11440,14 @@ else
+ POWERPC_FREEBSD_FALSE=
+ fi
+
++ if test x$TARGET = xAARCH64; then
++ AARCH64_TRUE=
++ AARCH64_FALSE='#'
++else
++ AARCH64_TRUE='#'
++ AARCH64_FALSE=
++fi
++
+ if test x$TARGET = xARM; then
+ ARM_TRUE=
+ ARM_FALSE='#'
+@@ -12620,6 +12634,10 @@ if test -z "${POWERPC_FREEBSD_TRUE}" &&
+ as_fn_error "conditional \"POWERPC_FREEBSD\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
++if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then
++ as_fn_error "conditional \"AARCH64\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+ if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then
+ as_fn_error "conditional \"ARM\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+Index: Python-2.7.3/Modules/_ctypes/libffi/configure.ac
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/configure.ac
++++ Python-2.7.3/Modules/_ctypes/libffi/configure.ac
+@@ -44,6 +44,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcd
+
+ TARGETDIR="unknown"
+ case "$host" in
++ aarch64*-*-*)
++ TARGET=AARCH64; TARGETDIR=aarch64
++ ;;
++
+ alpha*-*-*)
+ TARGET=ALPHA; TARGETDIR=alpha;
+ # Support 128-bit long double, changable via command-line switch.
+@@ -195,6 +199,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET =
+ AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
+ AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
+ AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
++AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64)
+ AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+ AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
+ AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
+Index: Python-2.7.3/Modules/_ctypes/libffi/fficonfig.py.in
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/fficonfig.py.in
++++ Python-2.7.3/Modules/_ctypes/libffi/fficonfig.py.in
+@@ -28,6 +28,7 @@ ffi_platforms = {
+ 'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
+ 'PA_LINUX': ['src/pa/linux.S', 'src/pa/ffi.c'],
+ 'PA_HPUX': ['src/pa/hpux32.S', 'src/pa/ffi.c'],
++ 'AARCH64' : ['src/aarch64/ffi.c', 'src/aarch64/sysv.S'],
+ }
+
+ ffi_sources += ffi_platforms['@TARGET@']
+Index: Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/ffi.c
+===================================================================
+--- /dev/null
++++ Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/ffi.c
+@@ -0,0 +1,1076 @@
++/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++``Software''), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
++
++#include
++
++#include
++#include
++
++#include
++
++/* Stack alignment requirement in bytes */
++#define AARCH64_STACK_ALIGN 16
++
++#define N_X_ARG_REG 8
++#define N_V_ARG_REG 8
++
++#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT)
++
++union _d
++{
++ UINT64 d;
++ UINT32 s[2];
++};
++
++struct call_context
++{
++ UINT64 x [AARCH64_N_XREG];
++ struct
++ {
++ union _d d[2];
++ } v [AARCH64_N_VREG];
++};
++
++static void *
++get_x_addr (struct call_context *context, unsigned n)
++{
++ return &context->x[n];
++}
++
++static void *
++get_s_addr (struct call_context *context, unsigned n)
++{
++#if defined __AARCH64EB__
++ return &context->v[n].d[1].s[1];
++#else
++ return &context->v[n].d[0].s[0];
++#endif
++}
++
++static void *
++get_d_addr (struct call_context *context, unsigned n)
++{
++#if defined __AARCH64EB__
++ return &context->v[n].d[1];
++#else
++ return &context->v[n].d[0];
++#endif
++}
++
++static void *
++get_v_addr (struct call_context *context, unsigned n)
++{
++ return &context->v[n];
++}
++
++/* Return the memory location at which a basic type would reside
++ were it to have been stored in register n. */
++
++static void *
++get_basic_type_addr (unsigned short type, struct call_context *context,
++ unsigned n)
++{
++ switch (type)
++ {
++ case FFI_TYPE_FLOAT:
++ return get_s_addr (context, n);
++ case FFI_TYPE_DOUBLE:
++ return get_d_addr (context, n);
++ case FFI_TYPE_LONGDOUBLE:
++ return get_v_addr (context, n);
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT64:
++ return get_x_addr (context, n);
++ default:
++ FFI_ASSERT (0);
++ return NULL;
++ }
++}
++
++/* Return the alignment width for each of the basic types. */
++
++static size_t
++get_basic_type_alignment (unsigned short type)
++{
++ switch (type)
++ {
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ return sizeof (UINT64);
++ case FFI_TYPE_LONGDOUBLE:
++ return sizeof (long double);
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT64:
++ return sizeof (UINT64);
++
++ default:
++ FFI_ASSERT (0);
++ return 0;
++ }
++}
++
++/* Return the size in bytes for each of the basic types. */
++
++static size_t
++get_basic_type_size (unsigned short type)
++{
++ switch (type)
++ {
++ case FFI_TYPE_FLOAT:
++ return sizeof (UINT32);
++ case FFI_TYPE_DOUBLE:
++ return sizeof (UINT64);
++ case FFI_TYPE_LONGDOUBLE:
++ return sizeof (long double);
++ case FFI_TYPE_UINT8:
++ return sizeof (UINT8);
++ case FFI_TYPE_SINT8:
++ return sizeof (SINT8);
++ case FFI_TYPE_UINT16:
++ return sizeof (UINT16);
++ case FFI_TYPE_SINT16:
++ return sizeof (SINT16);
++ case FFI_TYPE_UINT32:
++ return sizeof (UINT32);
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT32:
++ return sizeof (SINT32);
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ return sizeof (UINT64);
++ case FFI_TYPE_SINT64:
++ return sizeof (SINT64);
++
++ default:
++ FFI_ASSERT (0);
++ return 0;
++ }
++}
++
++extern void
++ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *,
++ extended_cif *),
++ struct call_context *context,
++ extended_cif *,
++ unsigned,
++ void (*fn)(void));
++
++extern void
++ffi_closure_SYSV (ffi_closure *);
++
++/* Test for an FFI floating point representation. */
++
++static unsigned
++is_floating_type (unsigned short type)
++{
++ return (type == FFI_TYPE_FLOAT || type == FFI_TYPE_DOUBLE
++ || type == FFI_TYPE_LONGDOUBLE);
++}
++
++/* Test for a homogeneous structure. */
++
++static unsigned short
++get_homogeneous_type (ffi_type *ty)
++{
++ if (ty->type == FFI_TYPE_STRUCT && ty->elements)
++ {
++ unsigned i;
++ unsigned short candidate_type
++ = get_homogeneous_type (ty->elements[0]);
++ for (i =1; ty->elements[i]; i++)
++ {
++ unsigned short iteration_type = 0;
++ /* If we have a nested struct, we must find its homogeneous type.
++ If that fits with our candidate type, we are still
++ homogeneous. */
++ if (ty->elements[i]->type == FFI_TYPE_STRUCT
++ && ty->elements[i]->elements)
++ {
++ iteration_type = get_homogeneous_type (ty->elements[i]);
++ }
++ else
++ {
++ iteration_type = ty->elements[i]->type;
++ }
++
++ /* If we are not homogeneous, return FFI_TYPE_STRUCT. */
++ if (candidate_type != iteration_type)
++ return FFI_TYPE_STRUCT;
++ }
++ return candidate_type;
++ }
++
++ /* Base case, we have no more levels of nesting, so we
++ are a basic type, and so, trivially homogeneous in that type. */
++ return ty->type;
++}
++
++/* Determine the number of elements within a STRUCT.
++
++ Note, we must handle nested structs.
++
++ If ty is not a STRUCT this function will return 0. */
++
++static unsigned
++element_count (ffi_type *ty)
++{
++ if (ty->type == FFI_TYPE_STRUCT && ty->elements)
++ {
++ unsigned n;
++ unsigned elems = 0;
++ for (n = 0; ty->elements[n]; n++)
++ {
++ if (ty->elements[n]->type == FFI_TYPE_STRUCT
++ && ty->elements[n]->elements)
++ elems += element_count (ty->elements[n]);
++ else
++ elems++;
++ }
++ return elems;
++ }
++ return 0;
++}
++
++/* Test for a homogeneous floating point aggregate.
++
++ A homogeneous floating point aggregate is a homogeneous aggregate of
++ a half- single- or double- precision floating point type with one
++ to four elements. Note that this includes nested structs of the
++ basic type. */
++
++static int
++is_hfa (ffi_type *ty)
++{
++ if (ty->type == FFI_TYPE_STRUCT
++ && ty->elements[0]
++ && is_floating_type (get_homogeneous_type (ty)))
++ {
++ unsigned n = element_count (ty);
++ return n >= 1 && n <= 4;
++ }
++ return 0;
++}
++
++/* Test if an ffi_type is a candidate for passing in a register.
++
++ This test does not check that sufficient registers of the
++ appropriate class are actually available, merely that IFF
++ sufficient registers are available then the argument will be passed
++ in register(s).
++
++ Note that an ffi_type that is deemed to be a register candidate
++ will always be returned in registers.
++
++ Returns 1 if a register candidate else 0. */
++
++static int
++is_register_candidate (ffi_type *ty)
++{
++ switch (ty->type)
++ {
++ case FFI_TYPE_VOID:
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT64:
++ return 1;
++
++ case FFI_TYPE_STRUCT:
++ if (is_hfa (ty))
++ {
++ return 1;
++ }
++ else if (ty->size > 16)
++ {
++ /* Too large. Will be replaced with a pointer to memory. The
++ pointer MAY be passed in a register, but the value will
++ not. This test specifically fails since the argument will
++ never be passed by value in registers. */
++ return 0;
++ }
++ else
++ {
++ /* Might be passed in registers depending on the number of
++ registers required. */
++ return (ty->size + 7) / 8 < N_X_ARG_REG;
++ }
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++
++ return 0;
++}
++
++/* Test if an ffi_type argument or result is a candidate for a vector
++ register. */
++
++static int
++is_v_register_candidate (ffi_type *ty)
++{
++ return is_floating_type (ty->type)
++ || (ty->type == FFI_TYPE_STRUCT && is_hfa (ty));
++}
++
++/* Representation of the procedure call argument marshalling
++ state.
++
++ The terse state variable names match the names used in the AARCH64
++ PCS. */
++
++struct arg_state
++{
++ unsigned ngrn; /* Next general-purpose register number. */
++ unsigned nsrn; /* Next vector register number. */
++ unsigned nsaa; /* Next stack offset. */
++};
++
++/* Initialize a procedure call argument marshalling state. */
++static void
++arg_init (struct arg_state *state, unsigned call_frame_size)
++{
++ state->ngrn = 0;
++ state->nsrn = 0;
++ state->nsaa = 0;
++}
++
++/* Return the number of available consecutive core argument
++ registers. */
++
++static unsigned
++available_x (struct arg_state *state)
++{
++ return N_X_ARG_REG - state->ngrn;
++}
++
++/* Return the number of available consecutive vector argument
++ registers. */
++
++static unsigned
++available_v (struct arg_state *state)
++{
++ return N_V_ARG_REG - state->nsrn;
++}
++
++static void *
++allocate_to_x (struct call_context *context, struct arg_state *state)
++{
++ FFI_ASSERT (state->ngrn < N_X_ARG_REG)
++ return get_x_addr (context, (state->ngrn)++);
++}
++
++static void *
++allocate_to_s (struct call_context *context, struct arg_state *state)
++{
++ FFI_ASSERT (state->nsrn < N_V_ARG_REG)
++ return get_s_addr (context, (state->nsrn)++);
++}
++
++static void *
++allocate_to_d (struct call_context *context, struct arg_state *state)
++{
++ FFI_ASSERT (state->nsrn < N_V_ARG_REG)
++ return get_d_addr (context, (state->nsrn)++);
++}
++
++static void *
++allocate_to_v (struct call_context *context, struct arg_state *state)
++{
++ FFI_ASSERT (state->nsrn < N_V_ARG_REG)
++ return get_v_addr (context, (state->nsrn)++);
++}
++
++/* Allocate an aligned slot on the stack and return a pointer to it. */
++static void *
++allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment,
++ unsigned size)
++{
++ void *allocation;
++
++ /* Round up the NSAA to the larger of 8 or the natural
++ alignment of the argument's type. */
++ state->nsaa = ALIGN (state->nsaa, alignment);
++ state->nsaa = ALIGN (state->nsaa, alignment);
++ state->nsaa = ALIGN (state->nsaa, 8);
++
++ allocation = stack + state->nsaa;
++
++ state->nsaa += size;
++ return allocation;
++}
++
++static void
++copy_basic_type (void *dest, void *source, unsigned short type)
++{
++ /* This is neccessary to ensure that basic types are copied
++ sign extended to 64-bits as libffi expects. */
++ switch (type)
++ {
++ case FFI_TYPE_FLOAT:
++ *(float *) dest = *(float *) source;
++ break;
++ case FFI_TYPE_DOUBLE:
++ *(double *) dest = *(double *) source;
++ break;
++ case FFI_TYPE_LONGDOUBLE:
++ *(long double *) dest = *(long double *) source;
++ break;
++ case FFI_TYPE_UINT8:
++ *(ffi_arg *) dest = *(UINT8 *) source;
++ break;
++ case FFI_TYPE_SINT8:
++ *(ffi_sarg *) dest = *(SINT8 *) source;
++ break;
++ case FFI_TYPE_UINT16:
++ *(ffi_arg *) dest = *(UINT16 *) source;
++ break;
++ case FFI_TYPE_SINT16:
++ *(ffi_sarg *) dest = *(SINT16 *) source;
++ break;
++ case FFI_TYPE_UINT32:
++ *(ffi_arg *) dest = *(UINT32 *) source;
++ break;
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT32:
++ *(ffi_sarg *) dest = *(SINT32 *) source;
++ break;
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ *(ffi_arg *) dest = *(UINT64 *) source;
++ break;
++ case FFI_TYPE_SINT64:
++ *(ffi_sarg *) dest = *(SINT64 *) source;
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ }
++}
++
++static void
++copy_hfa_to_reg_or_stack (void *memory,
++ ffi_type *ty,
++ struct call_context *context,
++ unsigned char *stack,
++ struct arg_state *state)
++{
++ unsigned elems = element_count (ty);
++ if (available_v (state) < elems)
++ {
++ /* There are insufficient V registers. Further V register allocations
++ are prevented, the NSAA is adjusted (by allocate_to_stack ())
++ and the argument is copied to memory at the adjusted NSAA. */
++ state->nsrn = N_V_ARG_REG;
++ memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size),
++ memory,
++ ty->size);
++ }
++ else
++ {
++ int i;
++ unsigned short type = get_homogeneous_type (ty);
++ unsigned elems = element_count (ty);
++ for (i = 0; i < elems; i++)
++ {
++ void *reg = allocate_to_v (context, state);
++ copy_basic_type (reg, memory, type);
++ memory += get_basic_type_size (type);
++ }
++ }
++}
++
++/* Either allocate an appropriate register for the argument type, or if
++ none are available, allocate a stack slot and return a pointer
++ to the allocated space. */
++
++static void *
++allocate_to_register_or_stack (struct call_context *context,
++ unsigned char *stack,
++ struct arg_state *state,
++ unsigned short type)
++{
++ size_t alignment = get_basic_type_alignment (type);
++ size_t size = alignment;
++ switch (type)
++ {
++ case FFI_TYPE_FLOAT:
++ /* This is the only case for which the allocated stack size
++ should not match the alignment of the type. */
++ size = sizeof (UINT32);
++ /* Fall through. */
++ case FFI_TYPE_DOUBLE:
++ if (state->nsrn < N_V_ARG_REG)
++ return allocate_to_d (context, state);
++ state->nsrn = N_V_ARG_REG;
++ break;
++ case FFI_TYPE_LONGDOUBLE:
++ if (state->nsrn < N_V_ARG_REG)
++ return allocate_to_v (context, state);
++ state->nsrn = N_V_ARG_REG;
++ break;
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT64:
++ if (state->ngrn < N_X_ARG_REG)
++ return allocate_to_x (context, state);
++ state->ngrn = N_X_ARG_REG;
++ break;
++ default:
++ FFI_ASSERT (0);
++ }
++
++ return allocate_to_stack (state, stack, alignment, size);
++}
++
++/* Copy a value to an appropriate register, or if none are
++ available, to the stack. */
++
++static void
++copy_to_register_or_stack (struct call_context *context,
++ unsigned char *stack,
++ struct arg_state *state,
++ void *value,
++ unsigned short type)
++{
++ copy_basic_type (
++ allocate_to_register_or_stack (context, stack, state, type),
++ value,
++ type);
++}
++
++/* Marshall the arguments from FFI representation to procedure call
++ context and stack. */
++
++static unsigned
++aarch64_prep_args (struct call_context *context, unsigned char *stack,
++ extended_cif *ecif)
++{
++ int i;
++ struct arg_state state;
++
++ arg_init (&state, ALIGN(ecif->cif->bytes, 16));
++
++ for (i = 0; i < ecif->cif->nargs; i++)
++ {
++ ffi_type *ty = ecif->cif->arg_types[i];
++ switch (ty->type)
++ {
++ case FFI_TYPE_VOID:
++ FFI_ASSERT (0);
++ break;
++
++ /* If the argument is a basic type the argument is allocated to an
++ appropriate register, or if none are available, to the stack. */
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT64:
++ copy_to_register_or_stack (context, stack, &state,
++ ecif->avalue[i], ty->type);
++ break;
++
++ case FFI_TYPE_STRUCT:
++ if (is_hfa (ty))
++ {
++ copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context,
++ stack, &state);
++ }
++ else if (ty->size > 16)
++ {
++ /* If the argument is a composite type that is larger than 16
++ bytes, then the argument has been copied to memory, and
++ the argument is replaced by a pointer to the copy. */
++
++ copy_to_register_or_stack (context, stack, &state,
++ &(ecif->avalue[i]), FFI_TYPE_POINTER);
++ }
++ else if (available_x (&state) >= (ty->size + 7) / 8)
++ {
++ /* If the argument is a composite type and the size in
++ double-words is not more than the number of available
++ X registers, then the argument is copied into consecutive
++ X registers. */
++ int j;
++ for (j = 0; j < (ty->size + 7) / 8; j++)
++ {
++ memcpy (allocate_to_x (context, &state),
++ &(((UINT64 *) ecif->avalue[i])[j]),
++ sizeof (UINT64));
++ }
++ }
++ else
++ {
++ /* Otherwise, there are insufficient X registers. Further X
++ register allocations are prevented, the NSAA is adjusted
++ (by allocate_to_stack ()) and the argument is copied to
++ memory at the adjusted NSAA. */
++ state.ngrn = N_X_ARG_REG;
++
++ memcpy (allocate_to_stack (&state, stack, ty->alignment,
++ ty->size), ecif->avalue + i, ty->size);
++ }
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++ }
++
++ return ecif->cif->aarch64_flags;
++}
++
++ffi_status
++ffi_prep_cif_machdep (ffi_cif *cif)
++{
++ /* Round the stack up to a multiple of the stack alignment requirement. */
++ cif->bytes =
++ (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1);
++
++ /* Initialize our flags. We are interested if this CIF will touch a
++ vector register, if so we will enable context save and load to
++ those registers, otherwise not. This is intended to be friendly
++ to lazy float context switching in the kernel. */
++ cif->aarch64_flags = 0;
++
++ if (is_v_register_candidate (cif->rtype))
++ {
++ cif->aarch64_flags |= AARCH64_FFI_WITH_V;
++ }
++ else
++ {
++ int i;
++ for (i = 0; i < cif->nargs; i++)
++ if (is_v_register_candidate (cif->arg_types[i]))
++ {
++ cif->aarch64_flags |= AARCH64_FFI_WITH_V;
++ break;
++ }
++ }
++
++ return FFI_OK;
++}
++
++/* Call a function with the provided arguments and capture the return
++ value. */
++void
++ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
++{
++ extended_cif ecif;
++
++ ecif.cif = cif;
++ ecif.avalue = avalue;
++ ecif.rvalue = rvalue;
++
++ switch (cif->abi)
++ {
++ case FFI_SYSV:
++ {
++ struct call_context context;
++ unsigned stack_bytes;
++
++ /* Figure out the total amount of stack space we need, the
++ above call frame space needs to be 16 bytes aligned to
++ ensure correct alignment of the first object inserted in
++ that space hence the ALIGN applied to cif->bytes.*/
++ stack_bytes = ALIGN(cif->bytes, 16);
++
++ memset (&context, 0, sizeof (context));
++ if (is_register_candidate (cif->rtype))
++ {
++ ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn);
++ switch (cif->rtype->type)
++ {
++ case FFI_TYPE_VOID:
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT64:
++ {
++ void *addr = get_basic_type_addr (cif->rtype->type,
++ &context, 0);
++ copy_basic_type (rvalue, addr, cif->rtype->type);
++ break;
++ }
++
++ case FFI_TYPE_STRUCT:
++ if (is_hfa (cif->rtype))
++ {
++ int j;
++ unsigned short type = get_homogeneous_type (cif->rtype);
++ unsigned elems = element_count (cif->rtype);
++ for (j = 0; j < elems; j++)
++ {
++ void *reg = get_basic_type_addr (type, &context, j);
++ copy_basic_type (rvalue, reg, type);
++ rvalue += get_basic_type_size (type);
++ }
++ }
++ else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
++ {
++ unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64));
++ memcpy (rvalue, get_x_addr (&context, 0), size);
++ }
++ else
++ {
++ FFI_ASSERT (0);
++ }
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++ }
++ else
++ {
++ memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64));
++ ffi_call_SYSV (aarch64_prep_args, &context, &ecif,
++ stack_bytes, fn);
++ }
++ break;
++ }
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++}
++
++static unsigned char trampoline [] =
++{ 0x70, 0x00, 0x00, 0x58, /* ldr x16, 1f */
++ 0x91, 0x00, 0x00, 0x10, /* adr x17, 2f */
++ 0x00, 0x02, 0x1f, 0xd6 /* br x16 */
++};
++
++/* Build a trampoline. */
++
++#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,FLAGS) \
++ ({unsigned char *__tramp = (unsigned char*)(TRAMP); \
++ UINT64 __fun = (UINT64)(FUN); \
++ UINT64 __ctx = (UINT64)(CTX); \
++ UINT64 __flags = (UINT64)(FLAGS); \
++ memcpy (__tramp, trampoline, sizeof (trampoline)); \
++ memcpy (__tramp + 12, &__fun, sizeof (__fun)); \
++ memcpy (__tramp + 20, &__ctx, sizeof (__ctx)); \
++ memcpy (__tramp + 28, &__flags, sizeof (__flags)); \
++ __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \
++ })
++
++ffi_status
++ffi_prep_closure_loc (ffi_closure* closure,
++ ffi_cif* cif,
++ void (*fun)(ffi_cif*,void*,void**,void*),
++ void *user_data,
++ void *codeloc)
++{
++ if (cif->abi != FFI_SYSV)
++ return FFI_BAD_ABI;
++
++ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, codeloc,
++ cif->aarch64_flags);
++
++ closure->cif = cif;
++ closure->user_data = user_data;
++ closure->fun = fun;
++
++ return FFI_OK;
++}
++
++/* Primary handler to setup and invoke a function within a closure.
++
++ A closure when invoked enters via the assembler wrapper
++ ffi_closure_SYSV(). The wrapper allocates a call context on the
++ stack, saves the interesting registers (from the perspective of
++ the calling convention) into the context then passes control to
++ ffi_closure_SYSV_inner() passing the saved context and a pointer to
++ the stack at the point ffi_closure_SYSV() was invoked.
++
++ On the return path the assembler wrapper will reload call context
++ regsiters.
++
++ ffi_closure_SYSV_inner() marshalls the call context into ffi value
++ desriptors, invokes the wrapped function, then marshalls the return
++ value back into the call context. */
++
++void
++ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
++ void *stack)
++{
++ ffi_cif *cif = closure->cif;
++ void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
++ void *rvalue = NULL;
++ int i;
++ struct arg_state state;
++
++ arg_init (&state, ALIGN(cif->bytes, 16));
++
++ for (i = 0; i < cif->nargs; i++)
++ {
++ ffi_type *ty = cif->arg_types[i];
++
++ switch (ty->type)
++ {
++ case FFI_TYPE_VOID:
++ FFI_ASSERT (0);
++ break;
++
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT64:
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ avalue[i] = allocate_to_register_or_stack (context, stack,
++ &state, ty->type);
++ break;
++
++ case FFI_TYPE_STRUCT:
++ if (is_hfa (ty))
++ {
++ unsigned n = element_count (ty);
++ if (available_v (&state) < n)
++ {
++ state.nsrn = N_V_ARG_REG;
++ avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
++ ty->size);
++ }
++ else
++ {
++ switch (get_homogeneous_type (ty))
++ {
++ case FFI_TYPE_FLOAT:
++ {
++ /* Eeek! We need a pointer to the structure,
++ however the homogeneous float elements are
++ being passed in individual S registers,
++ therefore the structure is not represented as
++ a contiguous sequence of bytes in our saved
++ register context. We need to fake up a copy
++ of the structure layed out in memory
++ correctly. The fake can be tossed once the
++ closure function has returned hence alloca()
++ is sufficient. */
++ int j;
++ UINT32 *p = avalue[i] = alloca (ty->size);
++ for (j = 0; j < element_count (ty); j++)
++ memcpy (&p[j],
++ allocate_to_s (context, &state),
++ sizeof (*p));
++ break;
++ }
++
++ case FFI_TYPE_DOUBLE:
++ {
++ /* Eeek! We need a pointer to the structure,
++ however the homogeneous float elements are
++ being passed in individual S registers,
++ therefore the structure is not represented as
++ a contiguous sequence of bytes in our saved
++ register context. We need to fake up a copy
++ of the structure layed out in memory
++ correctly. The fake can be tossed once the
++ closure function has returned hence alloca()
++ is sufficient. */
++ int j;
++ UINT64 *p = avalue[i] = alloca (ty->size);
++ for (j = 0; j < element_count (ty); j++)
++ memcpy (&p[j],
++ allocate_to_d (context, &state),
++ sizeof (*p));
++ break;
++ }
++
++ case FFI_TYPE_LONGDOUBLE:
++ memcpy (&avalue[i],
++ allocate_to_v (context, &state),
++ sizeof (*avalue));
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++ }
++ }
++ else if (ty->size > 16)
++ {
++ /* Replace Composite type of size greater than 16 with a
++ pointer. */
++ memcpy (&avalue[i],
++ allocate_to_register_or_stack (context, stack,
++ &state, FFI_TYPE_POINTER),
++ sizeof (avalue[i]));
++ }
++ else if (available_x (&state) >= (ty->size + 7) / 8)
++ {
++ avalue[i] = get_x_addr (context, state.ngrn);
++ state.ngrn += (ty->size + 7) / 8;
++ }
++ else
++ {
++ state.ngrn = N_X_ARG_REG;
++
++ avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
++ ty->size);
++ }
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++ }
++
++ /* Figure out where the return value will be passed, either in
++ registers or in a memory block allocated by the caller and passed
++ in x8. */
++
++ if (is_register_candidate (cif->rtype))
++ {
++ /* Register candidates are *always* returned in registers. */
++
++ /* Allocate a scratchpad for the return value, we will let the
++ callee scrible the result into the scratch pad then move the
++ contents into the appropriate return value location for the
++ call convention. */
++ rvalue = alloca (cif->rtype->size);
++ (closure->fun) (cif, rvalue, avalue, closure->user_data);
++
++ /* Copy the return value into the call context so that it is returned
++ as expected to our caller. */
++ switch (cif->rtype->type)
++ {
++ case FFI_TYPE_VOID:
++ break;
++
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_POINTER:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_INT:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_SINT64:
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ {
++ void *addr = get_basic_type_addr (cif->rtype->type, context, 0);
++ copy_basic_type (addr, rvalue, cif->rtype->type);
++ break;
++ }
++ case FFI_TYPE_STRUCT:
++ if (is_hfa (cif->rtype))
++ {
++ int i;
++ unsigned short type = get_homogeneous_type (cif->rtype);
++ unsigned elems = element_count (cif->rtype);
++ for (i = 0; i < elems; i++)
++ {
++ void *reg = get_basic_type_addr (type, context, i);
++ copy_basic_type (reg, rvalue, type);
++ rvalue += get_basic_type_size (type);
++ }
++ }
++ else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
++ {
++ unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
++ memcpy (get_x_addr (context, 0), rvalue, size);
++ }
++ else
++ {
++ FFI_ASSERT (0);
++ }
++ break;
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++ }
++ else
++ {
++ memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64));
++ (closure->fun) (cif, rvalue, avalue, closure->user_data);
++ }
++}
++
+Index: Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/ffitarget.h
+===================================================================
+--- /dev/null
++++ Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/ffitarget.h
+@@ -0,0 +1,59 @@
++/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++``Software''), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
++
++#ifndef LIBFFI_TARGET_H
++#define LIBFFI_TARGET_H
++
++#ifndef LIBFFI_H
++#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
++#endif
++
++#ifndef LIBFFI_ASM
++typedef unsigned long ffi_arg;
++typedef signed long ffi_sarg;
++
++typedef enum ffi_abi
++ {
++ FFI_FIRST_ABI = 0,
++ FFI_SYSV,
++ FFI_LAST_ABI,
++ FFI_DEFAULT_ABI = FFI_SYSV
++ } ffi_abi;
++#endif
++
++/* ---- Definitions for closures ----------------------------------------- */
++
++#define FFI_CLOSURES 1
++#define FFI_TRAMPOLINE_SIZE 36
++#define FFI_NATIVE_RAW_API 0
++
++/* ---- Internal ---- */
++
++
++#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags
++
++#define AARCH64_FFI_WITH_V_BIT 0
++
++#define AARCH64_N_XREG 32
++#define AARCH64_N_VREG 32
++#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16)
++
++#endif
+Index: Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/sysv.S
+===================================================================
+--- /dev/null
++++ Python-2.7.3/Modules/_ctypes/libffi/src/aarch64/sysv.S
+@@ -0,0 +1,307 @@
++/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
++
++Permission is hereby granted, free of charge, to any person obtaining
++a copy of this software and associated documentation files (the
++``Software''), to deal in the Software without restriction, including
++without limitation the rights to use, copy, modify, merge, publish,
++distribute, sublicense, and/or sell copies of the Software, and to
++permit persons to whom the Software is furnished to do so, subject to
++the following conditions:
++
++The above copyright notice and this permission notice shall be
++included in all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
++
++#define LIBFFI_ASM
++#include
++#include
++
++#define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
++#define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
++#define cfi_restore(reg) .cfi_restore reg
++#define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
++
++ .text
++ .globl ffi_call_SYSV
++ .type ffi_call_SYSV, #function
++
++/* ffi_call_SYSV()
++
++ Create a stack frame, setup an argument context, call the callee
++ and extract the result.
++
++ The maximum required argument stack size is provided,
++ ffi_call_SYSV() allocates that stack space then calls the
++ prepare_fn to populate register context and stack. The
++ argument passing registers are loaded from the register
++ context and the callee called, on return the register passing
++ register are saved back to the context. Our caller will
++ extract the return value from the final state of the saved
++ register context.
++
++ Prototype:
++
++ extern unsigned
++ ffi_call_SYSV (void (*)(struct call_context *context, unsigned char *,
++ extended_cif *),
++ struct call_context *context,
++ extended_cif *,
++ unsigned required_stack_size,
++ void (*fn)(void));
++
++ Therefore on entry we have:
++
++ x0 prepare_fn
++ x1 &context
++ x2 &ecif
++ x3 bytes
++ x4 fn
++
++ This function uses the following stack frame layout:
++
++ ==
++ saved x30(lr)
++ x29(fp)-> saved x29(fp)
++ saved x24
++ saved x23
++ saved x22
++ sp' -> saved x21
++ ...
++ sp -> (constructed callee stack arguments)
++ ==
++
++ Voila! */
++
++#define ffi_call_SYSV_FS (8 * 4)
++
++ .cfi_startproc
++ffi_call_SYSV:
++ stp x29, x30, [sp, #-16]!
++ cfi_adjust_cfa_offset (16)
++ cfi_rel_offset (x29, 0)
++ cfi_rel_offset (x30, 8)
++
++ mov x29, sp
++ cfi_def_cfa_register (x29)
++ sub sp, sp, #ffi_call_SYSV_FS
++
++ stp x21, x22, [sp, 0]
++ cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS)
++ cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS)
++
++ stp x23, x24, [sp, 16]
++ cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS)
++ cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS)
++
++ mov x21, x1
++ mov x22, x2
++ mov x24, x4
++
++ /* Allocate the stack space for the actual arguments, many
++ arguments will be passed in registers, but we assume
++ worst case and allocate sufficient stack for ALL of
++ the arguments. */
++ sub sp, sp, x3
++
++ /* unsigned (*prepare_fn) (struct call_context *context,
++ unsigned char *stack, extended_cif *ecif);
++ */
++ mov x23, x0
++ mov x0, x1
++ mov x1, sp
++ /* x2 already in place */
++ blr x23
++
++ /* Preserve the flags returned. */
++ mov x23, x0
++
++ /* Figure out if we should touch the vector registers. */
++ tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f
++
++ /* Load the vector argument passing registers. */
++ ldp q0, q1, [x21, #8*32 + 0]
++ ldp q2, q3, [x21, #8*32 + 32]
++ ldp q4, q5, [x21, #8*32 + 64]
++ ldp q6, q7, [x21, #8*32 + 96]
++1:
++ /* Load the core argument passing registers. */
++ ldp x0, x1, [x21, #0]
++ ldp x2, x3, [x21, #16]
++ ldp x4, x5, [x21, #32]
++ ldp x6, x7, [x21, #48]
++
++ /* Don't forget x8 which may be holding the address of a return buffer.
++ */
++ ldr x8, [x21, #8*8]
++
++ blr x24
++
++ /* Save the core argument passing registers. */
++ stp x0, x1, [x21, #0]
++ stp x2, x3, [x21, #16]
++ stp x4, x5, [x21, #32]
++ stp x6, x7, [x21, #48]
++
++ /* Note nothing useful ever comes back in x8! */
++
++ /* Figure out if we should touch the vector registers. */
++ tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f
++
++ /* Save the vector argument passing registers. */
++ stp q0, q1, [x21, #8*32 + 0]
++ stp q2, q3, [x21, #8*32 + 32]
++ stp q4, q5, [x21, #8*32 + 64]
++ stp q6, q7, [x21, #8*32 + 96]
++1:
++ /* All done, unwind our stack frame. */
++ ldp x21, x22, [x29, # - ffi_call_SYSV_FS]
++ cfi_restore (x21)
++ cfi_restore (x22)
++
++ ldp x23, x24, [x29, # - ffi_call_SYSV_FS + 16]
++ cfi_restore (x23)
++ cfi_restore (x24)
++
++ mov sp, x29
++ cfi_def_cfa_register (sp)
++
++ ldp x29, x30, [sp], #16
++ cfi_adjust_cfa_offset (-16)
++ cfi_restore (x29)
++ cfi_restore (x30)
++
++ ret
++
++ .cfi_endproc
++ .size ffi_call_SYSV, .-ffi_call_SYSV
++
++#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
++
++/* ffi_closure_SYSV
++
++ Closure invocation glue. This is the low level code invoked directly by
++ the closure trampoline to setup and call a closure.
++
++ On entry x17 points to a struct trampoline_data, x16 has been clobbered
++ all other registers are preserved.
++
++ We allocate a call context and save the argument passing registers,
++ then invoked the generic C ffi_closure_SYSV_inner() function to do all
++ the real work, on return we load the result passing registers back from
++ the call context.
++
++ On entry
++
++ extern void
++ ffi_closure_SYSV (struct trampoline_data *);
++
++ struct trampoline_data
++ {
++ UINT64 *ffi_closure;
++ UINT64 flags;
++ };
++
++ This function uses the following stack frame layout:
++
++ ==
++ saved x30(lr)
++ x29(fp)-> saved x29(fp)
++ saved x22
++ saved x21
++ ...
++ sp -> call_context
++ ==
++
++ Voila! */
++
++ .text
++ .globl ffi_closure_SYSV
++ .cfi_startproc
++ffi_closure_SYSV:
++ stp x29, x30, [sp, #-16]!
++ cfi_adjust_cfa_offset (16)
++ cfi_rel_offset (x29, 0)
++ cfi_rel_offset (x30, 8)
++
++ mov x29, sp
++
++ sub sp, sp, #ffi_closure_SYSV_FS
++ cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
++
++ stp x21, x22, [x29, #-16]
++ cfi_rel_offset (x21, 0)
++ cfi_rel_offset (x22, 8)
++
++ /* Load x21 with &call_context. */
++ mov x21, sp
++ /* Preserve our struct trampoline_data * */
++ mov x22, x17
++
++ /* Save the rest of the argument passing registers. */
++ stp x0, x1, [x21, #0]
++ stp x2, x3, [x21, #16]
++ stp x4, x5, [x21, #32]
++ stp x6, x7, [x21, #48]
++ /* Don't forget we may have been given a result scratch pad address.
++ */
++ str x8, [x21, #64]
++
++ /* Figure out if we should touch the vector registers. */
++ ldr x0, [x22, #8]
++ tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f
++
++ /* Save the argument passing vector registers. */
++ stp q0, q1, [x21, #8*32 + 0]
++ stp q2, q3, [x21, #8*32 + 32]
++ stp q4, q5, [x21, #8*32 + 64]
++ stp q6, q7, [x21, #8*32 + 96]
++1:
++ /* Load &ffi_closure.. */
++ ldr x0, [x22, #0]
++ mov x1, x21
++ /* Compute the location of the stack at the point that the
++ trampoline was called. */
++ add x2, x29, #16
++
++ bl ffi_closure_SYSV_inner
++
++ /* Figure out if we should touch the vector registers. */
++ ldr x0, [x22, #8]
++ tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f
++
++ /* Load the result passing vector registers. */
++ ldp q0, q1, [x21, #8*32 + 0]
++ ldp q2, q3, [x21, #8*32 + 32]
++ ldp q4, q5, [x21, #8*32 + 64]
++ ldp q6, q7, [x21, #8*32 + 96]
++1:
++ /* Load the result passing core registers. */
++ ldp x0, x1, [x21, #0]
++ ldp x2, x3, [x21, #16]
++ ldp x4, x5, [x21, #32]
++ ldp x6, x7, [x21, #48]
++ /* Note nothing usefull is returned in x8. */
++
++ /* We are done, unwind our frame. */
++ ldp x21, x22, [x29, #-16]
++ cfi_restore (x21)
++ cfi_restore (x22)
++
++ mov sp, x29
++ cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
++
++ ldp x29, x30, [sp], #16
++ cfi_adjust_cfa_offset (-16)
++ cfi_restore (x29)
++ cfi_restore (x30)
++
++ ret
++ .cfi_endproc
++ .size ffi_closure_SYSV, .-ffi_closure_SYSV
+Index: Python-2.7.3/Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp
+===================================================================
+--- Python-2.7.3.orig/Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp
++++ Python-2.7.3/Modules/_ctypes/libffi/testsuite/lib/libffi-dg.exp
+@@ -203,6 +203,10 @@ proc libffi_target_compile { source dest
+
+ lappend options "libs= -lffi"
+
++ if { [string match "aarch64*-*-linux*" $target_triplet] } {
++ lappend options "libs= -lpthread"
++ }
++
+ verbose "options: $options"
+ return [target_compile $source $dest $type $options]
+ }
diff --git a/python-2.7.3-multiprocessing-join.patch b/python-2.7.3-multiprocessing-join.patch
new file mode 100644
index 0000000..c137287
--- /dev/null
+++ b/python-2.7.3-multiprocessing-join.patch
@@ -0,0 +1,36 @@
+
+# HG changeset patch
+# User Richard Oudkerk
+# Date 1340030251 -3600
+# Node ID 4c07b9c49b75a10874d98841bb2d826f118835a3
+# Parent 8b38a81ba3bfa0535b3e7719c3b0e62343a56698
+Issue #15101: Make pool finalizer avoid joining current thread
+
+diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py
+--- a/Lib/multiprocessing/pool.py
++++ b/Lib/multiprocessing/pool.py
+@@ -489,7 +489,8 @@ class Pool(object):
+ # We must wait for the worker handler to exit before terminating
+ # workers because we don't want workers to be restarted behind our back.
+ debug('joining worker handler')
+- worker_handler.join()
++ if threading.current_thread() is not worker_handler:
++ worker_handler.join(1e100)
+
+ # Terminate workers which haven't already finished.
+ if pool and hasattr(pool[0], 'terminate'):
+@@ -499,10 +500,12 @@ class Pool(object):
+ p.terminate()
+
+ debug('joining task handler')
+- task_handler.join(1e100)
++ if threading.current_thread() is not task_handler:
++ task_handler.join(1e100)
+
+ debug('joining result handler')
+- result_handler.join(1e100)
++ if threading.current_thread() is not result_handler:
++ result_handler.join(1e100)
+
+ if pool and hasattr(pool[0], 'terminate'):
+ debug('joining pool workers')
diff --git a/python-2.7.3rc2-multilib.patch b/python-2.7.3rc2-multilib.patch
index 8f1975f..086c9e1 100644
--- a/python-2.7.3rc2-multilib.patch
+++ b/python-2.7.3rc2-multilib.patch
@@ -33,7 +33,7 @@ Index: configure.in
+esac
+
+case $ARCH:$python_cv_cc_64bit_output in
-+ppc64:yes | powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes)
++aarch64:yes | ppc64:yes | powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes)
+ LIB="lib64"
+ ;;
+*:*)
diff --git a/python-base.changes b/python-base.changes
index 86845a5..d7fee19 100644
--- a/python-base.changes
+++ b/python-base.changes
@@ -1,3 +1,20 @@
+-------------------------------------------------------------------
+Wed Feb 27 17:04:32 UTC 2013 - schwab@suse.de
+
+- Add aarch64 to the list of lib64 platforms
+
+-------------------------------------------------------------------
+Sat Feb 9 16:24:10 UTC 2013 - schwab@suse.de
+
+- Add ctypes-libffi-aarch64.patch: import aarch64 support for libffi in
+ _ctypes module
+
+-------------------------------------------------------------------
+Fri Feb 8 14:49:45 UTC 2013 - jmatejek@suse.com
+
+- multiprocessing: thread joining itself (bnc#747794)
+- gettext: fix cases where no bundle is found (bnc#794139)
+
-------------------------------------------------------------------
Thu Oct 25 11:21:06 UTC 2012 - coolo@suse.com
diff --git a/python-base.spec b/python-base.spec
index 494f0e0..43f1195 100644
--- a/python-base.spec
+++ b/python-base.spec
@@ -52,6 +52,9 @@ Patch18: python-2.7.3-ssl_ca_path.patch
Patch19: python-2.7.3-fix-dbm-64bit-bigendian.patch
# PATCH-FEATURE-OPENSUSE python-bundle-lang.patch bnc#617751 dimstar@opensuse.org -- gettext: when looking in default_localedir also check in locale-bundle.
Patch20: python-bundle-lang.patch
+Patch21: python-2.7.3-multiprocessing-join.patch
+# PATCH-FIX-OPENSUSE Import aarch64 support for libffi in _ctypes module
+Patch22: ctypes-libffi-aarch64.patch
# COMMON-PATCH-END
%define python_version %(echo %{tarversion} | head -c 3)
BuildRequires: automake
@@ -142,6 +145,8 @@ other applications.
%patch18
%patch19 -p1
%patch20 -p1
+%patch21 -p1
+%patch22 -p1
# COMMON-PREP-END
# drop Autoconf version requirement
diff --git a/python-bundle-lang.patch b/python-bundle-lang.patch
index f92f8fa..e31463a 100644
--- a/python-bundle-lang.patch
+++ b/python-bundle-lang.patch
@@ -16,7 +16,7 @@ Index: Python-2.7.3/Lib/gettext.py
def find(domain, localedir=None, languages=None, all=0):
+ if localedir in [None, _default_localedir]:
+ bundle = find(domain, localedir=_default_bundlelocaledir, languages=languages, all=all)
-+ if len(bundle):
++ if bundle:
+ return bundle
# Get some reasonable defaults for arguments that were not supplied
if localedir is None:
diff --git a/python-doc.spec b/python-doc.spec
index 249682c..ab1ec8f 100644
--- a/python-doc.spec
+++ b/python-doc.spec
@@ -49,6 +49,9 @@ Patch18: python-2.7.3-ssl_ca_path.patch
Patch19: python-2.7.3-fix-dbm-64bit-bigendian.patch
# PATCH-FEATURE-OPENSUSE python-bundle-lang.patch bnc#617751 dimstar@opensuse.org -- gettext: when looking in default_localedir also check in locale-bundle.
Patch20: python-bundle-lang.patch
+Patch21: python-2.7.3-multiprocessing-join.patch
+# PATCH-FIX-OPENSUSE Import aarch64 support for libffi in _ctypes module
+Patch22: ctypes-libffi-aarch64.patch
# COMMON-PATCH-END
Provides: pyth_doc
Provides: pyth_ps
@@ -98,6 +101,8 @@ Python, and Macintosh Module Reference in PDF format.
%patch18
%patch19 -p1
%patch20 -p1
+%patch21 -p1
+%patch22 -p1
# COMMON-PREP-END
%build
diff --git a/python.changes b/python.changes
index ed23be0..6aea52b 100644
--- a/python.changes
+++ b/python.changes
@@ -1,3 +1,8 @@
+-------------------------------------------------------------------
+Mon Feb 25 17:24:52 UTC 2013 - jmatejek@suse.com
+
+- fix pythonstart failing on $HOME-less users (bnc#804978)
+
-------------------------------------------------------------------
Sun Aug 12 11:46:22 UTC 2012 - idonmez@suse.com
diff --git a/python.spec b/python.spec
index 19581dd..cb685cb 100644
--- a/python.spec
+++ b/python.spec
@@ -57,6 +57,9 @@ Patch18: python-2.7.3-ssl_ca_path.patch
Patch19: python-2.7.3-fix-dbm-64bit-bigendian.patch
# PATCH-FEATURE-OPENSUSE python-bundle-lang.patch bnc#617751 dimstar@opensuse.org -- gettext: when looking in default_localedir also check in locale-bundle.
Patch20: python-bundle-lang.patch
+Patch21: python-2.7.3-multiprocessing-join.patch
+# PATCH-FIX-OPENSUSE Import aarch64 support for libffi in _ctypes module
+Patch22: ctypes-libffi-aarch64.patch
# COMMON-PATCH-END
BuildRequires: automake
BuildRequires: db-devel
@@ -181,6 +184,8 @@ implementation of the standard Unix DBM databases.
%patch18
%patch19 -p1
%patch20 -p1
+%patch21 -p1
+%patch22 -p1
# COMMON-PREP-END
# drop Autoconf version requirement
diff --git a/pythonstart b/pythonstart
index e155a31..3802a13 100644
--- a/pythonstart
+++ b/pythonstart
@@ -13,7 +13,10 @@ historyPath = os.path.expanduser("~/.pyhistory")
# handler for saving history
def save_history(historyPath=historyPath):
import readline
- readline.write_history_file(historyPath)
+ try:
+ readline.write_history_file(historyPath)
+ except:
+ pass
# read history, if it exists
if os.path.exists(historyPath):